nashcft's blog

時々何か書く。

Bitrise で Android instrumentation test を実行させるための調査メモ

最近 Android アプリの instrumentation test を実行する workflow を構築する機会があったので、そのために当たった情報やついでに気になって調べたことなどを覚書も兼ねて記事にすることにした。

目次

Steps

必要なのは以下の2つ:

基本的に何を設定すればいいかは公式のドキュメントを読んで組み立てればOK。

devcenter.bitrise.io

Virtual Device Testing for Android で instrumentation test の設定をする

実行するテストを指定する

Workflow Editor の Virtual Device Testing for Android には Instrumentation Test というセクションがあって、 instrumentation test のための設定がいくつか行える。開くと以下のキャプチャのような感じ。

f:id:nashcft:20191207193823p:plain

この中の Test targets, seperated with the "," character. という項目で実行するテストを指定することができる。指定の方法は3種類あって、editor の記述を持ってくると

  • package package_name
  • class package_name.class_name
  • class package_name.class_name#method_name

というようにパッケージ単位から特定のテストメソッドまで指定することができる。上のキャプチャではクラス単位での指定をしているが、例えばパッケージでまとめるなら package jp.nashcft.uitest.example 、テストケース単位だったら class jp.nashcft.uitest.example.UITest1#fooTest というようにすれば良い。

これによって特定の文脈では一部のテストだけ実行する、みたいなことができ、例えば Room のスキーマを変更する際に特別な branch 名を使うようにして、その branch に対する workflow では migration test だけを実行対象にした instrumentation test の step を設定する、といったことが考えられる。

また、項目名にあるように、複数の実行対象を指定する場合は , で区切れば良い。これにはちょっとした罠があって、多数指定する場合、可読性のために改行を挟みたくなることがあると思うが、, の後に改行を入れてしまうと最後の行で指定された対象以外は実行対象として認識されなくなってしまう。なので、一切改行を入れずに羅列するか、どうしても改行したい場合は classpackage の後の whitespace で改行すると全ての対象を認識してくれるので、そのように回避する必要がある。とはいえ Workflow Editor 空記入するにしても bitrise.yml に直接書き込むにしてもどうせコピペ運用になると思うのでそこまで気にしなくても良いかもしれない。余談だが、この挙動について認識しているのか editor で改行せず実行対象を羅列して保存し、 bitrise.yml を見ると、class / package の後で改行しながらの記述になっている。

Test Reports で実行結果を見る

Test Reports そのものについては公式のドキュメントがあるのでそちらを参照してほしい。

devcenter.bitrise.io

Test Reports で確認できるものは、各テストケースの実行結果の他に、テスト実行時の録画やスクリーンショット、ログ、CPU/RAM/Network のプロファイルなどがある。

ところで今回構築していた時に気づいて確認したことだが、Virtual Device Testing for Android を使用した場合、そのあとで Deploy to Bitrise.io を実行しなくても Test Reports に実行結果がアップロードされている。内容的に先に UI testing のページを読んでいた場合には別に当然という認識になるのだが、私は以前 Test Reports の方だけ調べていた時期があって、そちらのページには (今でも) test step 実行後に Deploy to Bitrise.io を実行すると結果をアップロードしてくれると書いてあったので、deploy 忘れてるのに Test Reports が見られたので少し驚いてしまった。

既知の問題

Android library の AndroidTest build が失敗する

Android library は assemble すると aar を生成するが、 Android Build for UI Testing は成果物に apk だけを想定しているため、 step が失敗してしまう、という issue があがっている。

github.com

こちらに関しては Bitrise の中の人に認知されていて、 forum の方で feature request が作成されている。この feature request は vote の数が多くなると priority の高い項目として対応されやすくなるので、関心のある人や対応されないと困るなあという人はログインしてこの request に vote しておくと良い。

discuss.bitrise.io

現状でなんとか Android library の instrumentation test を実行したいという場合は、多分 script step で自分でコマンド指定してビルドして、成果物の出力先パスを Virtual Device Testing for AndroidApp pathTest APK path に渡せば動くかもしれない。これはまだ試していないので実行できるかは不明。

Nested module はビルド対象として認識されない

これは Android 系 build step 共通の問題なのだが、現状 project の root directory にある module しかビルド対象として認識されず、存在しない module を指定しているとしてビルドが失敗する。

例えば以下のような project があるとする:

/
+ app
|  + build.gradle
+ features
  + featureA
  |  + build.gradle
  + featureB
     + build.gradle

この場合、step に認識される module は app だけで、 feature ディレクトリ以下の各 module は検出されない。

この問題については原因となるパッケージに対して既に修正のPR が出されていて merge もされており、これに依存している各 step のレポジトリも依存を更新しているので、次回のバージョンアップで解決するはず。

調べてないこと

  • Instrumentation test の設定の Use Orchestrator って何
    • 多分以下のドキュメントに書いてある設定のことだと思うけど、外部から設定できるんだなって

developer.android.com

先の話、願望の話

前述した nested module を認識しない問題と Android Build for UI Testing (と、もしかしたら Virtual Device Testing for Android も) の aar 対応がリリースされたら feature module などの instrumentation test 用 workflow を構築するつもりだ。これについて既に見えている課題として、

  • それぞれ 1 step あたり1つの module しか対象にできない
  • 現状 Virtual Device Testing for Android が1ビルドあたり1 step しか設定できない

というのがある。これらを解決する一番単純な方法は対象となる module の分だけ workflow を作って Bitrise Start Build で並列化して繋いで実行するという感じになるが、数個だけならまだやるとしても既に数十個の module に分割されているアプリに対してそれをするのは作業する気にもなれないし、仮にやったとして、1回実行しただけで queue がパンクするんだよなあ... となる。Queue の方は per concurrency plan から Pay as You Go plan に変更すれば一応解決するが、財力の問題が当然ある。

まあ Pay as You Go plan にするにしてもそうでないにしても、こういう方針でやるなら全ての module に対してまとめてビルドを行って、artifact をテスト実行コンテナにバラバラっと配って、そちらでそれぞれの module の instrumentation test を実行する、というような構成ができたら総ビルド時間も短くなるし嬉しいんだよなという思いがある。これは実質 CircleCI の workflow による job の pipeline 化と1つの workflow 内での workspace の共有と同じような発想なのだけど、Bitrise でも build router start で workflow の並列実行ができるようになっているのだしこういうことが Bitrise でもできるようになってほしいなあって期待してる。

circleci.com

もしくは Android Build for UI Testing が variant だけ適当に指定したらそれにヒットする module のビルドを行ってくれるようになって、Virtual Device Testing for Android が複数のテスト対象を 1 step でまとめて実行してくれるようになってくれたら、というアイデアもある。こっちの方がユーザ的にはやることが少なくなって楽だけど、任意の数の module に対して成果物を取得してそれぞれに対して Firebase Test Lab (もしくは何らかの device farm) でテストを実行して結果を収集して Test Reports にアップロードするというのを実現するのはしんどそうだなあと思う。

終わりに

Android の instrumentation に必要な2つの step は、Android Build for UI Testing は v0.1.1, Virtual Device Testing for Android は step 名に [BETA] とついていることから察せるようにまだ発展途上というか機能的に物足りなく、単純に apk のテストをすることしかできないが、単にいくつかの設定を記入するだけでUIテストを実行してくれる手段を公式で提供してくれているというのは他のCIサービスにはない強みだと思うので、今後のバージョンアップに期待したい。

参考資料