こんにちは、naberyo (@error96num) です。今年の4月に STORES へ入社し、 STORES ブランドアプリ のAndroidエンジニアをしています。
本記事では、STORES ブランドアプリ にE2Eテストを導入した話について書きます。
なお、 STORES Advent Calendar 2024 の9日目の記事になります。
なぜE2Eテストを導入するのか
STORES ブランドアプリ は、お商売をしているオーナーさんごとにカスタマイズされたオリジナルアプリを提供するサービスです。クーポン配布や店舗からの案内などを通じて、オーナーさんとお客さまの関係を深めることを目指しています。
現在、2週間ごとにアプリの定期リリースをしており、QAエンジニアとモバイルエンジニアが協力してマニュアルテストを実施しています。このテストには、新機能が期待どおりに動作するかを確認する機能検証と、既存機能への影響を確認するリグレッションテストが含まれます。しかし、リグレッションテストは繰り返し作業が多く、工数が増大するため、その一部を自動化することで効率化を図る必要性がありました。
加えて、 STORES ブランドアプリ では、オーナーさんが管理画面を通じてUIのレイアウトや利用可能な機能のオンオフを自由に設定できる仕組みを提供しています。このようなカスタマイズ機能により、サービスの柔軟性が高まる一方で、各オーナーさんの設定に応じたテストケースが膨大化しやすいという課題も抱えています。この特性を踏まえると、テストの一部を自動化することは、運用負担を軽減しつつ、品質の維持と向上を実現するために必要であると判断し、E2Eテストを導入することに決めました。
E2Eテストで確認したいこと
E2Eテスト(End-to-Endテスト)は、アプリの主要なユーザーフローが期待どおりに動作するかをシステム全体を通して検証する手法です。STORES ブランドアプリ では、以下のようなポイントを重点的に確認することを見据えて、E2Eテストを導入しました。
- 主要なユーザーフローの動作確認
- 会員登録、ログイン、ログアウトといった基本操作。
- 一覧や詳細データの表示機能(例: クーポン・会員証バーコード・お知らせの表示、QRコードの読み取りなど)。
- データの整合性
- APIやバックエンドと正しく通信が行われているか。
- 正しいデータが正しい画面に表示され、サーバーとの同期が期待どおりに機能しているか。
- デバイス間の互換性
- iOSやAndroidの異なるOSでの動作確認。
- 多様なデバイスサイズやスペックにおける動作の一貫性。
E2Eテストの導入でやったこと
初期スコープを決める
E2Eテストで検証したいポイントのうち、中でも優先的に対応する機能を、初期スコープとして定めました。次のような観点で初期スコープの候補となる機能を洗い出しました。
- アプリの利用者にとって最も重要な主機能
例: 店舗で使える会員証バーコードの表示 - 主機能を利用するための前提機能
例: 認証(会員登録・ログイン・退会) - 過去に不具合やインシデントが発生し、今後もテストで担保すべき機能
認証機能は、アプリ全体の入口にあたる重要な機能です。認証が失敗すると、その他の多くの機能テストが進められないため、最優先で自動化を進める必要があります。また、過去の不具合の対応経験から、会員登録やログインはユーザー体験を大きく左右する重要なポイントであることが明らかになっています。
これらの理由から、認証機能を初期スコープの自動化対象とすることで、重要な機能を確実にカバーすると同時に、今後のテストケース拡充への基盤を整えることを目指しました。
導入のマイルストーンを決める
E2Eテスト導入をスムーズに進めるために、段階的な目標を設定しました。理想的には、すべての定期リリース前にE2EテストをCI上で自動実行し、品質を担保できる状態を目指します。そのために以下のマイルストーンを設けました。
- 開発者のローカル環境でE2Eテストを実行できるようにする
テストに必要な環境設定や依存関係を整備し、かんたんなテストを実行できるようにする。 - 初期スコープのテストケースを実装する
先に選定した会員登録・ログイン・退会のテストケースを作成し、テストの動作確認を行う。 - CI環境にE2Eテストを組み込む
BitriseやGitHub Actionsを利用して、定期的な自動実行を可能にする。 - テストケースを拡充する
優先順位に基づき、ユーザー利用頻度の高い機能や過去に不具合が多発した機能を中心に、段階的にテストを追加していく。
これにより、短期的な目標と長期的な運用体制の双方を見据えた導入をする準備が整いました。
テストツールを決める
E2Eテストの実現手段は多岐に渡ります。例えば、iOSやAndroidが提供する公式のUIテストフレームワークのほか、よりシンプルにテストを書けるOSSツールや、ノーコード・ローコードで運用可能なSaaS型のテスト自動化ツールなどが存在します。この中から最も適したツールを選定するのは、導入プロセスの中でも特に重要なステップでした。
テストツールの選択肢
ツールの候補としては、次の表に示すものが上がりました。
カテゴリー | ツール名 | メリット | デメリット | 採用可否 |
---|---|---|---|---|
公式 |
|
公式サポートにより、ツール自体の継続性が期待できる。 プロダクションコードへのアクセスが容易で、柔軟性が高い。 |
他と比べて初期の学習・実装コストが高い。 | ✅ 採用 |
OSS |
|
シンプルな記述で初期の学習・実装コストが低い。 | 他と比べて柔軟性が限定的。 | ❌ 不採用 |
SaaS |
|
GUIでテストケースを作成可能で初期の学習・実装コストが低い。 実行環境を含むSaaS型で導入が容易。 |
他と比べて運用にかかる費用が高い。 | ❌ 不採用 |
最終的には iOSアプリではXCTestを、AndroidアプリではCompose UI TestとEspressoを使ってE2Eテストを実装していくことにしました。以下ではその結論に至った経緯について説明します。
まず、SaaS型のツールについては、運用にかかる費用の面で私たちの予算に見合わなかったこと、他のツールでも運用体制を作れることから、検討から外れることになりました。残る公式フレームワークとOSSツールについては、どちらも試す価値があると判断し、短期間でプロトタイプを作成しました。
プロトタイプ
初期スコープで選定した機能の中でも実装がかんたんなログインテストを対象として、実際にテストを書きました。
この際、特に自分たちの運用イメージに合ったツールの有力な候補として (1)XCTest (iOS)、(2)Compose UI Test + Espresso (Android)、(3)Maestro の3パターンを試しました。
developer.apple.com developer.android.com developer.android.com maestro.mobile.dev
やったこと
- ログインのテストケースを試作
ログイン機能のテストを、それぞれのツールで実装し、記述量や動作を比較しました。 - 試験的な検証の実施
チーム内で2週間という期限を設け、それぞれのツールで試したい内容を自由に検証しました。これにより、学習・実装コストや柔軟性、使い勝手の違いを体感しました。
得られた知見
実装コストの違い
Maestroは、コード量が少なくシンプルな構文でテストケースを作成できます。そのため、実装速度が非常に速いことが確認できました。以下は、ユーザーによるログイン操作を模倣するコードの比較です。 (実装の詳細については後の章で説明するため、ここでは触れません。) 左がAndroidの公式フレームワークであるCompose UI TestとEspressoを使って実装した場合、右がMaestroを使った場合です。Maestroの方がシンプルな記述であることは一目瞭然です。 また、MaestroのようなOSSツールを採用した場合には、エンジニア以外であってもテストケースの追加や修正を行える可能性があることがわかりました。一方で、公式フレームワークを使ったテスト実装ではアプリ開発の専門的な知識が必要とされます。そのため運用としては、テストケースの作成依頼を受けて、エンジニアがテストコードの実装を担うと想定されます。柔軟性の違い
XCTestやCompose UI Test・Espressoなどの公式フレームワークは、プロダクションコードへのアクセスが容易で、テストの柔軟性が高いという特徴があります。この利点は、特に STORES ブランドアプリ のように、UI情報の一部をサーバーで管理しているアプリで顕著に現れることがわかりました。STORES ブランドアプリ では、オーナーさんが自由にアプリの構成を変更できる仕組みを提供しています。具体的には、管理画面でメニューの順番やレイアウト情報を編集すると、その設定に応じて下図のように (1)文言、(2)導線 をはじめとしたアプリ内のさまざまなUIが変化します。 このようなアプリの特性を踏まえると、特定の機能をテストするコードにおいても、UI操作の導線や参照する文言を固定値ではなく動的に設定する必要があります。アプリのプロダクションコードやAPIレスポンスに含まれるUI情報に直接アクセス可能な公式フレームワークを採用することで、 STORES ブランドアプリ のテストに要求されるであろう、高い柔軟性の実現が期待できました。
選定の結論
最終的には、公式フレームワーク(XCTest、Compose UI Test + Espresso)が最適であると判断しました。以下の点が決定の要因となりました。
- 柔軟性:
APIレスポンスやサーバー管理データを利用し、テストの内容を動的に調整する必要がある STORES ブランドアプリ の特性に対応可能。
一方で、OSSやSaaSツールは以下の課題がありました。
- OSSツールの課題:
MaestroやAppiumはシンプルな記述が特徴だが、サーバードリブンUIや動的なテストデータ利用には対応しきれない部分がある。 - SaaSツールの課題:
MagicPodやAutifyはGUIでの操作性に優れるものの、コスト面で導入が難しいと判断。
最終的に、公式フレームワークを採用することで、高度なカスタマイズや運用負担の軽減を実現し、長期的な品質向上に寄与するという判断に至りました。
テストを実装する
設計・実装方針
ツール選定の結果、シンプルな記述よりも高度な柔軟性を重視することになった一方で、極力シンプルで保守性の高いテストコードを目指すモチベーションも同時に生まれました。これを実現するため、以下の設計パターンを採用しました。
POM (Page Object Model)
テスト対象の画面ごとにオブジェクトを作成し、UI操作や検証ロジックをその中に集約することで、テストコードの再利用性を高めました。Robot パターン
各テストケースが何を意図しているかを明確化し、テストコードの可読性を向上させました。
実装例
次の記事で、POMやRobot パターンを活用した具体的なテスト実装例を紹介しています:
※ iOSの記事は、12/17(火)に公開予定です。
おわりに
STORES ブランドアプリ にE2Eテストを導入する過程で、マイルストーンの設定やプロトタイプ作成を経て、公式フレームワークを採用するという結論に至りました。この選択により、APIレスポンスを利用した柔軟なテスト設計が可能となり、STORES ブランドアプリ の特性に合った運用の土台を構築することができました。
その第一歩として、認証機能のテストを実装しました。これを起点に、以下の取り組みを通じてさらに効果的な運用を目指していきます。
- CIへの組み込み
現在はローカル環境でのテスト実行が中心ですが、BitriseやGitHub Actionsを活用し、E2Eテストを定期リリース前に自動実行できるようにします。例えば、夜間ビルドを設定し、翌朝にはテスト結果が確認できる体制を目指します。 - テストケースの拡充
認証機能の他にも、会員証バーコードやクーポンの表示など、ユーザー利用頻度が高い機能を優先してカバーしていきます。 - チーム全体での運用改善
E2Eテスト結果を可視化したり、不具合を検出した後のプロセスを自動化する取り組みについても、QAチームと連携しながら進めていきます。
このように、E2Eテストは単なるテスト自動化ではなく、プロダクト品質を高めるための大切な取り組みです。これからも、新しい技術の導入やテスト運用の改善を模索し続けていきます。
この記事が、E2Eテスト導入を検討しているみなさんにとって少しでも参考になり、プロジェクトに役立つヒントやアイデアとなれば嬉しいです!