これは Mercari Advent Calendar 2018 10日目の記事です。
こんにちは、メルカリの自動化&品質保証グループ(Automation & QA Group:通称AQA) の 根本 征 です。
私は普段、テスト自動化・CI / CD 改善・その他社内の生産性を上げるための自動化を行っています。
今回は、Android・Appium の自動テストを 20~30台のエミュレータで並列実行できる 環境を作成したので、その試行錯誤についてお話したいと思います。
これまでの Android 自動テスト環境とその課題
AQA グループでは現在、Appium を使って Android の自動テストを実装・実行させています。
詳細に関しましてはこちらの記事をご覧ください。
当時は Android リリースをする前に、リグレッションテストとして実行していました。
テスト実行環境としては、簡単に言うと下記のようになっていました。
Jenkins (master) -> 社内の mac -> 数台の Android 実機端末
テスト自動化をはじめた当時としては、必要十分だったかと思います。
現在では、自動テストの数・実装する人・実行する機会も大分増えました。
そうなると、様々な課題に遭遇します。
- テスト実行時間の増加
- 実機端末のメンテナンス
- 実機端末の不良(ネットワークなど)によるテストの失敗
- Appium・Ruby などの実行環境のメンテナンス
iOS の自動テストは、既にクラウドで安定的に実行されていたため、同じようにできないか考えました。
最近だと Firebase Test Lab による Android 実機テストが話題になっています。
しかし、Firebase Test Lab は、現状 Appium に対応していないため、今回紹介する Docker-Android を試しました。
Docker-Android
今回のテスト実行環境作成で利用したのは Docker-Android と呼ばれる Docker イメージです。
今年ロンドンで開催された AppiumConf2018 で、この Docker-Android について紹介されていました。
この Docker イメージでは以下のような特徴があります。
- ARM エミュレータより高速に動く x86 エミュレータを起動できる
- 環境変数
APPIUM=true
でコンテナ内で Appium を起動できる - Selenium Grid に簡単に接続ができる
- noVNC によってコンテナ内部でエミュレータの様子を確認できる
- ビデオレコーディングができる
以下のような docker-compose.yml
を書き、$ docker-compose up -d
することで
Selenium Grid Hub → Node (Android エミュレータ + Appium)
を簡単に立ち上げることができます。
# docker-compose.yml version: "2.2" services: selenium_hub: image: selenium/hub ports: - 4444:4444 nexus_5_8.0: image: butomo1989/docker-android-x86-8.0 privileged: true depends_on: - selenium_hub environment: - DEVICE=Nexus 5 - CONNECT_TO_GRID=true - APPIUM=true - SELENIUM_HOST=selenium_hub
また、同じ Node であればオプションで --scale nexus_5_8.0=XX
することで、その数を簡単に増やすことができます。
クラウドでどう実行させたか
前述の通り、今回は安定性やメンテナンスのことを考え、クラウド上で実行したいという思いがありました。
Docker イメージとして提供されていれば、Docker × Selenium Grid のように簡単にクラウドで展開することができそうです。
しかし、この Docker-Android をクラウドで利用するには制限があります。
Docker-Android では x86 エミュレータを利用している都合上、ハードウェア仮想化機能が必要になります。
一般的なクラウドインスタンスは、それ自体がハードウェア仮想化の中で動作しているためこの機能を利用することができません。
そのため、以下のいずれか環境下で Docker-Android を立ち上げる必要があります。
仮想マシンの入れ子(Nested Virtualization) を有効にする
仮想マシンの上でさらにハードウェア仮想化機能を使うことができます。
現在 Google Cloud と Microsoft Azure でこの機能を利用することができます。
Google Compute Engine、仮想マシンの入れ子(Nested Virtualization)を可能に。KVM対応 - Publickey
クラウドの仮想マシンの上に仮想マシンを作れる、Nested Virtualizationに対応した新型VMをMicrosoft Azureがリリース - Publickey
ベアメタルインスタンスを利用する
物理サーバーをそのまま利用することができます。
AWS では現在、ベアメタルインスタンス(i3.metal)を利用することができます。
AWS、ベアメタルサーバ「i3.metal」を正式サービスとして提供開始 - Publickey
現在では Docker-Android を各種クラウドサービスで使うためのドキュメントやサンプルコードがあります。
docker-android/README_CLOUD.md at master · budtmo/docker-android · GitHub
今回はこちらの記事を参考に、AWSのベアメタルインスタンス(i3.metal)を利用することにしました。
i3.metal はかなり高性能のため、今回のような Android エミュレータを複数立ち上げても問題のないテスト環境を作ることができました。
Docker-Android による恩恵
これらによって、Android・Appium の自動テストをエミュレータで並列実行できる環境を作ることができました。
この並列実行によって、これまでよりもテスト実行時間を短くすることが期待できます。
実行時間が短くなることによって、テストの実行機会を現状より増やすこともできそうです。
また、クラウド化・コンテナ化・エミュレータ化によって、メンテナンスしないといけない部分を減らすことができると期待しています。
課題
以上のような恩恵もあるのですが、同時にこれから取り組まないといけない課題もあります。
実機とエミュレータの役割分担
今回のテスト実行環境では Android エミュレータを利用しています。
しかし、カメラなど複数の実機で実行すべきテストもあるため、全てのテストをエミュレータで担保するのは難しいと考えています。
今後はどれを実機で行うべきで、どれをエミュレータ担保でも良いのか役割分担をしていく必要があります。
検証環境への負荷
現状、この環境と検証環境は分離されています。
そのため、テストの並列化が進むとより検証環境への負荷が高くなってしまいます。
検証環境も同時にスケールしたり、モック化したりするなどの対応が必要になってくるかと思います。
テストの分散とテストレポート
現状だとレポートなどの関係上、JenkinsのPipelineファイルでそれぞれテストを割り振っています。
しかし、モバイルUIテストのようなテスト実行時間が長くなりがちなものの場合、それぞれのエミュレータにどうテストを分散させるのかも課題になってきます。
今後は Knapsack などのツールを試しながら、テストを分散・最適化させていくための取り組みをしていきたいと思います。
また、分散されたテストに合わせてテストレポートも変えていく必要があります。
SeleniumConf Chicagoで、分散化された Selenium のテストレポートに Allure を利用している事例が紹介されていたので、今後試していきたいと思います。
Allure | Test report and framework for writing self-documented tests
おわりに
上記のようにまだまだ課題はありますし、UIテストでどこまで担保していくかは引き続き QA・エンジニア と考えていかなくてはいけません。
しかし、自動テストにおいて速さは正義だと考えていますし、実行時間の短縮によって実行機会が増えるのには未来があると考えています。
引き続きより良い自動テスト環境を追い求めていきたいと思います。
明日の執筆担当は @satomi です。引き続きお楽しみください!