nashcft's blog

時々何か書く。

Bitrise Test Reports について調べてみた記録

先週 Bitrise の build log に "Test Reports" って項目が増えてて、JUnit とかのテスト結果をアップロードしたらGUIでいい感じにみられるようにしてくれる機能が追加されたことを知った。公式のドキュメントを読んだ感じだと Bitrise から提供されてるいくつかの test step の後に Deploy to Bitrise.io 使ったらアップロードされるよと書いてある他に、対応しているファイル形式についても書いてあった。それによると plistJUnit 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 のコードを追ってみた。

github.com

github.com

Deploy to Bitrise.io の方は、まず main.go の以下の部分が対応している:

https://github.com/bitrise-steplib/steps-deploy-to-bitrise-io/blob/f1ce02dacdb35d56c05b3e6fc1522ad53828ca33/main.go#L229-L246

config.TestDeployDir$BITRISE_TEST_DEPLOY_DIR を指しているのでそこに対象のテスト結果を配置することは間違っていないようだ。なので、test.ParseTestResults が何をしているか紐解く必要がある。これは repository の test/test.go に記述されている。

https://github.com/bitrise-steplib/steps-deploy-to-bitrise-io/blob/f1ce02dacdb35d56c05b3e6fc1522ad53828ca33/test/test.go#L120-L212

ParseTestResults は長いのでこちらに載せないが、要点をまとめると、

  1. testRootDir ($BITRISE_TEST_DEPLOY_DIR) 配下の各ディレクトリ (以後 testDir) に対して走査を行う
  2. testDir から step-info.json を取得する、当該ファイルがない、もしくは指定された scheme に合致しない場合は対象ディレクトリに対する処理をスキップ
  3. testDir 配下の各ディレクトリに対してファイル取得を行う
  4. 取得した各ファイルに対して、対応フォーマットだった場合には内容を読み取って返却する resultsResult 型のデータ構造として追加する、その際 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.jsontest-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)

追記終わり

さいごに

多分 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 が既に投稿されている。

discuss.bitrise.io

また、Flutter project 向けにも Test Reports に対応する request も今日投稿されていた。

discuss.bitrise.io

このような感じで、現状 Test Reports を活用するには Bitrise 側の準備というか状況が全然足りてなくて、みんながみんな自分の use case に応じた feature request を送ったり、これからも送られるだろうなという感じなのだけど、その要望に対してそれぞれの test step に Test Reports 向けの処理を埋め込むという解決法をとると、これまで作ったものにもそうだし、これから新たに test step が追加される場合にも逐一その処理を追加することになって手間だよなーと感じたし、現行の実装を見るにテスト結果を格納しているディレクトリの場所について限定された想定しかされてなくて融通効かなさそうなの嫌だなーって思ったので、独立した step にして project の種類や構成、使用してる step に依存しないようにしてほしいなーってことで私も feature request を投稿した。

discuss.bitrise.io

個人的には repository 中を適当に走査して、対応する format のファイルを全部 $BITRISE_TEST_RESULT_DIR に放り込んで、あとは必要な json を適当に生成してよしなに体裁を整えてくれれば良くて、例えば複数モジュールに対するテスト結果があったとしても、全部1つのグループにまとめられてしまっても構わないと考えてる。まあファイルの存在するディレクトリの情報を取っておいて、それを元に metadata とか格納先ディレクトリを区別するとかでできるのかもしれないけど。

この機能周辺に関しては悪い意味での easy に寄ったスタートしてるなーって感想で、触っててストレスしか感じないような現状なので早く使いやすくなってほしい...