現場はJava6。
今までずっと手動テストでやってきたんだけど、やっぱ限界あるよね?
っことでテストコードを書くことになり、その見積もりを手伝った。
JUnitとかMockitoとかを集めるところから始めたんだけど、いかんせん
古すぎてぐぐってもなかなか情報にヒットしないので苦労した。
技術的負債がたまりすぎると死ぬよ?というケースとして忘備録。
JUnit 4.11
Javaでテストコード書くと言えばJUnit。
最新はJUnit5があるけど、Java8以降じゃないと使えないので4系からチョイス。
後述の@Ruleアノテーション使うために 4.8以降じゃないとダメ。
assertJ 1.7.1
アサーションライブラリ。
メソッドチェーンでつないで書いていくスタイルなので、
((((かっこ地獄))))になりにくいし、
Eclipseのサジェストにあわせてポンポンassert文が書ける。
Mockito 1.9.5
テスト用のモックをかなり簡単に実装できるライブラリ。もひーと、と読むらしい。
JUit5系だとMockito 2.x.xとかあるけど、JUnit4系で安定は1.9.5の模様。
モックって何?
Hogeクラスのhogehoge()メソッドをテストしたいとする。
hogehoge()メソッドが別のFugaクラスに依存している場合、
Fugaクラスも準備しないとテストできないことになる。
モックとはそういうとき、
「HogeクラスからFuga#fugafuga()を見たときは、とにかく3を返せ」
って設定できる。Javaでテストと言ったら必須。
PowerMock 1.5.6
Mockitoはめっちゃ便利なんだけど、staticメソッドなんかはモックできない。
PowerMockはそこをいい感じにハックすることで
Mockitoと似た書き方でstaticメソッドのモックができる。
あとprivateメソッドなんかも。
古くからJava使ってる現場ではどーせstaticメソッドも
猛威をふるっている(偏見)のでこちらも必須。
このPowerMockと後述のEclemmaが相性が悪く苦労した。
(最新バージョンでは解決している)
1.5.6にしたのはMockito 1.9.xとPowerMock1.5.xが対応してるから。
#Javassist3.18.2
JavassistはJavaバイトコードをいじるときに使うライブラリ。
Javaバイトコードとは、僕らが書いたJavaソースを
コンパイルしてできるやつ。JVMで動くやつ。
PowerMockはこれを使っている。ソースじゃなくてJavaバイトコードの方を
うまく書き換えて、モックを実現させているらしい。
(詳しくは知らないし、この説明は厳密には間違っているかもしれない)
既存プロジェクトでJavassist3.4が入っていて、
優先度がそっちのが高かったので怒られたとき「え?入ってるよね?」ってハマった。
#QuickJUnit
JUnitを書くためのEclipseプラグイン。
いろんなショートカットとか雛形とかそろってる。
#Eclemma 3.0.1
Eclipse + EMMAライブラリ。
テストのカバレッジを測るEMMAをEclipse上で動かすためのプラグイン。
Eclemmaはかなり前に更新止まっててほんとはJaCoCoとかを使いたかった。
EclemmaとPowerMock1.5.6は相性が非常に悪く、
PowerMockを用いたテストを実行するとカバレッジ0%とか表示される。
Eclemmaは先ほど説明したJavaバイトコードを見て、どこが実行されたかを
監視しているのだが、
PowerMockが(staticメソッドのモック実現のために)
そのバイトコード(のコピー)をJavassistで編集し、そっちが実行されてしまうため。
この問題はJava8、JUnit5系以降なら全部解決済みである。
#Ruleアノテーション
RunWithの変わりに使うことで、
上記の「カバレッジ0%問題」を回避することができる。
参考:https://code.i-harness.com/ja/q/1647e8c
#まとめ
これで一通りそろった(と思う)
試しに数メソッドのテストコード書いて、実行、カバレッジ測定までできた。
Javaだからまだいいよ、探すのに苦労するだけで、探せばなんとか出てくるんだから。
##なぜこんなに苦労したのか?
###①複数の問題が同時に発生した。
Javassistバージョン競合と、PowerMockとEclemmaの「カバレッジ0%問題」
間接的には、Eclipseのバージョンが古すぎ&Maven無いという開発環境なので
プラグインやライブラリインストールが非常に面倒、って問題も重なった。
1つ1つなら大したことない問題でも、
複数発生すると途端に解決のためにかかる時間がハネあがる。
###②もう解決したから、情報が埋もれる
JUnit5系以降ならPowerMockとEclemmaの「カバレッジ0%」問題は解決している。
つまり、世間では2年前には解決済みなので、今その2つのキーワードでぐぐると、
Ruleアノテーションを使わないRunWithの書き方の方が多くヒットする。
(Ruleで書くとめんどくさいらしい)
##蛇足
苦労して手順化したんだけど、このテスティングフレームワーク群が
ぼくの提案どおり採用されるかわかんない。
何より「カバレッジ100%が必須」とか言われてるので嫌な予感がする。
##追記
結局、「テストを書くのは時間がかかるので手動テストをやろう」
という結論になりました。
どういう判断だ!
っていうか手動テストケース作るの俺じゃないか!
嫌だー!!