Shibuya.apk #36 の ひっそりJetpackに追加されていたApp Crawler toolの紹介 で紹介されていた App Crawler を手元で動かしてみたので、実行方法や、はまったことなどをシェアします。
App Crawlerとは
App Crawlerは、テストコードなしで、自動でUIテストを実行してくれるテストツールです。Firebase Test LabのRobo Testで使われているツールが、おそらくほぼそのまま提供されています。詳しくは、ひっそりJetpackに追加されていたApp Crawler toolの紹介によくまとまっていますので、そちらをご参照ください。
2019年8月8日現在、App Crawlerはまだ正式リリースではなく、Beta 1.0という扱いのようです。App Crawlerの配布ZIPに含まれているREADMEにバージョンとリリースノートが記述されています。
実行方法
App Crawlerは実行可能Jarとして提供されています。公式ドキュメントにある通り、配布されているZIPをダウンロードして、そこに含まれている crawl_launcher.jar
を java
コマンドで起動することで実行できます。
# ZIPファイルをダウンロードして展開
wget https://dl.google.com/appcrawler/beta1/app-crawler.zip
unzip app-crawler.zip
# java コマンドで実行
java -jar app-crawler/crawl_launcher.jar <他にもいくつかオプションが必要>
なお、App Crawlerを実行するときには、テストを実行するデバイス (エミュレーターでも可) がADBで接続している必要があります。
必須のコマンドラインオプション
公式ドキュメントのCrawler optionsセクションに書いてあるように、App Crawlerの実行時には「Android SDKのパス」と「テスト対象のアプリ」を最低限、コマンドラインオプションで指示する必要があります。
Android SDKのパス
--android-sdk
オプションで指定します。
# --android-sdk オプションの例 (Macの場合)
java -jar app-crawler/crawl_launcher.jar --android-sdk ~/Library/Android/sdk <他にもオプションが必要>
テスト対象アプリ
以下のどちらかの方法で、テスト対象のアプリを指定します。
- APKファイルが手元にあるアプリを、デバイスにインストールしてテストする
→--apk-file
オプションでAPKファイルのパスを指定する - デバイスにインストール済みのアプリをテストする (APKファイルは不要)
→--app-package-name
オプションでパッケージ名を指定する
以下は、筆者が Android Architecture Blueprints v2 で試した場合のコマンド例です。
# APKファイルをインストールしてテストする場合の例
java -jar app-crawler/crawl_launcher.jar --android-sdk ~/Library/Android/sdk --apk-file ~/Work/android/android-architecture/app/build/outputs/apk/prod/debug/app-prod-debug.apk
# インストール済みのアプリをテストする場合の例
java -jar app-crawler/crawl_launcher.jar --android-sdk ~/Library/Android/sdk --app-package-name com.example.android.architecture.blueprints.master
テスト結果の出力
テスト結果は、crawl_output
というディレクトリの中にファイルで出力されます。crawl_output
内には、例えば、次のようなファイルが生成されます。
crawl_output/
├── com.example.android.architecture.blueprints.master-logcat.txt
└── app_firebase_test_lab/
├── 1.png
├── 2.png
├── 3.png
├── accessibility1.meta
├── accessibility2.meta
├── accessibility3.meta
├── crawl_outputs.proto
├── crawl_outputs.txt
├── robo_actions.dpb
├── robo_crawls.dpb
├── robo_screen_elements.dpb
└── robo_screens.dpb
.txt
, .png
以外の拡張子のファイルはバイナリファイルで、少なくとも筆者は、バイナリの内容はわかりませんでした。今のところ、テスト実行中のlogcat出力 (*-logcat.txt
) と、アプリのスクリーンショット (*.png
) が、利用可能なテスト出力と言えそうです。
また、テスト実行中にアプリがクラッシュした場合は、テストがそこで中断し、コンソール出力にスタックトレースが出力されます。
筆者がはまった点
App Crawlerの実行にあたって、筆者がはまったポイントを紹介しておきます。
はまりポイント(1): 古いプラットフォームがSDKにインストールされていると起動に失敗する
Android SDKにAPIレベル9 (Android 2.3) 以下のプラットフォームがインストールされていると、App Crawlerの実行に失敗します。
もっと正確に言うと、Android SDKの platforms
ディレクトリ内に、android-7
や android-8
や android-9
といったディレクトリがあると、実行に失敗します。
実行に失敗する理由
App Crawlerは、テストの実行前に、App Crawlerの処理をデバイス上で担うAPKをビルドしてデバイスにインストールする、という処理を行なっており、APKのビルドに、Android SDKにインストールされている最新のプラットフォームの android.jar
を利用しています。
App Crawlerは、android.jar
のパスを得るために「Android SDKにインストールされている最新プラットフォーム」のディレクトリを探すのですが、その処理が単純で、
-
platforms
ディレクトリ内に存在するディレクトリを名前の辞書順に並べて、 - 最後になったものを最新のプラットフォームのディレクトリとしている
ようです。
本当なら android-29
などがヒットして欲しいのですが、android-7
や android-8
などのディレクトリが存在していると、そちらがヒットしてしまい、その中の android.jar
がApp Crawler APKのビルドに使われることになります。App CrawlerはminSdkVersion = 18 のアプリなので、APIレベル10未満の android.jar
ではビルドができず、結果、テストの実行に失敗する、というわけです。
はまりポイント(2): 最近のOSバージョン上でないと実行できない?
App Crawlerの実行APKは minSdkVersion = 18 なので、Android 4.3 (APIレベル18) 以上のデバイスであれば実行できそうなのですが、筆者が手元で確認した限りでは、Android 7.0 (APIレベル24) 以上のデバイスでないとApp Crawlerが期待通りに動作しませんでした。テスト対象のアプリは起動してApp Crawlerが動きかけるのですが、テストの実行が即座に終了してしまいました。
App Crawlerはエラー検出 & エラー出力の実装がまだ不十分なようで、上記のケースでも特にエラーが出力されず、正常に終了したように見えています。何が悪いのかよくわかっていません。