この記事は、 Merpay Advent Calendar 2021 の10日目の記事です。
本記事は、1週間リリースを支えるAndroid自動テスト運用についてメルペイ Androidチームの@amane, @kenken, @anzai, @hiroPがお送りします。
自動化の背景
メルカリアプリでは、お客さまに素早く価値を届ける目的で、2週間に1度のアプリリリースサイクルを1週間に1度に短縮することを目指しました。(リリースサイクルのアップデートに関しては@stamakiさんのこちらの記事を参照してください。)
しかしこのサイクルを実現するには、2日間かかっていたリグレッションテストを1日に短縮する必要がありました。
そこで手動で実施しているテストの工数を短縮するために、自動化を始めました。
Androidのリグレッションテスト環境の構築
メルペイではFirebase Test Lab上の端末でリグレッションテストを夜間に一度、masterブランチに対して実行しています。また、ブランチ名にuitestの文字列を含むブランチに対してもテストを実行しています。
テストケースとテストの証跡はTestRailというツールで管理しています。TestRailのAPIを利用して、CircleCIとFirebase Test Labからテスト結果を登録しています。
テストフレームワークはEspressoを使っています。実装に際しては、こちらの資料を参考にさせていただきました。貴重な知見の共有ありがとうございます。
EspressoではじめるAndroid UIテスト / Android UI Testing Starting with Espresso
テストケースの選定
リグレッションテストを自動化していく際、いままで実施していたテストの質を犠牲にすることはできません。そのため、QAチームが設計したテストケースをそのまま自動化していきました。
ただし、以下のようなデバイスの機能を用いるケースについては現状の仕組みでは自動化ができないため手動で対応しています。
- カメラを起動する
- NFCを利用する
- プッシュ通知をタップする
- Google マップで位置情報を使う
- 画面の輝度を確認する
リグレッションテスト実装の目標と結果
QAチームが設計したリグレッションテストは現状238件あり、手動で実施した場合は総計で約24時間(1人あたり約12時間)かかっていました。
1日でリグレッションテストを終わらせるために、手動での実施件数120件以下、実施時間で総計16時間(1人あたり8時間)以下を目標に自動化を進めていきました。
238件中146件を自動化した結果、手動での実施件数と実施時間が下表のように削減できました。
表. 自動化前後のリグレッションテストのマニュアルでの実施件数と実施時間(*1)
(*1)自動化後の実施件数は、「リグレッションテストの総数(238)-自動化した件数(146)+ 自動テストで失敗した件数」になっています。
課題と対策
リグレッションテストの自動化を進めてきた中で、出てきた課題とその対策についていくつか紹介します。
課題1: 実行時間が長い
自動テストは、複数のOSバージョンで実施しています。146件の自動テストを対象のOSバージョン全てで実行すると総計で約9時間かかり、これをプルリクエスト毎に実行するとかなり高コストです。
そこで、現在は自動テストの実行を夜間ビルドとUIテスト修正のプルリクエストのみに制限しています。
また、夜間ビルドでは自動テストを全件実行していますが、FlankというFirebase Test Lab上でのテスト実行を並列化するライブラリを使って、OSバージョン毎に10並列でテストを実行しています。その結果、総計9時間かかるテストが30分程度で完了します。
UIテスト修正のプルリクエストに対する自動テスト実行では、時間を節約するため修正したテストだけに絞って実行する仕組みを作りました。プルリクエストに対するコメントで実行したいテストのパッケージ名を指定することで、自動テストの対象を制限できます。
図. コメントの例
図. GitHubのコメントでのテスト対象制限の処理フロー
処理の流れは上図のようになっています。
GitHubのAPIでプルリクエストのコメントを取得し、Flankのテスト設定用のyamlファイル生成時にテスト対象のパッケージ名を指定しています。
生成したyamlの一部抜粋
gcloud:
## 略
test-targets:
- size large
- package <package name> # ここにコメントから取得したパッケージ名が入ります
## 略
課題2: 増えていく自動テストの失敗
前述の通り、プルリクエストごとにリグレッションテストを実行しているわけではないため、 機能実装時に想定できなかった影響により、テストが壊れてしまうことがあります。このままだと手動でリカバリするテストが増え続けてしまうため、開発と並行して既存の自動テストのメンテナンスを進めています。
メンテナンスの方法ですが、自動テストはAPIの不調など様々な要因で失敗するため、テストの失敗原因を1つ1つ確認していると大きな労力がかかってしまいます。
この労力を減らすためメルペイAndroidチームでは、TestRailでテストケース毎のテスト結果を集計したレポートを作成し、このレポートを週次で確認することで、失敗率の高いテストを見つけ、都度修正しています。
図. TestRailのレポート
課題3: テスト用のお客さまデータを使い回すと失敗するケース
メルペイではテストに使うお客さまデータの状態によってテスト結果が変わってしまうことがあります。
例えばポイントのチャージのテストについては注意が必要です。
お客さまデータを使い回すと、以下のようなテストでは期待するテスト結果にならないことがあります。
1回目
- 1,000ポイントチャージする。
- 現在の保有ポイントが1,000ポイント加算されるため、表示は1,000ポイントとなる。
2回目
- 1,000ポイントチャージする。
- 期待するテスト結果は1000ポイントだが、すでに1,000ポイント保有しているため、表示が2,000ポイントとなってしまう。
この場合、チャージ前の保有ポイントを取得して差分をテスト対象にすれば成功しますが、CIで実行する場合は、並列でテストを実行しているため、タイミングによって表示ポイント数が期待値とズレてしまいます。
メルペイにはuser-tkoolというツールがあり、テスト環境のお客さまデータを作成するAPIを提供してくれています。こちらを利用してテストの実行毎に新規のお客さまデータを作成してテストを実行することで、このような問題に対処しています。
今後の課題
リグレッションテストの自動化はまだ始めたばかりで、さまざまな課題が残っています。中でもメンテナンスコストは気になっていて、もう少しテストの追加や既存テストの修正の手間を削減したいと思っています。
これからは、自動テスト用のテンプレートやスニペットなどを充実させたり、週次のレポートから修正が必要なテストを自動で抽出する仕組みを作っていくつもりです。
まとめ
この記事では、メルペイAndroidチームがリグレッションテストをどのように自動化し運用しているか、また現在の運用に至るまでに遭遇した課題とその対策について紹介しました。
リグレッションテストの自動化とその運用には大変な面もありますが、これらの取り組みを行うことで1週間リリースを維持し、これからも高品質なアプリを素早くお客さまに届けていきたいと思っています。
明日のMerpay Advent Calendar 2021 執筆担当は、iOSチーム Engineering Managerの @stamaki さんです。引き続きお楽しみください。