Mercari Engineering Blog

We're the software engineers behind Mercari. Check out our blog to see the tech that powers our marketplace.

Docker × Android エミュレータで、自動テスト(Appium)を並列化・爆速にする環境を作ったお話

f:id:tadashi-nemoto0713:20181129162340j:plain


これは Mercari Advent Calendar 2018 10日目の記事です。

こんにちは、メルカリの自動化&品質保証グループ(Automation & QA Group:通称AQA)で、自動化をぶりぶりしている tadashi0713 です。

私は普段、テスト自動化・CI / CD 改善・その他社内の生産性を上げるための自動化を行っています。

今回は、Android・Appium の自動テストを 20~30台のエミュレータで並列実行できる 環境を作成したので、その試行錯誤についてお話したいと思います。


f:id:tadashi-nemoto0713:20181127193934j:plain
Android エミュレータで並列実行させた Jenkins パイプライン

これまでの Android 自動テスト環境とその課題

AQA グループでは現在、Appium を使って Android の自動テストを実装・実行させています。

詳細に関しましてはこちらの記事をご覧ください。

tech.mercari.com

当時は Android リリースをする前に、リグレッションテストとして実行していました。

テスト実行環境としては、簡単に言うと下記のようになっていました。

Jenkins (master) -> 社内の mac -> 数台の Android 実機端末

テスト自動化をはじめた当時としては、必要十分だったかと思います。

現在では、自動テストの数・実装する人・実行する機会も大分増えました。

そうなると、様々な課題に遭遇します。

  • テスト実行時間の増加
  • 実機端末のメンテナンス
  • 実機端末の不良(ネットワークなど)によるテストの失敗
  • Appium・Ruby などの実行環境のメンテナンス


iOS の自動テストは、既にクラウドで安定的に実行されていたため、同じようにできないか考えました。

tech.mercari.com

最近だと Firebase Test Lab による Android 実機テストが話題になっています。

しかし、Firebase Test Lab は、現状 Appium に対応していないため、今回紹介する Docker-Android を試しました。

Docker-Android

今回のテスト実行環境作成で利用したのは Docker-Android と呼ばれる Docker イメージです。

github.com

今年ロンドンで開催された AppiumConf2018 で、この Docker-Android について紹介されていました。

www.youtube.com

この 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 · butomo1989/docker-android · GitHub


今回はこちらの記事を参考に、AWSのベアメタルインスタンス(i3.metal)を利用することにしました。

techlife.cookpad.com

i3.metal はかなり高性能のため、今回のような Android エミュレータを複数立ち上げても問題のないテスト環境を作ることができました。


f:id:tadashi-nemoto0713:20181127191224j:plain
Selenium Grid

Docker-Android による恩恵

これらによって、Android・Appium の自動テストをエミュレータで並列実行できる環境を作ることができました。

この並列実行によって、これまでよりもテスト実行時間を短くすることが期待できます。

実行時間が短くなることによって、テストの実行機会を現状より増やすこともできそうです。

また、クラウド化・コンテナ化・エミュレータ化によって、メンテナンスしないといけない部分を減らすことができると期待しています。

課題

以上のような恩恵もあるのですが、同時にこれから取り組まないといけない課題もあります。

実機とエミュレータの役割分担

今回のテスト実行環境では Android エミュレータを利用しています。

しかし、カメラなど複数の実機で実行すべきテストもあるため、全てのテストをエミュレータで担保するのは難しいと考えています。

今後はどれを実機で行うべきで、どれをエミュレータ担保でも良いのか役割分担をしていく必要があります。


f:id:tadashi-nemoto0713:20181129110342j:plain
検証環境への負荷

現状、この環境と検証環境は分離されています。

そのため、テストの並列化が進むとより検証環境への負荷が高くなってしまいます。

検証環境も同時にスケールしたり、モック化したりするなどの対応が必要になってくるかと思います。

テストの分散とテストレポート

現状だとレポートなどの関係上、JenkinsのPipelineファイルでそれぞれテストを割り振っています。

tech.mercari.com

しかし、モバイルUIテストのようなテスト実行時間が長くなりがちなものの場合、それぞれのエミュレータにどうテストを分散させるのかも課題になってきます。

今後は Knapsack などのツールを試しながら、テストを分散・最適化させていくための取り組みをしていきたいと思います。

Knapsack gem README

また、分散されたテストに合わせてテストレポートも変えていく必要があります。

SeleniumConf Chicagoで、分散化された Selenium のテストレポートに Allure を利用している事例が紹介されていたので、今後試していきたいと思います。

Allure | Test report and framework for writing self-documented tests


f:id:tadashi-nemoto0713:20181129162445j:plain:w700
SeleniumConf Chicago で紹介されていた、Allure によるテストレポート

おわりに

上記のようにまだまだ課題はありますし、UIテストでどこまで担保していくかは引き続き QA・エンジニア と考えていかなくてはいけません。

しかし、自動テストにおいて速さは正義だと考えていますし、実行時間の短縮によって実行機会が増えるのには未来があると考えています。

引き続きより良い自動テスト環境を追い求めていきたいと思います。


明日の執筆担当は @satomi です。引き続きお楽しみください!