テストを実行した跡にレポートを自動的に開く
gradle経由でテストタスクを実行すると、テスト結果のレポートがbuild/reportsディレクトリに出力される。このレポートファイルを確認するのに、毎回ProjectウィンドウをProject表示に切り替えて、ディレクトリを掘ってファイルをブラウザで開くようにするのは手間である。そこでテスト実行後に自動的に開くようにした。
もっとスマートにやる方法があるのではないかと思うのだが、Gradleがよくわからなくて私には無理だった。以下のタスクをapp/build.gradleに追加した。
task openReportJvmTest(type: Exec) {
workingDir "build/reports/tests/testProdDebugUnitTest"
commandLine 'open'
args "index.html"
}
task openReportInstrumentedTest(type: Exec) {
workingDir "build/reports/androidTests/connected/flavors/MOCK"
commandLine 'open'
args "index.html"
}
openReportJvmTest.onlyIf { !ciBuild && !travisBuild }
openReportInstrumentedTest.onlyIf { !ciBuild && !travisBuild }
tasks.withType(AbstractTestTask) { task ->
if (task.name == "testProdDebugUnitTest") {
task.finalizedBy openReportJvmTest
}
}
tasks.withType(com.android.build.gradle.internal.tasks.AndroidTestTask) { task ->
if (task.name == "connectedMockDebugAndroidTest") {
task.finalizedBy openReportInstrumentedTest
}
}
openReportXXXというのがテストレポートをブラウザで開くタスク。開くディレクトリを直書きしているが、がんばればタスクによって開くディレクトリを変えることはできるだろう。openコマンドを使っているが、Windowsだときっと動かない。
既存のテストタスクのFinalizerタスクとして実行するよう指定しているが、CI上ではopenコマンドが認識できないので失敗してしまう。そこでCI上では実行しないようにonlyIfで指定している。
pluginで定義されているテストタスクの後に実行させたいのだが、tasks.withType
を使うことで各タスクの参照を得ている。直接タスクを指定すると「そんなプロパティはない」と言われたり、nullだったりしてうまくいかなくてこういう形に行き着いた。
取得したテストタスクそれぞれでfinalizedBy
を使ってレポートを開くタスクを指定している。dependsOn
を使うとテストが全てパスしていればレポートが開くが、1つでもテストが失敗しているとopenReportタスクが実行されないので、finalizedBy
を使っている。
http://gradle.monochromeroad.com/docs/userguide/more_about_tasks.html
そもそもRun configurationでテストを実行できるようにすればいいのではないかと思うかもしれない。というか私も最初はその方法をとった。
しかしAndroid Instrumented Testに関してはできたが、Android JUnitではできなかった。
個別のテストをクラスを指定して実行する分には問題ないが(テストコードを表示して実行するやり方)、プロジェクトに存在するテストコードをまとめて実行する方法が取れなかった。Javaで書かれたテストコードは実行されても、Kotlinで書かれたテストが漏れてしまうのである(このプロジェクトはJavaで書かれたテストコードとKotlinで書かれたテストコードが混在している)。
しょうがないのでCIでも実行するgradleのテストタスクを走らせる方法をとることにしたのだ。