こんにちは、新規事業のプロダクト開発を担当している杉山です。
弊社では、これまでWebなどのE2EテストにGaugeを使用してきましたが、今回の新規事業のモバイルアプリの開発では、Maestroを採用しました。
本記事は、モバイルアプリのE2Eテスト導入を検討しており、理想と現実のバランスに悩むエンジニアの方を中心にお役に立てればと思い書いた記事です。Maestroを選定した理由、現在の構成、導入前の懸念点と実際の体験について詳しく紹介します。
Maestroの選定理由
弊社ではGaugeを広く使っていたということもあり、選択肢としてはAppiumとGaugeの組み合わせも検討しましたが、シンプルさとスピードを優先し、Maestroを採用しました。こちらの記事にもあるように、学習コストが低く、セットアップが簡単であることがとても魅力的でした。
EASとの親和性
テスト・ビルド・ストア配信をEASで行っており、EASがMaestroを公式でサポートしています。公式ドキュメントに詳しい手順が記載されており、EASとの親和性が高いことも大きな理由です。
クロスプラットフォーム対応
今回のリリースではiOSのみですが、Androidのリリースは今後のロードマップにあります。Maestroはクロスプラットフォームでテストを記述でき、iOSとAndroidの差分はconditionsを使って容易に吸収できます。
# プラットフォームごとの差分を吸収 - tapOn: text: "ボタン" - runFlow: when: platform: iOS commands: - tapOn: "iOS固有の操作" - runFlow: when: platform: Android commands: - tapOn: "Android固有の操作"
1つのテストコードでiOS/Android両方をカバーできるため、Android対応時にテストコードを一から書き直す必要がなく、保守コストも抑えられると判断しました。
安定している
試しにEAS上でMaestroを動かしてみたところ、公式通りにやることで非常に簡単に動作しました。 また現在までの運用でも安定して動作しており、信頼性が高いと感じています。 以前Appiumを導入しようと検証していた際には、不安定な動作に悩まされることが多々ありましたが、Maestroではそのような問題はほとんど発生していません。
シンプルさ
Maestroは非常にシンプルで、YAMLベースの記述が直感的でわかりやすいです。 リリース期限が決まっており、機能を考える際の取捨選択の中でiOSやAndroidのネイティブの複雑な機能は不要と判断して、シンプルなツールで十分であると判断しました。Maestroはネイティブの挙動の操作の弱さはありますが、必要十分な機能を提供してくれます。
現在の構成
現在の構成は以下のようになっています:
- GitHub Actionsから定期実行またはワークフロー手動実行
- EAS WorkflowでビルドとMaestroテストを実行
- E2Eテストを実行
ほとんど公式の引用ですが、具体的には以下のフローで動作しています:
# .github/workflows/stg-build-and-e2e-test-on-eas.yml - name: Run E2E Tests via EAS Workflow run: | eas workflow:run .eas/workflows/build-and-e2e-test-ios.yml \ --wait --non-interactive
# .eas/workflows/build-and-e2e-test-ios.yml jobs: build_ios_for_e2e: type: build params: platform: ios profile: e2e-test # Simulator用のビルド設定 maestro_test: needs: [build_ios_for_e2e] type: maestro params: build_id: ${{ needs.build_ios_for_e2e.outputs.build_id }} flow_path: ['.maestro/flows/work_flow_ci.yaml'] record_screen: true retries: 1
テストケース
現在、以下の5つのE2Eテストケースを用意しています:
work_flow_ci.yaml- メインワークフロー(CI上で実行)- そのほかの4つのワークフロー - ローカル環境で実行
すべてのテストケースをCI上で実行しているわけではありません。
開発者は各自のローカル環境で全テストを実行できますが、CI上では重要なケース(work_flow_ci.yaml)のみに絞っています。work_flow_ci.yamlは認証後のほとんどの画面で要素が正しく表示されるかを確認する内容です。
モバイルのE2Eでは、データの表示確認よりもネイティブの挙動(画面遷移、モーダル表示、キーボード操作など)を中心にテストしています。テストの設計方針として、E2Eテストはなるべく薄くしています。基本的にはユニットテストや統合テストでカバーし、E2Eテストは主要なユーザーフローの確認に集中させています。E2Eテストが多くなることで管理コストと実行時間が増大するためです。
理想と現実のトレードオフ
理想的な構成
本来であれば、以下のような構成が理想的だと考えています。
- テスト専用の環境をテストごとに動的に作成・破棄
- テストごとにデータのsetupとteardownが容易
- すべてのE2EテストケースをCI上で自動実行
このような構成であれば、テストデータの管理が容易になり、テスト間の依存関係を排除でき、より堅牢なテストが実現できます。
現実的な対応
リリースまでのスケジュールがタイトだったためスピードを最優先し、PMFの不確実性から初期の過剰な作り込みを避けるため、あえて理想的な構成とのトレードオフとして、以下のような現実的な対応を選択しました。
- Staging環境に対して直接テストを実行
- テスト専用環境の構築コストを削減
- 既存のStaging環境を活用
- 事前に作成されたテストアカウントを使用
- setup / teardownが不要
- テストに合わせてあらかじめ手動でデータを用意する必要がある
- CI上では重要なケースのみ実行
- セットアップが複雑なケースはローカルでのみ実行
- コスト削減と実行時間の短縮
これらは意図的なトレードオフです。 理想はテスト単位の環境を構築することで、データセットアップも容易になり、すべてのテストケースをCI上で実行できるようにしたいと考えています。しかし、現時点ではE2Eテストを導入し、品質向上に寄与することをまず優先しました。
Maestroの使い心地
開発体験
Maestroの導入前に懸念していた点がいくつかありましたが、実際に使ってみると非常にいい体験でした。
Maestro Studioの威力
Maestro Studio (CLI) | Maestro
Maestro Studioを使用することで、WebのGUI上から要素の検出からテストケースの作成まで、非常にスムーズに行えました。
# Maestro Studioの起動 maestro studio
ブラウザでhttp://localhost:9999/interactにアクセスすると、シミュレータの画面をリアルタイムで確認しながら、クリック操作や要素の検証を行えます。特に、要素のセレクタを自動で提案してくれる機能が便利でした。
YAMLによるシンプルな記述
Maestroのテストケースは、非常にシンプルなYAMLで記述できます:
appId: ${MAESTRO_APP_ID} --- # アプリ起動 - runFlow: file: ../shared/app_launch.yaml # ログイン処理 - runFlow: file: ../shared/login.yaml env: TEST_USER_AUTH_EMAIL: "test@example.com" TEST_USER_AUTH_PASSWORD: "password" # 画面要素の検証 - assertVisible: id: home-hoge-text - tapOn: id: home-fuga-button
ステップの再利用も、runFlowを使って簡単に実現できます。共通の処理(ログインなど)をshared/ディレクトリに分離することで、保守性の高いテストケースを作成できました。
EAS統合の容易さ
EASとの統合も非常にシンプルでした。公式ドキュメントに従うだけで、特別な設定なしにEAS上でMaestroを実行できます:
// eas.json { "build": { "e2e-test": { "extends": "staging", "ios": { "simulator": true, "buildConfiguration": "Release" } } } }
ポイントはsimulator: trueの設定のみ。これだけで、EAS上でシミュレータビルドが作成され、Maestroでテストできるようになります。
導入前の懸念点と実際
料金
料金体系の確認
Maestroは無料で利用できますが、EAS上での実行にはコストがかかります。特に以下の点を考慮する必要がありました:
- ビルド時間: シミュレータ用のビルドには約10分
- テスト実行時間: 1回のテスト実行に約5-10分
- 実行頻度: 平日毎日の定期実行 + 必要に応じた手動実行
コスト試算と最適化戦略
リリース頻度や開発フェーズを考慮してコストを試算しました。
頻度は以下の場合を想定しています:
- 平日毎日の定期実行:デグレを早めに検知するため
- APIのリリース時:API変更が現状リリースされているアプリに影響を与えないか確認するため
- 任意の手動実行:必要に応じた検証のため
テストを含めた1実行あたり300〜400円程度のコストがかかると見積もり、当初は月額数千円程度の運用を見込んでいましたが、リリース前の集中的な開発によるビルド・テストの繰り返しで実行頻度が増え、現在は月額3〜4万円程度のコストで推移しています。 プロダクションのリリース後はビルドとテストの頻度は落ち着くと思われます。当初の見積もりとはずれてしまいましたが、許容範囲として開発を進めています。
コストの最適化は急務ではないため、まずは必要な頻度で実行し、将来的に必要に応じて調整する方針としました。
テストの記述性・保守性
Gaugeとの比較
弊社では他のサービスでのE2EテストにGaugeを使用してきました。 Gaugeは、各ステップを人間が読みやすい自然言語で書くことができ、新規参加メンバーもテストケースを理解しやすいという利点があります:
# Gauge Example * メールアドレス:"test@example.com"とパスワード:"password"でログインする * ホーム画面が表示されること * "要素1" ボタンをタップ
このような記述方法に慣れていたため、YAMLベースのMaestroでテストが書きにくくなるのではないかという懸念がありました。
実際の体験
実際にMaestroを使い始めると、この懸念は杞憂でした:
YAMLは非常にシンプル: 直感的なキーワード(
tapOn,assertVisible,scrollUntilVisibleなど)で構成され、学習コストが低い初めてのエンジニアでもすぐに書ける: チームメンバーが特に苦労することなく、テストケースを書き始められた
公式ドキュメントが充実: ステップの再利用、変数の使用、条件分岐など、必要な機能はすべてドキュメントに記載されている
Maestro Studioのサポート: GUI上で操作を記録できるため、ステップを手動で書く必要がほとんどない
結果として、Gaugeと比較しても遜色ない、シンプルで保守しやすいテストコードを書けています。
まとめ
導入して良かった点
開発効率の向上
- Maestro Studioによる直感的なテスト作成
- YAMLによるシンプルで保守しやすいテストコード
- EASとのシームレスな統合
品質の担保
- 主要なユーザーフローを自動テストでカバー
- 平日毎日の定期実行により、リグレッションを早期発見
- 画面録画機能により、失敗時の原因特定が容易
柔軟な運用
- ローカルでの全テスト実行とCI上での重要テストのみ実行を使い分け
- コストと品質のバランスを取った現実的な運用
最後に
新規事業という制約の中で、理想と現実のバランスを取りながらMaestroを導入しました。完璧な構成ではありませんが、まずは始めることを優先し、段階的に改善していく方針が功を奏しています。
Maestro自体の開発体験は非常に良く、特にMaestro Studioの存在が大きいです。モバイルアプリのE2Eテスト導入を検討している方には、ぜひMaestroをおすすめします。
最小限の構成から始めて、プロダクトの成長とともにテスト基盤も進化させていく。この段階的なアプローチが、新規事業における現実的な選択だと実感しています。