概要
Firebase Test Labはクラウドベースのアプリテスト基板です。この投稿ではCircleCIからFirebase Test LabでのAndroidアプリのテストを実行する方法についてまとめます。
サンプルアプリ
Firebase Test Labでテスト実行するサンプルアプリとして以下を用意しました。2Activityで構成される簡単なアプリで、テストコードをEspressoで書いています。
CLIからのFirebase Test Labによるテストの実行
まずローカル環境でCLIからFirebase Test Labによるテストを実行できるようにします。その流れとしては以下のようになります。
- Firebaseプロジェクトの作成と課金
- Google Cloud SDKの実行環境の構築
- テストの実行
これらの詳細は以下の記事にまとめています。
CircleCIからのFirebase Test Labでのテスト実行の流れ
ローカル環境からCLIを使用してテストを実行できたのでCIのプロセスへ組み込みます。CIが実行される流れとして今回は以下のような流れを想定します。
- コードの変更をコミットしリポジトリにプッシュ
- CircleCIが変更を検知しビルドを開始
- Firebase Test Labによるテストの実行
Firebase Test Labによるテストの実行の部分を分解すると以下のようになります。
- コードの変更をコミットしリポジトリにプッシュ
- CircleCIが変更を検知しビルドを開始
- gcloudコマンドラインツールの設定、認証処理
- apkおよびテストapkの作成
- Firebase Test Labによるテストの実行
この内、gcloudコマンドラインツールの認証処理は、CLIで実行した場合と異なります。
CircleCIでのgcloudコマンドラインツールの認証処理
認証方法
CircleCIでのgcloudコマンドラインツールの認証には、サービスアカウントキーを使用します。サービスアカウントキーは、JSONとP12形式を選択できますが、今回はキーをJSONファイルとしてダウンロードします。
サービスアカウントの作成とキーのダウンロード
サービスアカウントキーを作成するには、こちらのリンクからGoogle Cloud PlatformのAPIマネージャーを開き、先ほど作成したFirebaseプロジェクトを選択します。
次にサービスアカウントを作成します。サービスアカウント名
とサービスアカウントID
を入力して新規作成します。役割
には、テスト結果を保存する際にGoogle Cloud Storageへのアクセスが必要になるので編集者
を指定します。サービスアカウントの役割についての詳細は、こちらから確認できます。そしてキーのタイプにJSON
を選択し作成
をクリックするとJSONファイルがダウンロードされます。
サービスアカウントキーは認証情報ですので扱いには十分注意してください。
必要なAPIの有効化
Google Cloud Testing API
とCloud Tool Results API
を有効にします。APIを有効にするためには、コンソール上部の検索窓にAPI名を入力し、APIの概要ページで「有効にする」をクリックします。有効化後、「すべてのAPI認証情報」にサービスアカウントキーを作成したサービスアカウントが表示されていることを確認します。
CircleCIのセットアップ
プロジェクトの追加
CircleCIとGitHubリポジトリを紐付けます。例として、サンプルとして用意した「FirebaseTestLabSample」をプロジェクトとして追加します。organizationを選択し、リポジトリ名の右側に表示されている「Build Project」をクリックすれば最初のビルドが開始されます。
CircleCIへのサービスアカウントキーの追加
以前のセクションでサービスアカウントキーをJSONファイルとしてダウンロードしたと思います。CircleCIがgcloudを認証するために、CircleCIはサービスアカウントキーへアクセスする必要がありますが、このキーをバージョンコントロール下で直接管理するのはセキュリティ的にスマートなやり方ではありません。直接管理する代わりにCircleCIの環境変数を利用して認証させます。
まず最初にサービスアカウントキーをbase64でエンコードし、その結果をコピーします。
$ base64 <your-service-account.json>
先ほど追加したプロジェクトが左側のBUILDSから確認できるので選択します。プロジェクト名の右側もしくは右上にあるProject Settings
をクリックします。
設定メニューが表示されるのでEnvironment variables
を選択し、Add Variable
をクリックします。
NameにCLIENT_SECRET
、Valueにコピーしたエンコード済みのサービスアカウントキーの値をペーストし、Save variables
をクリックします。これでCircleCIのビルドからサービスアカウントキーへアクセスできるようになりました。
gcloudコマンドラインツールの認証
環境変数に登録したサービスアカウントキーは、ビルドスクリプトでJSONファイルにデコードします。
$ echo $CLIENT_SECRET | base64 --decode > ${HOME}/client-secret.json
そしてclient-secret.json
を使用してgcloudコマンドラインツールの認証を行います。
$ gcloud auth activate-service-account --key-file ${HOME}/client-secret.json
circle.yml
CircleCIからgcloudコマンドラインツールの認証を行う準備ができました。今回、CIが実行される流れを以下のように想定していますので、この流れを実現するようcircle.ymlを定義していきます。
- コードの変更をコミットしリポジトリにプッシュ
- CircleCIが変更を検知しビルドを開始
- gcloudコマンドラインツールの設定、認証処理
- apkおよびテストapkの作成
- Firebase Test Labによるテストの実行
1,2に関してはリポジトリをCircleCIに追加した時点で既に実現できているので、circle.ymlで定義するのは3,4,5についてです。
dependenciesセクション
dependenciesセクションでは、サンプルアプリのビルドに必要なAndroid SDKのアップデートとgcloudコマンドラインツールの設定、認証処理を行います。
サンプルアプリでは、compileSdkVersionを24、buildToolsVersionを24.0.2に指定し、加えてsupport libraryを利用しているのでAndroid SDKのアップデートは以下のようなコマンドになります。
dependencies:
override:
- echo y | android update sdk --no-ui --all --filter "android-24,build-tools-24.0.2"
- echo y | android update sdk --no-ui --all --filter "extra-android-m2repository"
また、gcloudコマンドラインツールの設定、認証処理は以下のようになります。gcloud config set project
でセットしているプロジェクト名は環境変数PROJECT_IDとして定義しています。環境変数CLIENT_SECRETに格納したサービスアカウントキーをclient-secret.jsonにデコードし認証に使用します。--quiet
オプションを指定すると全てのインタラクティブなプロンプトを無効にします。
dependencies:
override:
- echo $CLIENT_SECRET | base64 --decode > ${HOME}/client-secret.json
- sudo /opt/google-cloud-sdk/bin/gcloud config set project $PROJECT_ID
- sudo /opt/google-cloud-sdk/bin/gcloud --quiet components update
- sudo /opt/google-cloud-sdk/bin/gcloud --quiet components install beta
- sudo /opt/google-cloud-sdk/bin/gcloud auth activate-service-account --key-file ${HOME}/client-secret.json
最終的なdependenciesセクションの設定は以下のようになります。
dependencies:
override:
- echo y | android update sdk --no-ui --all --filter "android-24,build-tools-24.0.2"
- echo y | android update sdk --no-ui --all --filter "extra-android-m2repository"
- echo $CLIENT_SECRET | base64 --decode > ${HOME}/client-secret.json
- sudo /opt/google-cloud-sdk/bin/gcloud config set project $PROJECT_ID
- sudo /opt/google-cloud-sdk/bin/gcloud --quiet components update
- sudo /opt/google-cloud-sdk/bin/gcloud --quiet components install beta
- sudo /opt/google-cloud-sdk/bin/gcloud auth activate-service-account --key-file ${HOME}/client-secret.json
testセクション
testセクションで行うことは、apkおよびテストapkの作成とFirebase Test Labによるテストの実行です。apkおよびテストapkの作成するには、assembleDebug
タスクとassembleAndroidTest
タスクを実行します。
test:
override:
- ./gradlew assembleDebug assembleAndroidTest
そして、gcloud beta test android run
コマンドでFirebase Test Labでのテストをスケジューリングします。
test:
override:
- ./gradlew assembleDebug assembleAndroidTest
- gcloud beta test android run --type instrumentation --app app-debug.apk --test app-debug-test.apk --device-ids Nexus5 --os-version-ids 21 --locales ja_JP --orientations portrait
テストに必要なパラメーターは、上記のようにgcloud beta test android run
コマンドのオプションとして指定することも出来ますが、見通しが悪いのでYAMLファイルにまとめてしまいます。
instrumentation-test:
type: instrumentation
app: app/build/outputs/apk/app-debug.apk
test: app/build/outputs/apk/app-debug-androidTest.apk
device-ids: Nexus5
os-version-ids: 21
locales: ja_JP
orientations: portrait
オプションとしてYAMLファイルに定義した値を使用した場合、args.yaml:instrumentation-test
の形式で指定します。YAMLファイルへの定義方法についてはgcloud topic arg-files
を実行することで確認できます。
test:
override:
- ./gradlew assembleDebug assembleAndroidTest
- echo "y" | sudo /opt/google-cloud-sdk/bin/gcloud beta test android run test_settings.yml:instrumentation-test
CircleCIのartifactsへのテスト結果の保存
gsutil
を使用することでCircleCIのartifactsにGoogle Cloud Storageのbucketに保存されたテスト結果の内、最も新しいファイルをダウンロードすることができます。これによって、Google Cloud StorageとCircleCIの両方でテスト結果を利用することができます。
最終的なcircle.ymlは以下のようになります。
dependencies:
pre:
- sudo pip install -U crcmod
override:
- echo y | android update sdk --no-ui --all --filter "android-24,build-tools-24.0.2"
- echo y | android update sdk --no-ui --all --filter "extra-android-m2repository"
- echo $CLIENT_SECRET | base64 --decode > ${HOME}/client-secret.json
- sudo /opt/google-cloud-sdk/bin/gcloud config set project $PROJECT_ID
- sudo /opt/google-cloud-sdk/bin/gcloud --quiet components update
- sudo /opt/google-cloud-sdk/bin/gcloud --quiet components install beta
- sudo /opt/google-cloud-sdk/bin/gcloud auth activate-service-account --key-file ${HOME}/client-secret.json
test:
override:
- ./gradlew assembleDebug assembleAndroidTest
- echo "y" | sudo /opt/google-cloud-sdk/bin/gcloud beta test android run args.yaml:instrumentation-test
post:
- sudo /opt/google-cloud-sdk/bin/gsutil -m cp -r -U `sudo /opt/google-cloud-sdk/bin/gsutil ls gs://${BUCKET_NAME} | tail -1` $CIRCLE_ARTIFACTS/ | true
テスト結果はスクリーンショットや以下のように動画で確認できます。
まとめ
CircleCIからFirebase Test LabでのAndroidアプリのテストを実行することができました。CircleCIでは、gcloudやgsutilといったコマンドが予めインストールされているため連携がしやすかったです。また、ビルドの実行時間は大体11分程度でした。CircleCIでのビルドの詳細はこちらから確認できます。