AndroidのテストにFirebase Test Labを使おう

# そもそもの考え方
Androidのテストは困難である。
大きい理由はその端末数で、日本向けに発売されたXperiaシリーズだけでも、2014 ~ 2016 までで35種類（１端末３キャリアでも３つとカウント）もある。

すべての端末 ✕ All Android OSでテストするのが理想だが、時間もお金も有限なわけで...
個人的にテストする場合は、次の内容で実施がよい。

端末（日本での利用者数が多いシリーズ）

* テストしたいAPPの利用者が一番多いシリーズ
* Nexusシリーズ or Galaxyシリーズ or Xperiaシリーズ

Android OS

* テストしたいAPPのminSdkVersion ~ maxSdkVersion
* 4.3.X ~ 7.1.X（最新OS）

それ以上のテストは必要に応じて実施すればよい。かけるコスト（時間・お金）と天秤にかけなさい。

# なぜFirebase Test Lab？
今の世の中、クラウド型のTest Labはたくさんある。
[AWS Device Farm - Amazon Web Services](https://aws.amazon.com/jp/device-farm/)や、[クラウド実機テストサービスまとめ via Nifty](http://blog.mb.cloud.nifty.com/?p=1225)を参考にすれば、どれくらいのサービスがあるか分かる。

どのクラウドサービスを選択するかは自由だけど、私がFirebase Test Labを選ぶ理由は次の通り。

* 上記の端末✕OSでテスト可能
* Android Studio、Firebase console、gcloud コマンドラインと統合されている
* CI前提
* テストライブラリ（Espresso, Robotium, UI Automator）が利用可能

ぶっちゃけ、どのクラウドサービスも上記はある程度満たせる。
今後のAndroidのプラットフォームに対するGoogleの方針を考えると Firebase を利用したほうが良い、という単純な答え。

今回はCIを考慮して、CLIベースでFirebase Test Labを利用するためのまとめです。
基本は[Firebase Test Lab - Google](https://firebase.google.com/docs/test-lab/)に書いてる。

# Firebase Test Labでテストできる端末とAndroid OS

## テスト出来るAndroid端末

```Bash
$ gcloud beta test android devices list

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

┌─────────────┬──────────┬────────────────────┬──────────┬─────────────┬────────────────┬─────────┐
│  DEVICE_ID  │   MAKE   │     MODEL_NAME     │   FORM   │  RESOLUTION │ OS_VERSION_IDS │   TAGS  │
├─────────────┼──────────┼────────────────────┼──────────┼─────────────┼────────────────┼─────────┤
│ D6503       │ Sony     │ Xperia Z2          │ PHYSICAL │ 1920 x 1080 │ 21             │         │
│ D6603       │ Sony     │ Xperia Z3          │ PHYSICAL │ 1920 x 1080 │ 21             │         │
│ E5803       │ Sony     │ Xperia Z5 Compact  │ PHYSICAL │ 1280 x 720  │ 22             │         │
│ F5121       │ Sony     │ Sony Xperia X      │ PHYSICAL │ 1920 x 1080 │ 23             │         │
│ Nexus10     │ Samsung  │ Nexus 10           │ VIRTUAL  │ 2560 x 1600 │ 19,21,22       │ beta    │
│ Nexus4      │ LG       │ Nexus 4            │ VIRTUAL  │ 1280 x 768  │ 19,21,22       │ beta    │
│ Nexus5      │ LG       │ Nexus 5            │ VIRTUAL  │ 1920 x 1080 │ 19,21,22,23    │ beta    │
│ Nexus5X     │ LG       │ Nexus 5X           │ VIRTUAL  │ 1920 x 1080 │ 23,24,25       │ beta    │
│ Nexus6      │ Motorola │ Nexus 6            │ VIRTUAL  │ 2560 x 1440 │ 21,22,23,24,25 │ beta    │
│ Nexus6P     │ Huawei   │ Nexus 6P           │ VIRTUAL  │ 2560 x 1440 │ 23,24,25       │ beta    │
│ Nexus7      │ ASUS     │ Nexus 7 (2012)     │ VIRTUAL  │ 1280 x 800  │ 19,21,22       │ beta    │
│ Nexus9      │ HTC      │ Nexus 9            │ VIRTUAL  │ 2048 x 1536 │ 21,22,23,24,25 │ beta    │
│ athene      │ Motorola │ Moto G4 Plus       │ PHYSICAL │ 1920 x 1080 │ 23             │         │
│ athene_f    │ Motorola │ Moto G4            │ PHYSICAL │ 1920 x 1080 │ 23             │         │
│ condor_umts │ Motorola │ Moto E             │ PHYSICAL │  960 x 540  │ 19             │         │
│ falcon_umts │ Motorola │ Moto G (1st Gen)   │ PHYSICAL │ 1280 x 720  │ 19             │         │
│ flo         │ ASUS     │ Nexus 7 (2013)     │ PHYSICAL │ 1920 x 1200 │ 19,21          │         │
│ flounder    │ HTC      │ Nexus 9            │ PHYSICAL │ 2048 x 1536 │ 21             │         │
│ g3          │ LG       │ LG G3              │ PHYSICAL │ 2560 x 1440 │ 19             │         │
│ hammerhead  │ LG       │ Nexus 5            │ PHYSICAL │ 1920 x 1080 │ 19,21,22,23    │ default │
│ herolte     │ Samsung  │ Galaxy S7          │ PHYSICAL │ 1440 x 2560 │ 23             │         │
│ hlte        │ Samsung  │ Galaxy Note 3 Duos │ PHYSICAL │ 1920 x 1080 │ 19             │         │
│ htc_m8      │ HTC      │ HTC One (M8)       │ PHYSICAL │ 1920 x 1080 │ 19             │         │
│ j5lte       │ Samsung  │ Galaxy J5          │ PHYSICAL │ 1280 x 720  │ 23             │         │
│ ja3g        │ Samsung  │ Galaxy S4 (3G)     │ PHYSICAL │ 1920 x 1080 │                │         │
│ lt02wifi    │ Samsung  │ Galaxy Tab 3       │ PHYSICAL │  600 x 1024 │ 19             │         │
│ m0          │ Samsung  │ Samsung Galaxy S3  │ PHYSICAL │ 1280 x 720  │ 18             │         │
│ mako        │ LG       │ Nexus 4            │ PHYSICAL │ 1280 x 768  │ 19,22          │         │
│ osprey_umts │ Motorola │ Moto G (3rd Gen)   │ PHYSICAL │ 1280 x 720  │ 22             │         │
│ p1          │ LG       │ LG G4              │ PHYSICAL │ 1440 x 2560 │ 22             │         │
│ serranolte  │ Samsung  │ Galaxy S4 mini     │ PHYSICAL │  960 x 540  │ 19             │         │
│ shamu       │ Motorola │ Nexus 6            │ PHYSICAL │ 2560 x 1440 │ 21,22,23       │         │
│ t03g        │ Samsung  │ Galaxy Note 2      │ PHYSICAL │ 1280 x 720  │ 19             │         │
│ titan_umts  │ Motorola │ Moto G (2nd Gen)   │ PHYSICAL │ 1280 x 720  │ 19             │         │
│ trelte      │ Samsung  │ Galaxy Note 4      │ PHYSICAL │ 1920 x 1080 │ 22             │         │
│ victara     │ Motorola │ Moto X             │ PHYSICAL │ 1920 x 1080 │ 19             │         │
│ zeroflte    │ Samsung  │ Galaxy S6          │ PHYSICAL │ 2560 x 1440 │ 22             │         │
│ zerolte     │ Samsung  │ Galaxy S6 Edge     │ PHYSICAL │ 2560 x 1440 │ 22             │         │
└─────────────┴──────────┴────────────────────┴──────────┴─────────────┴────────────────┴─────────┘
```

## テストに使用可能なAndroid OS

```Bash
$ gcloud beta test android versions list

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

┌───────────────┬─────────┬─────────────┬───────────┬──────────────┬─────────┐
│ OS_VERSION_ID │ VERSION │  CODE_NAME  │ API_LEVEL │ RELEASE_DATE │   TAGS  │
├───────────────┼─────────┼─────────────┼───────────┼──────────────┼─────────┤
│       18      │  4.3.x  │ Jelly Bean  │     18    │  2013-10-03  │         │
│       19      │  4.4.x  │ KitKat      │     19    │  2014-06-02  │         │
│       21      │  5.0.x  │ Lollipop    │     21    │  2014-12-19  │ default │
│       22      │  5.1.x  │ Lollipop    │     22    │  2015-04-21  │         │
│       23      │  6.0.x  │ Marshmallow │     23    │  2015-10-05  │         │
│       24      │  7.0.x  │ Nougat      │     24    │  2016-08-22  │         │
│       25      │  7.1.x  │ Nougat      │     25    │  2016-10-19  │         │
└───────────────┴─────────┴─────────────┴───────────┴──────────────┴─────────┘
```

## テストに使用可能なロケール

```Bash
$ gcloud beta test android locales list

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

┌────────┬─────────────────────────────┬───────────────────────────────────┬─────────┐
│ LOCALE │             NAME            │               REGION              │   TAGS  │
├────────┼─────────────────────────────┼───────────────────────────────────┼─────────┤
│ af     │ Afrikaans                   │                                   │         │
│ :      │ :                           │                                   │         │
│ ja     │ Japanese                    │                                   │         │
│ ja_JP  │ Japanese                    │ Japan                             │         │
│ :      │ :                           │                                   │         │
└────────┴─────────────────────────────┴───────────────────────────────────┴─────────┘
```

# 準備

利用しているもの

* Android Studio 2.2.3
* OS X El Capitan 10.11.5


## OS XにGoogle Cloud SDK のインストールおよび初期化をおこなう
https://cloud.google.com/sdk/docs/quickstart-mac-os-x

システムに Python 2.7 がインストールされていることを確認

```Bash
$ python -V
Python 2.7.10
```

アーカイブファイルをダウンロードし、展開後のカレントディレクトリでインストール

```Bash
$ ./google-cloud-sdk/install.sh
Welcome to the Google Cloud SDK!
 :
Do you want to help improve the Google Cloud SDK (Y/n)?  Y
 :
Your current Cloud SDK version is: 121.0.0
The latest available version is: 138.0.0
 :
Modify profile to update your $PATH and enable shell command
completion? (Y/n)?  Y
 :
For more information on how to get started, please visit:
  https://cloud.google.com/sdk/#Getting_Started


$ gcloud --version
Google Cloud SDK 121.0.0
bq 2.0.24
bq-nix 2.0.24
core 2016.08.05
core-nix 2016.08.05
gcloud
gsutil 4.20
gsutil-nix 4.20
```

SDKの初期化

```Bash
$ gcloud init
Welcome! This command will take you through the configuration of gcloud.

Your current configuration has been set to: [default]

Network diagnostic detects and fixes local network connection issues.
Checking network connection...done.
Reachability Check passed.
Network diagnostic (1/1 check) passed.

# Googleアカウントを利用してログインを受け入れるかどうか
You must log in to continue. Would you like to log in (Y/n)?  Y

Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?************
```

GoogleアカウントでFirebaseを認証
![gcloud_auth_login.png](https://qiita-image-store.s3.amazonaws.com/0/33505/85269ffc-00b1-7662-8f80-f7ce254ffd36.png "gcloud_auth_login.png")



```Bash
You are logged in as: [**********@gmail.com].

Pick cloud project to use:
 [1] [******]
 [2] [******]
 [3] [sample-firebase-test-lab]

# Cloud Platform プロジェクトを選択
Please enter your numeric choice:  3

Your current project has been set to: [sample-firebase-test-lab].
 :
Your Google Cloud SDK is configured and ready to use!
 :


$ gcloud config list
Your active configuration is: [default]

[core]
account = **********@gmail.com
disable_usage_reporting = False
project = sample-firebase-test-lab
```

認証情報を確認する

```Bash
$ gcloud auth login
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?************

Saved Application Default Credentials.
 :
You are now logged in as [**********@gmail.com].
Your current project is [sample-firebase-test-lab].  You can change this setting by running:
  $ gcloud config set project PROJECT_ID
```

# テスト実施

テストに利用したAPK
[notepad.zip](https://firebase.google.com/docs/test-lab/command-line) file by Firebase.

```Bash
$ pwd
/Users/samukaak/Downloads/NotePad
$ ./gradlew assembleAndroidTest
$ ls app/build/outputs/apk/*.apk
app/build/outputs/apk/app-debug-androidTest.apk
app/build/outputs/apk/app-debug.apk
```

## Roboテストの実施

```Bash
$ gcloud beta test android run \
> --type robo \
> --app ./Downloads/NotePad/app/build/outputs/apk/app-debug.apk \
> --device-ids Nexus6,Nexus7 \
> --os-version-ids 19,21 \
> --locales ja \
> --orientations portrait,landscape \
> --timeout 90s

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

Uploading [./Downloads/NotePad/app/build/outputs/apk/app-debug.apk] to the Cloud Test Lab...
 :
More details are available at [https://console.developers.google.com/project/sample-firebase-test-lab/testlab/mobile/histories/bh.66d832153acdcd49/executions/8946206190459142105].
┌─────────┬────────────────────────┬────────────────────────────────────┐
│ OUTCOME │    TEST_AXIS_VALUE     │            TEST_DETAILS            │
├─────────┼────────────────────────┼────────────────────────────────────┤
│ Passed  │ Nexus6-21-ja-landscape │ --                                 │
│ Passed  │ Nexus6-21-ja-portrait  │ --                                 │
│ Passed  │ Nexus7-19-ja-landscape │ --                                 │
│ Passed  │ Nexus7-19-ja-portrait  │ --                                 │
│ Passed  │ Nexus7-21-ja-landscape │ --                                 │
│ Passed  │ Nexus7-21-ja-portrait  │ --                                 │
│ Skipped │ Nexus6-19-ja-landscape │ Incompatible device/OS combination │
│ Skipped │ Nexus6-19-ja-portrait  │ Incompatible device/OS combination │
└─────────┴────────────────────────┴────────────────────────────────────┘
```

## Instrumentationテストの実施
```Bash
$ gcloud beta test android run \
> --type instrumentation \
> --app ./Downloads/NotePad/app/build/outputs/apk/app-debug.apk \
> --test ./Downloads/NotePad/app/build/outputs/apk/app-debug-androidTest.apk \
> --device-ids Nexus6,Nexus7 \
> --os-version-ids 19,21 \
> --locales ja \
> --orientations portrait,landscape \

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

Uploading [./Downloads/NotePad/app/build/outputs/apk/app-debug.apk] to the Cloud Test Lab...
Uploading [./Downloads/NotePad/app/build/outputs/apk/app-debug-androidTest.apk] to the Cloud Test Lab...
 :
Test results will be streamed to [https://console.developers.google.com/project/sample-firebase-test-lab/testlab/mobile/histories/bh.66d832153acdcd49/executions/5864603158034325334].
17:30:03 Test matrix status: Finished:6 Unsupported:2
Instrumentation testing complete.

More details are available at [https://console.developers.google.com/project/sample-firebase-test-lab/testlab/mobile/histories/bh.66d832153acdcd49/executions/5864603158034325334].
┌─────────┬────────────────────────┬────────────────────────────────────┐
│ OUTCOME │    TEST_AXIS_VALUE     │            TEST_DETAILS            │
├─────────┼────────────────────────┼────────────────────────────────────┤
│ Passed  │ Nexus6-21-ja-landscape │ 1 test cases passed                │
│ Passed  │ Nexus6-21-ja-portrait  │ 1 test cases passed                │
│ Passed  │ Nexus7-19-ja-landscape │ 1 test cases passed                │
│ Passed  │ Nexus7-19-ja-portrait  │ 1 test cases passed                │
│ Passed  │ Nexus7-21-ja-landscape │ 1 test cases passed                │
│ Passed  │ Nexus7-21-ja-portrait  │ 1 test cases passed                │
│ Skipped │ Nexus6-19-ja-landscape │ Incompatible device/OS combination │
│ Skipped │ Nexus6-19-ja-portrait  │ Incompatible device/OS combination │
└─────────┴────────────────────────┴────────────────────────────────────┘
```

# テスト結果をFirebaseで見る
実行結果は [Test Lab | Firebase](https://console.firebase.google.com/project/) または [Cloud Test Lab | Google Cloud Platform](https://console.cloud.google.com/testlab/mobile) で確認することができます。
※ Google Cloud Platformは、Firebaseの無料プラン SPARK では利用できません。

Firebase Test Lab
![fb_testlab.png](https://qiita-image-store.s3.amazonaws.com/0/33505/7e54b873-8eb5-9eba-11dd-94e0273e6e8e.png "fb_testlab.png")
テストタイプに合わせて結果を見ることができる

マトリックスを選択
![fb_testlab_robo.png](https://qiita-image-store.s3.amazonaws.com/0/33505/45d7f1b1-0148-684d-3a18-a8844c11d1bd.png "fb_testlab_robo.png")
テスト実施した端末や画面の向きなどのテスト結果がある。
ここは、インストゥルメンテーションやRoboテストで差はない。

## インストゥルメンテーションのテスト結果
![ins_test.png](https://qiita-image-store.s3.amazonaws.com/0/33505/833ba74b-ba7b-53f2-3e24-dd4770564616.png "ins_test.png")
テストケースや実施時のログ、スクリーンショット、動画、を見ることができます。

## Roboのテスト結果
![robo_test.png](https://qiita-image-store.s3.amazonaws.com/0/33505/de01c33a-c014-00de-c7b3-56c5fcc89b0d.png "robo_test.png")
ログ、スクリーンショット、アクティビティマップ、動画、を見ることができます。

# まとめ
比較的学習コストなくCIへの導入ができると思います。
ローカルサーバでJenkinsを立てれば、費用なしでも可能です。

個人的にはCIもFirebaseに統合してくれや...