先週 Bitrise の build log に "Test Reports" って項目が増えてて、JUnit とかのテスト結果をアップロードしたらGUIでいい感じにみられるようにしてくれる機能が追加されたことを知った。公式のドキュメントを読んだ感じだと Bitrise から提供されてるいくつかの test step の後に Deploy to Bitrise.io 使ったらアップロードされるよと書いてある他に、対応しているファイル形式についても書いてあった。それによると plist
と JUnit XML
に対応しているとのことで、じゃあアップロードの仕組みがわかれば指定されてる test step を使わなくてもできるのでは、と思って色々試したり step のコードを読んだ結果として面倒くさくなって諦めたことについて書き残しておく。
ドキュメントを読んでやってみたこと
私が今 Android アプリ開発をやっているということで読んだのは以下2つ:
特に2つ目の以下の記述について注目した:
You can check your Android unit test results on the Test Reports page. The Android Unit Test Step generates and exports unit test reports into the
$BITRISE_TEST_DEPLOY_DIR
folder. Then the Deploy to Bitrise.io Step exports those reports from the$BITRISE_TEST_DEPLOY_DIR
folder to the respective build’s Test Reports page where you can view the test results.
ここの記述から $BITRISE_TEST_DEPLOY_DIR
にテスト結果 (<module>/build/test-results
) を放り込んだらアップロードできるのではと考えて適当にテスト結果をコピーしてみたところ、何もアップロードされず Test Reports には何も記録されなかった。
コードを読んでわかったこと
どうもファイルがあれば良いという単純な話ではなさそうなので、Test Reports へのアップロードを担当している Deploy to Bitrise.io step と、テスト結果の収集方法についての参考に Android Unit Test step のコードを追ってみた。
Deploy to Bitrise.io の方は、まず main.go
の以下の部分が対応している:
config.TestDeployDir
は $BITRISE_TEST_DEPLOY_DIR
を指しているのでそこに対象のテスト結果を配置することは間違っていないようだ。なので、test.ParseTestResults
が何をしているか紐解く必要がある。これは repository の test/test.go
に記述されている。
ParseTestResults
は長いのでこちらに載せないが、要点をまとめると、
testRootDir
($BITRISE_TEST_DEPLOY_DIR
) 配下の各ディレクトリ (以後testDir
) に対して走査を行うtestDir
からstep-info.json
を取得する、当該ファイルがない、もしくは指定された scheme に合致しない場合は対象ディレクトリに対する処理をスキップtestDir
配下の各ディレクトリに対してファイル取得を行う- 取得した各ファイルに対して、対応フォーマットだった場合には内容を読み取って返却する
results
にResult
型のデータ構造として追加する、その際testDir
配下の各ディレクトリにtest-info.json
が存在することを期待している
という感じになる。ここから、単にテスト結果のディレクトリを $BITRISE_TEST_DEPLOY_DIR
に配置しただけでは、step-info.json
がないのでアップロード対象にならないので Test Reports で表示できないということがわかる。また、仮に step-info.json
が存在したとしても、さらに各 test phase (Android というか gradle でいうところの各 task, testDebugUnitTest
とか testReleaseUnitTest
とか) に対して test-info.json
が無いといけない。
test-info.json
については関数内で test-name
という string 型の property があれば良いことがわかるが、 step-info.json
の必要な scheme については model.TestResultStepInfo
を見る必要がある。これは別の repository にあって、該当するのは以下のリンク先にある。
https://github.com/bitrise-io/bitrise/blob/master/models/models.go#L128-L134
とりあえず必要な scheme は↓のとおり
{ id: string, version: string, title: string, number: number }
ということでアップロード側が対象を認識する部分についてはなんとなくわかったので、今度は対象を作って配置する側で、主にテスト結果ファイルや step-info.json
や test-info.json
の中身がどうなっていればよいのか? を見るために Android Unit Test の repository をのぞいてみる。
とりあえず main.go
から、関係するのはこの辺: https://github.com/bitrise-steplib/bitrise-step-android-unit-test/blob/dd2535d711f8515202beb3f02ef43c9b2c268b5b/main.go#L215-L233
artifact によって unique なディレクトリを作って、そこに xml を export してるっぽいことが読み取れる。ディレクトリは <module>-<variant>
って名前。Export 処理については testaddon/testaddon.go
の方で、test-info.json
作って xml を$BITRISE_TEST_RESULT_DIR/<module>-<variant>/
の下にコピーしてるだけ。 $BITRISE_TEST_DEPLOY_DIR
のサブディレクトリを指す環境変数だそうな。
さて step-info.json
についてまるで触れられてないけどどういうことなんでしょう。この辺でもういいやってなって諦めた。
追記 (2019-06-16)
step-info.json の出所見つけた / https://t.co/6JjHRRISJq
— nash (@nashcft) June 11, 2019
追記終わり
さいごに
多分 test の後に script
step で JSON をいい感じに作ってテスト結果と一緒に配置すれば指定の test step を使わなくても Test Reports が使えるのだろうけど、調査だけで怠くなったのと完全にレールを外れたことしてるなって感じて、それを解決方法にしたくないという気持ちになったので試してない。
Android で Test Reports を使いたい人は大人しく Android Unit Test を使おう、というべきところなのだろうけど、この step も問題があって、1 step で1つのモジュールに対してしかテストを実行できないし、project root 直下のモジュールしか認識できないのでグループ分けとかでもっと下の階層にモジュールが存在する場合は Android Unit Test でそれを実行できないし、例えば JaCoCo とかで coverage report を作成している場合はそれ用の task を実行してると思うけど Android Unit Test は モジュールと build variant しか指定できなくて test<Variant>UnitTest
とか基本の test task しか実行できないので coverage report が欲しかったら別途 step を実行しなきゃできないとか、とにかく融通がきかない。
Android project で任意の gradle task を使ってテストを実行したい場合には Gradle Unit Test という step があるけど、当然こっちには Test Reports 向けの export 処理は入ってなくて、やっぱり欲しいって人はいて feature request が既に投稿されている。
また、Flutter project 向けにも Test Reports に対応する request も今日投稿されていた。
このような感じで、現状 Test Reports を活用するには Bitrise 側の準備というか状況が全然足りてなくて、みんながみんな自分の use case に応じた feature request を送ったり、これからも送られるだろうなという感じなのだけど、その要望に対してそれぞれの test step に Test Reports 向けの処理を埋め込むという解決法をとると、これまで作ったものにもそうだし、これから新たに test step が追加される場合にも逐一その処理を追加することになって手間だよなーと感じたし、現行の実装を見るにテスト結果を格納しているディレクトリの場所について限定された想定しかされてなくて融通効かなさそうなの嫌だなーって思ったので、独立した step にして project の種類や構成、使用してる step に依存しないようにしてほしいなーってことで私も feature request を投稿した。
個人的には repository 中を適当に走査して、対応する format のファイルを全部 $BITRISE_TEST_RESULT_DIR
に放り込んで、あとは必要な json を適当に生成してよしなに体裁を整えてくれれば良くて、例えば複数モジュールに対するテスト結果があったとしても、全部1つのグループにまとめられてしまっても構わないと考えてる。まあファイルの存在するディレクトリの情報を取っておいて、それを元に metadata とか格納先ディレクトリを区別するとかでできるのかもしれないけど。
この機能周辺に関しては悪い意味での easy に寄ったスタートしてるなーって感想で、触っててストレスしか感じないような現状なので早く使いやすくなってほしい...