Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ユニットテスト実行を 45% 高速化した Repository テスト戦略 / Repository Test Strategy Speeds up Unit Test

yukana
June 04, 2023

ユニットテスト実行を 45% 高速化した Repository テスト戦略 / Repository Test Strategy Speeds up Unit Test

私が開発を担当するプロダクトでは、ユニットテストの実行に時間がかかるという課題がありました。
その原因と改善の鍵は、データアクセス抽象化レイヤーとしての Repository クラスのテスト戦略にありました。

Spring Boot + Hibernate、オニオンアーキテクチャーで構築されたアプリケーションにおける、データベースアクセスを伴うユニットテストの課題と改善手法について、実アプリケーション開発でのユニットテストに対するトレードオフの判断を交えて説明します。

yukana

June 04, 2023
Tweet

Other Decks in Programming

Transcript

  1. 自己紹介
 • 名前:Yuya Nishimaki/西牧 佑哉
 • 所属:BABY JOB株式会社
 ◦ エンジニア歴3年


    ◦ バックエンドエンジニア
 ◦ Java, Spring Bootを使用した自社サービスの開発 
 • 初登壇です何卒🙏
 2

  2. 言語やツール
 • Java8
 • Spring Boot
 • オニオンアーキテクチャ
 • Spring

    Data JPA, Hibernate(ORM)
 • JUnit5
 • H2(テスト用DB)
 • GitHub Actions(CI)
 10

  3. オニオンアーキテクチャ
 11
 依存関係は外側から内側に向かう 
 
 • ドメイン層
 ◦ ビジネスルールやドメイン知識を表現する 


    ◦ リポジトリを定義する 
 • アプリケーション層
 ◦ ユースケースを実現する 
 ◦ アプリケーションサービスを定義する 
 アプリケーション層
 プレゼンテーション層
 テスト
 インフラ層
 ドメイン層

  4. リポジトリを過剰にテストしている
 25
 アプリケーション
 サービスA
 リポジトリ
 DB
 アプリケーション
 サービスB
 アプリケーションサービスBの 


    テストがカバーする範囲
 リポジトリのテストが
 カバーする範囲
 アプリケーションサービスAの 
 テストがカバーする範囲

  5. リポジトリを過剰にテストしている(再掲)
 30
 アプリケーション
 サービスA
 リポジトリ
 DB
 アプリケーション
 サービスB
 アプリケーションサービスBの 


    テストがカバーする範囲
 リポジトリのテストが
 カバーする範囲
 アプリケーションサービスAの 
 テストがカバーする範囲

  6. テストの責務を分離する
 31
 アプリケーション
 サービスA
 リポジトリ
 DB
 アプリケーション
 サービスB
 アプリケーションサービスBの 


    テストがカバーする範囲
 リポジトリのテストが
 カバーする範囲
 アプリケーションサービスAの 
 テストがカバーする範囲
 モックリポジトリ
 モックリポジトリ

  7. 高速化の結果
 • @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)を使用したテスト ケース数
 ◦ 203 → 0👏


    • CIでの実行時間
 ◦ 約45%改善(338s → 183s)👏
 • ローカルでの実行時間
 ◦ 約75%改善(255s → 64s)👏
 33

  8. 後日談
 • レイヤーの責務を守る
 • 責務を守ると
 ◦ ドメイン層にビジネスロジックがある 
 ◦ アプリケーションサービスのテストケースは少なくなる

    
 • テストケース数が少なければデータベースを使用してテストを行える
 • モックを使ったユニットテストの高速化は現実解
 ◦ アプリケーションサービス内に意図せずビジネスロジックを書いてしまう 
 ◦ すでに書かれている
 ◦ アプリケーションサービスの数が多い 
 41