CircleCI での Firebase Test Lab ロボテスト自動化

CircleCI で Android の `apk` をビルドしたときに、 Firebase Test Lab にテストを投げたいときのやりかたです。

大体は CircleCI 公式ページの https://circleci.com/docs/2.0/language-android/#testing-with-firebase-test-lab に載ってる流れです。

## 概要

1. ビルドされた `apk` を `gcloud` コマンドを使って投げ
2. 結果が出力されるまで待つ
3. 結果が Google Cloud Storage バケットに保存される
4. 結果をバケットから取り出して Artifact として保存

という流れになります。

CircleCI の Android ビルド用の イメージには Test Lab の実行に必要な `gcloud` コマンドが入ってるので
これを使っている場合は別のイメージを使ったりする必要はないです。通常のビルドで使ってる `config.yml` に、
Test Lab に送るジョブを追加すれば OK です。

## 前提

まずリリースビルドを行う job がこういう感じだったとします:

```yml:.circleci/config.yml
jobs:

  buildRelease:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/code
      - deploy:
          name: Build Release Apk
          command: ./gradlew :app:assembleRelease
      - store_artifacts:
          path: app/build/outputs/apk/
      - persist_to_workspace:
          root: ~/code
          paths:
            - app/build/outputs/apk
```

後に別ジョブで Test Lab に `apk` を送れるように
ここで `persist_to_workspace` をして、ビルドした apk をワークスペースで共通に参照できるようにしておくことが必要です。

## Test Lab のジョブを追加

次に Test Lab でテストするジョブを追加します:

```yml:.circleci/config.yml
jobs:

  runRoboTest:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/code
      - run:
          name: Authorize with gcloud
          command: |
            echo ${GCLOUD_SERVICE_KEY} | sudo gcloud auth activate-service-account --key-file=-
            sudo gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
      - run:
          name: Invoke Robo Test on Firebase Test Lab
          command: >
            sudo gcloud firebase test android run \
              --app app/build/outputs/apk/release/app-release.apk \
              --type robo \
              --device model=hwALE-H,version=21,locale=ja,orientation=portrait \
              --device model=j1acevelte,version=22,locale=ja,orientation=portrait \
              --device model=shamu,version=23,locale=ja,orientation=portrait \
              --device model=lucye,version=24,locale=ja,orientation=portrait \
              --device model=sailfish,version=25,locale=ja,orientation=portrait \
              --device model=sailfish,version=26,locale=ja,orientation=portrait \
              --device model=walleye,version=27,locale=ja,orientation=portrait \
              --device model=walleye,version=28,locale=ja,orientation=portrait \
              --results-bucket cloud-test-${GOOGLE_PROJECT_ID} \
              --timeout 5m
      - run:
          name: Collect Artifacts
          command: |
            sudo pip install -U crcmod
            sudo mkdir test_lab_results
            sudo gsutil \
                -m cp \
                -r -U `sudo gsutil ls gs://cloud-test-${GOOGLE_PROJECT_ID} | tail -1` test_lab_results/ \
                | true
      - store_artifacts:
          path: test_lab_results/
```

認証してテストを実行し、結果を Artifacts として保存するジョブです。

ここで `${GCLOUD_SERVICE_KEY}` やら `${GOOGLE_PROJECT_ID}` ならの謎の環境変数が登場していますね。

これはあらかじめ、認証情報として Firebase の認証鍵の JSON と Google Cloud Platform のプロジェクト ID を
CircleCI のプロジェクト環境変数にコンソールから設定しておく必要があります:

<img width="751" alt="Project_settingsCircleCI.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/8d75747b-a760-0c6a-c267-68860f1a9a6e.png">

`GOOGLE_PROJECT_ID` は GCP のプロジェクト ID を、`GCLOUD_SERVICE_KEY` には認証情報の JSON を入れます。

あとは Google Developer Console で `Cloud Testing API` と `Cloud Tools Results API` を有効にしておきましょう:

<img width="777" alt="gdc-cloud-testing-api.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/2ff48438-7e80-a93d-c684-cb7bdf021400.png">


## 結果

ひととおり設定が終わったら、ビルドを走らせてみます:

<img width="963" alt="CircleCI.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/b3dad2de-f3dd-2f43-7250-ff3bb5e4a3d1.png">

認証を行ってから Test Lab を実行するジョブが走っていることが確認できますね。

実行中でもジョブのログに記載されている Firebase Test Lab の詳細ページで確認することができます
(`Test results will be streamed to [...]` で示された URL です)。

テスト終了後の結果は詳細ページに加えて、Artifacts としても保存されます:

<img width="597" alt="circleci-artifacts.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/37b2c767-ea8c-8536-5956-c7d5bdaf811b.png">

## 注意点

Test Lab のジョブのコマンドのうち

> `--device model=<MODEL_ID>,... --device model=<MODEL_ID>,...`

の部分でテスト対象のデバイスを複数指定できますが、ここの `MODEL_ID` の確認方法は `gcloud firebase test android models list` コマンドで取得できる `MODEL_ID` です。

たとえば Pixel 2 でも、物理デバイスの `MODEL_ID` は `walleye` で、仮想デバイスのほうは `Pixel2` だったりします。`Pixel2` だろうと決めてかかったら、このコマンドの結果を見ないと絶対わからないので注意です。

`gcloud` まわりの使い方については https://firebase.google.com/docs/test-lab/android/command-line を参照するのがいいでしょう。

テストに時間がかかったり、謎に失敗する端末もあるので、ここは一度試して試行錯誤する必要がありそうです。