Slide 1

Slide 1 text

ユニットテスト環境改善 yamashita.kiyoshi 若手・学生サーバーサイドエンジニアLT会 2024/01/19

Slide 2

Slide 2 text

まずは自己紹介
 名前:山下 清史
 所属:株式会社ラクーンホールディングス 技術戦略部 開発チーム
 主な仕事:BtoB卸売りサイト スーパーデリバリーの開発
 趣味:ISUCON(前回 上位25%)
 vuejs-jpのコアスタッフしてます

Slide 3

Slide 3 text

Javaのユニットテスト環境が辛かった🥵
 - FWはSpring
 - テストの実行が遅い
 - 1000ケースしかないのに15分程度かかる
 - masterにmerge後テストを待たずにリリース... 
 - テストを書くモチベーションが湧かない
 - カバレッジが可視化されていないので達成感が無い
 - テストの網羅性を注目されていなかった
 - テスティングライブラリのVersionが古い
 - JUnit 4, JMockit 1.33
 - Java11の文法に対応していない
 - 複数の振る舞いをテストするときの記述量が増える


Slide 4

Slide 4 text

この一年でやったこと
 - JUnit4から5へリプレース
 - 遅いテストケースの原因探して修正
 - カバレッジの可視化


Slide 5

Slide 5 text

JUnit4から5へリプレース

Slide 6

Slide 6 text

JUnitのVersionアップ
 移行で辛かったポイント①
 - パッケージが変更されていた
 - org.junit.Test => org.junit.jupiter.api.Test
 - 一部機能が変わっておりコンパイルできない👼
 - 例外が投げられることのテストでは
 - @Test(expected = NullPointerException.class)が
 Assertions.assertThrows(NullPointerException.class
 根気よく空き時間を見つけて修正💪


Slide 7

Slide 7 text

JUnitのVersionアップ
 移行で辛かったポイント②
 - JUnitのVersionをあげたことでMockライブラリ(JMockit)もVersionを上げる必要 が出てきた
 - JMockitはマイナーバージョンアップでも後方互換性がないので
 最新Versionにすると全て書き換える必要あり 
 - 開発は2019年で止まっている
 
 
 JMockitで書かれている箇所をMockito🍷に書き換え なんとかJUnit5に移行できた...

Slide 8

Slide 8 text

Mockitoの選定理由
 - JUnit5に対応している
 - 開発が今も続いている
 - 毎月リリースされている
 - 学習コストが低い
 - 弊社の新卒研修で使われているので知っている人が多い
 - 日本語のドキュメントがある


Slide 9

Slide 9 text

JUnit5にリプレースした結果
 - JUnitが最新バージョンになった
 - Java8以降の文法(ラムダ関数など)が使用可能
 - JUnitの便利な機能
 - パラメータ化テスト
 - @DisplayName
 - テストを階層化して整理


Slide 10

Slide 10 text

テストが遅い問題

Slide 11

Slide 11 text

テストが遅い問題①
 遅いテストを確認すると...
 1つのテストクラスだけで約50秒!!


Slide 12

Slide 12 text

テストが遅い問題①
 巨大な画像(6000px×6000px)の画像をリサイズしていた
 テスト対象のコード内でpropertyファイルから取得する
 リサイズの上限が6000px×6000pxであるため
 
 リフレクションでテスト時のみ縦横ピクセルのリサイズの上限を変更

Slide 13

Slide 13 text

テストが遅い問題①
 約50秒速くした
 他にも遅いテストを見つけては原因調査...


Slide 14

Slide 14 text

テストが遅い問題②
 問題:
 複数のテストクラスで同じDIコンテナ使用していたが、
 テスト毎に生成しては破棄を繰り返していた。
 クラスA クラスC クラスB キャッシュ済みのDIコンテナが使えないとテストクラスごとに DIコンテナ生成コストがかかる

Slide 15

Slide 15 text

テストが遅い問題②
 クラスA クラスC クラスB 全てのテストクラスでキャッシュ済みのDIコンテナを 利用出来るように修正 問題:
 複数のテストクラスで同じDIコンテナ使用していたが、
 テスト毎に生成しては破棄を繰り返していた。


Slide 16

Slide 16 text

カバレッジ可視化

Slide 17

Slide 17 text

カバレッジ可視化
 - カバレッジが計測されていない状況だったので、
 テスト作成モチベーションがわかなかった
 
 - MR時にどの行がテストでカバーされていないか表示 - MR時にカバレッジの割合変化を表示 - READMEにバッジを張る - gitlab pagesにカバレッジレポートをホスティング

Slide 18

Slide 18 text

カバレッジ可視化
 - カバレッジが計測されていない状況だったので、
 テスト作成モチベーションがわかなかった
 
 - MR時にどの行がテストでカバーされていないか表示 - MR時にカバレッジの割合変化を表示 - READMEにバッジを張る - gitlab pagesにカバレッジレポートをホスティング

Slide 19

Slide 19 text

カバレッジ可視化
 コードレビュー時の指標の1つ、モチベーションアップに繋がりそう!?

Slide 20

Slide 20 text

カバレッジ可視化
 - カバレッジが計測されていない状況だったので、
 テストの品質が低い状況だった...
 
 - MR時にどの行がテストでカバーされていないか表示 - MR時にカバレッジの割合変化を表示 - READMEにバッジを張る - gitlab pagesにカバレッジレポートをホスティング

Slide 21

Slide 21 text

カバレッジ可視化
 カバレッジを簡単に確認できる💪

Slide 22

Slide 22 text

まとめ
 - JUnitのVersionをあげたことでテストの書きやすさ↗
 - 遅いテストを修正、キャッシュ済みのDIコンテナを使用
 - テスト速度↗(約15分⇒約6分)
 - カバレッジレポートをgitlab-pagesにホスティングさせた
 - MR時にカバーされていないコードを分かるようにした
 - テストへのモチベーション↗
 - まだまだ改善できる余地があるのでこれからもやっていき!


Slide 23

Slide 23 text

参考
 - Spring コンテキストキャッシング
 - GitLab テストカバレッジの可視化