Maestro:React NativeとFlutterのUIテスト自動化は、もう「苦行」ではない

Development tutorial - IT technology blog
Development tutorial - IT technology blog

リリース直前の「デグレード」という悪夢

金曜日の午後、チーム全員が仕事を切り上げて飲みに行こうとしていたその時、バグが牙を剥きます。よくある光景です。新しい機能をマージし、完璧に動作すると自信満々だったはずが、実は3ヶ月間ずっと正常に動いていた「新規登録(Sign-up)」フローをうっかり壊してしまっていたのです。

私は以前、Fintechプロジェクトで5万行を超えるコードベースのリファクタリングに携わったことがあります。その時の痛切な教訓は、「手動テストだけに頼ってはいけない」ということでした。UIテストの保護なしにコードを1行修正することは、運任せのギャンブルと同じです。しかし、モバイルアプリのUIテスト作成は、これまで非常に骨の折れる作業でした。

なぜモバイルのUIテストはこれほど難しいのか?

Appiumを触ったことがある人なら、環境構築やWebDriverの設定、複雑な依存関係の解決だけで丸一日を費やしてしまうあの感覚がわかるはずです。

UIテストは、以下の3つの大きな障壁があるため、中小規模のプロジェクトでは敬遠されがちです。

  • セットアップが複雑すぎる: Node.jsやAppium Serverから、各OS固有のDriverまで、あらゆるものをインストールする必要があります。
  • 動作が遅く不安定(Flakiness): エミュレータの遅延やアプリのアニメーションが原因で、テストが理由もなく失敗することがよくあります。20個のテストケースのうち、仮想マシンのカクつきだけで5個が失敗することもあります。
  • 独自の言語習得が必要: 単純なUIテストをしたいだけなのに、JavaやPythonといった重厚なフレームワークを別途学ぶ必要があります。

現在の主要なソリューション

Maestroについて詳しく見る前に、市場にある馴染みのあるツールをおさらいしておきましょう:

  1. Appium: 非常に強力ですが、ジュニアエンジニアにとってメンテナンスは悪夢です。
  2. Detox (React Native): コードに深く介入するため高速ですが、Androidの初期設定には膨大な時間がかかります。
  3. Flutter Integration Test: Flutterには最適ですが、マルチプラットフォームのプロジェクトや統一されたツールを求める場合には最善の選択肢とは言えません。

Maestro:あらゆるプロセスをシンプルに

Maestroはこのアプローチを根本から変えます。複雑なスクリプトを書く代わりに、YAMLファイルでテスト手順を定義します。React Native、Flutter、ネイティブのiOS/Androidでスムーズに動作します。

Maestroの最大の利点は、アニメーションや遅延の処理能力です。要素が表示されるのを自動的に待機するため、いわゆる「偽陰性(不当なテスト失敗)」の発生率を最小限に抑えられます。

ステップ1:30秒でMaestroをインストール

macOSまたはLinuxでは、次の1行のコマンドを実行するだけです:

curl -Ls "https://get.maestro.mobile.dev" | bash

その後、ターミナルを再起動し、バージョンを確認してインストールが成功したか確かめます:

maestro --version

注:Windowsの場合は、WSL2を使用することをお勧めします。

ステップ2:UI要素に識別子を付与する

Maestroが画面上のコンポーネントを見つけられるように、IDを付与する必要があります。

  • React Nativeの場合: testID プロパティを使用します。
<TouchableOpacity testID="login_button" onPress={handleLogin}>
  <Text>ログイン</Text>
</TouchableOpacity>
  • Flutterの場合: Semantics または Tooltip を使用します。また、Maestroは画面上に表示されているテキスト内容で直接検索することも可能です。

ステップ3:最初のテストフローを作成する

login_flow.yaml ファイルを作成しましょう。基本的なログインフローをテストすると仮定します:

appId: com.example.myapp # Bundle ID (iOS) または Package Name (Android)
---
- launchApp
- tapOn: "Email"
- inputText: "[email protected]"
- tapOn: "パスワード"
- inputText: "123456"
- tapOn: "login_button"
- assertVisible: "ようこそ!"

この構造は非常に分かりやすいものです。コードの深い知識がなくても、マニュアルQA担当者がテストセットの作成や内容の理解に参加できます。

ステップ4:実行と結果の確認

アプリをインストール済みのエミュレータまたはシミュレータを起動し、次のコマンドを実行します:

maestro test login_flow.yaml

Maestroが自動的にタップ、入力、結果の検証を行います. ファイルを修正するたびにテストを自動再実行したい場合(ホットリロードのような機能)は、-c フラグを追加します:

maestro test -c login_flow.yaml

ちょっとしたコツ:Maestro Studioを活用する

これは最も時間を節約できる機能です。要素の名前を推測する代わりに、次のように入力します:

maestro studio

Webインターフェースが表示されます。仮想マシンの画面上の任意の要素にマウスを合わせるだけで、Maestroが対応するYAMLコマンドを提案してくれます。あとはそれをコピーしてテストファイルに貼り付けるだけです。

ソースコードを守るためのCI/CD統合

ローカル環境でフローが安定して動作するようになったら、GitHub Actionsに組み込むのが一般的です。プルリクエスト(PR)が作成されるたびに、システムが自動的に全テストケースを実行します。

これを行うことで、既存の機能をうっかり壊してしまうのを防げます。CI上で実行する場合、Maestroが動作するように仮想マシン環境(iOSの場合はmacOS runnerなど)を構成する必要がある点に注意してください。

本番環境で深刻なエラーが発生するまで、テストを書くのを待たないでください. 今日からMaestroを使って、ログインやチェックアウトなどの最も重要なフローから始めてみましょう。そのシンプルさに、「もっと早く使っていればよかった」と思うはずです!

Share: