Firebase Test Labで簡単にテストをしてみよう！

## 対象
今までAndroidのUIテストをほとんど行ったことがない方を対象としています。

## 今回やること
Firebase Test LabのRobo Testのお陰でAndroidのテストの敷居が一気に下がりました。
今回は適当なGoogleのサンプルアプリを対象にFirebase Test Labを使ってテストを実施します。
テストケースの作成に関しては触れません。
Firebase Test Labを操作する方法はいくつかありますが、
今回はCIにも統合しやすいようにCLIで操作していきたいと思います。

## 作業環境
* Mac
* Homebrew
* Python 2.7 (Google Cloud Platformで使います)


## そもそも何がテストできるのか
Googleが提供している実機上(もしくはVM上)でE2Eテスト(UIのテスト)を行うことができます。
Firebase Test Labには2種類のテストタイプがあります。

* Instrumentation Test
* Robo Test

### Instrumentation Test
従来のAndroidが提供しているテストフレームワークです。
Android端末内で、テストアプリがInstrumentation越しに実際のアプリに対してテストを実施します。
今現在は以下の3種類のフレームワークに対応しています。

* Espresso
* UI Automator 2.0
* Rbotium

残念ながら今現在はAppiumには対応していません...。
今後に期待しましょう。

Firebaseとは直接関係ありませんが、
Android Studio 2.2以上でしたら[Espresso Test Recorder](https://developer.android.com/studio/test/espresso-test-recorder.html?utm_source=android-studio)を利用することで、UIの操作から自動的にテストコードを生成することができます。

### Robo Test
Firebase Test Labで動作する新たなテストタイプです。
AndroidアプリのUI要素を解析して自動で操作してくれます。
なので、AndroidのUIフレームワークを利用していないアプリはテストできません。

モンキーテストに近いですが、ランダムに操作するのではなく、
一定の規則性を持ってUIの解析/操作を行うので、同様の条件であれば常に同じ操作が期待されます。

実施後、操作した画面遷移を元に画面遷移図が自動生成されます。

## Step by Step

### 事前準備

Espressoでテストが書かれているGoogleの[サンプルアプリ](https://github.com/googlesamples/android-topeka)をFirebase Test Labで動かしたいと思います。

#### Firebaseの設定
[Firebaseコンソール](https://console.firebase.google.com/?hl=ja)で今回使うプロダクトを作成してください。
その後、

```
プロジェクトの設定 > サービスアカウント > 新しい秘密鍵の生成
```

で、Google Cloud SDKで利用するJSON形式の認証情報をダウンロードしてください。　(以降${keyfile}.jsonとします。)
![スクリーンショット 2016-12-02 4.16.03.png](https://qiita-image-store.s3.amazonaws.com/0/84972/446853ad-d3e3-d947-89a0-2f838427e864.png "スクリーンショット 2016-12-02 4.16.03.png")

その後、 **すべてのサービス アカウントを管理** に移動し、 **Google Cloud Testing API** と **Cloud Tool Results API** を有効化します。


#### Google Cloud SDKをセットアップ
Homebrew Caskでインストールし、先ほどダウンロードしてきた認証情報を設定します。

```
brew cask install google-cloud-sdk
gcloud auth activate-service-account --key-file ${keyfile}.json
```

#### テスト対象アプリとテストアプリをビルド

```
$ cd ${WorkSpace}
$ git clone https://github.com/googlesamples/android-topeka
$ cd android-topeka
$ ./gradlew assembleDebug
$ ./gradlew assembleDebugAndroidTest
$ cd app/build/outputs/apk
```
`./gradlew assembleDebug`でテスト対象アプリのビルド、
`./gradlew assembleDebugAndroidTest`でテストアプリのビルドを行います。

### Firebase Test Lab (Instrumentation Test)
今回cloneしてきたプロダクトには既にEspressoを使ったテストケースが書かれているので、
そのままInstrumentationタイプのテストを実行していきます。

以下のコマンドでテスト可能なデバイスリストを取得できます。

```
gcloud beta test android devices list
```

以下のコマンドでテスト可能なAPI Levelを取得できます。

```
gcloud beta test android versions list
```

以下のコマンドで実際にテストを実施します。
オプションは適宜変更してください。

```
$ gcloud beta test android run \
	--type instrumentation \
	--app app-debug.apk \
	--test app-debug-androidTest.apk \
	--device-ids Nexus5 \
	--os-version-ids 21 \
	--locales ja
```

以下のようにCLI上に結果が確認できます。

```
Have questions, feedback, or issues? Get support by visiting:
  https://firebase.google.com/support/

Uploading [app-debug.apk] to Firebase Test Lab...
Uploading [app-debug-androidTest.apk] to Firebase Test Lab...
Raw results will be stored in your GCS bucket at [https://console.developers.google.com/storage/browser/test-lab-3ckx1zasj957c-ytd8urz864y82/2016-12-02_04:53:37.683754_Xleh/]

Test [matrix-bapkms9vyca3] has been created in the Google Cloud.
Firebase Test Lab will execute your instrumentation test on 1 device(s).
Creating individual test executions...done.

Test results will be streamed to [https://console.developers.google.com/project/topeka-3dbf6/testlab/mobile/histories/bh.95375e7332cdbe60/executions/9063728638933816166].
04:53:49 Test is Pending
04:54:03 Starting attempt 1
04:54:03 Test is Running
04:54:59 Installing APK: com.google.samples.apps.topeka
04:55:06 Installing APK: com.google.samples.apps.topeka.test
04:55:13 Logging into the device
04:55:21 Running instrumentation test. Package: com.google.samples.apps.topeka.test testrunner: android.support.test.runner.AndroidJUnitRunner options: []
05:02:39 Instrumentation test has finished
05:02:39 Retrieving test artifacts
05:02:51 Retrieving any crash results
05:03:31 Retrieving logcat
05:03:45 Done. Test time=432 (secs)
05:03:52 Test is Finished

Instrumentation testing complete.

More details are available at [https://console.developers.google.com/project/topeka-3dbf6/testlab/mobile/histories/bh.95375e7332cdbe60/executions/9063728638933816166].
┌─────────┬───────────────────────┬──────────────────────┐
│ OUTCOME │    TEST_AXIS_VALUE    │     TEST_DETAILS     │
├─────────┼───────────────────────┼──────────────────────┤
│ Passed  │ Nexus5-21-ja-portrait │ 58 test cases passed │
└─────────┴───────────────────────┴──────────────────────┘
```

### Firebase Test Lab (Robo Test)
では、そのままRobo Testも実施しましょう。

```
gcloud beta test android run \
	--type robo \
	--app app-debug.apk \
	--device-ids Nexus5 \
	--os-version-ids 21 \
	--locales ja
```

Instrumentation Testと違い、Robo Testが自動で操作を行ってくれるので、テストアプリは必要ありません。

Instrumentation Testと同様にCLI上で結果が確認できます。


### 詳細な結果を確認

Firebaseコンソール上で
Instrumentationの場合はテストケース、ログ、操作動画、
Roboの場合はログ、スクリーンショット、画面遷移図、操作動画、
をそれぞれ確認することができます。

![スクリーンショット 2016-12-02 6.10.49.png](https://qiita-image-store.s3.amazonaws.com/0/84972/97e728f2-30e3-cd09-770d-deee26c3816a.png "スクリーンショット 2016-12-02 6.10.49.png")
![スクリーンショット 2016-12-02 6.10.37.png](https://qiita-image-store.s3.amazonaws.com/0/84972/ce5ed7e0-5677-c695-b1ae-3e7e9a71bdde.png "スクリーンショット 2016-12-02 6.10.37.png")




## まとめ
Instrumentation Testを使えば今までローカルでやっていたテストをクラウド上で、
Robo Testを使えばテストコードのないプロダクトもテストを行うことができます。

尚、CircleCIとの連携方法は[CircleCI公式](https://circleci.com/docs/firebase-test-lab/)に載っていますので、簡単に導入できます。

Firebase Test Labサービス開始直後はSparkプラン(FREE)では利用できませんでしたが、
嬉しいことに、つい先月辺りからSparkプランでも[利用できるようになりました](https://firebase.googleblog.com/2016/11/start-using-firebase-test-lab-for-android-at-no-charge.html)。
1日 VM10回、実機5回の計15回まで無料で利用できるので、これを機に試してみるのは如何でしょうか？

Robo Testは簡単に利用できるので、
現在テストしていないようなAndroidプロダクトにテストを組み込む一歩目としては丁度良いかと思います。

それでは良いテストライフを！