自然言語とAI活用で保守性を高めるArbigentによるモバイルUIテスト自動化

こんにちは、Androidエンジニアの @syarihu です。

モバイルアプリのUIテストは、品質を保つために欠かせない作業です。しかし、画面遷移の複雑さや操作手順の細かな指定が必要になるため、テストコードの作成と保守には多くの時間がかかります。

今回、GiftmallのAndroidアプリプロジェクトでは、AIを活用したUIテスティングフレームワーク「Arbigent」を導入しました。この記事では、Arbigentの導入背景、セットアップ方法、実際の活用事例について紹介します。

Arbigentとは

Arbigentは、AIエージェントベースのUIテスティングフレームワークです。従来のUIテストでは要素IDやXPathを細かく指定する必要がありましたが、Arbigentでは自然言語でテストシナリオを記述できます。

マルチプラットフォーム対応: Android、iOS、Web(Experimental)に対応しており、同じアプローチで複数のプラットフォームのUIテストを実装できます。

Webについては環境要因なのかアプリ側なのかは切り分けはできていませんが、Java APIまわりの問題でChromeへの接続ができず今回は検証できていません。一方、AndroidとiOSについては、ほぼ同じシナリオで正しくテストを実行できました。

主な特徴

  • 自然言語でのシナリオ記述: 「ログイン画面が表示される」「ホームタブがある」といった人間が理解しやすい表現でテストを定義
  • AIによる自律的な操作: OpenAI APIなどのLLMを活用し、画面を認識しながら目標達成のための操作を自動実行
  • 詳細な実行ログ: 各ステップでの画面状態、実行したアクション、判断理由を記録
  • GUIアプリケーション: CLIだけでなく、直感的に操作できるGUIアプリケーションも提供されており、シナリオの作成や実行を視覚的に行える

導入の背景

GiftmallのAndroidアプリプロジェクトでは、これまでMaestroを使用してUIテストを実装していました。

Maestroは優れたツールですが、以下のような課題がありました。

  1. 詳細な要素指定の必要性: 各操作で正確な要素IDやテキストを指定する必要がある
  2. UIの変更への脆弱性: デザイン変更やレイアウト調整でテストが壊れやすい
  3. テストコードの保守コスト: 画面構成の変更に合わせてテストコードを更新する手間

Arbigentの導入により、これらの課題を軽減し、より柔軟で保守しやすいテスト環境を構築することを目指しました。

GUIアプリケーションでのシナリオ作成とテスト実行

ArbigentはGUIアプリケーションを提供しています。GUIアプリではyamlを直接編集することなく、視覚的にテストシナリオを作成・管理できます。

デバイス接続とプラットフォーム選択

GUIアプリケーションの初期画面では、次の設定を行います。

  • Device Type: Android、iOS、Web(Experimental)から選択
  • Devices: 接続されているデバイスやエミュレータを選択
  • AI Provider: OpenAI等のAIプロバイダーを設定
  • Variables: テストで使用する変数(メールアドレス、パスワードなど)を定義

このように、プラットフォームを選択するだけで、同じインターフェースでAndroid、iOS、Webのテストを作成できます。

ビジュアルシナリオエディタ

シナリオエディタでは、直感的にテストフローを作成できます。

  • 左ペイン: シナリオのツリー構造を表示。依存関係や階層構造が一目で把握可能
  • 右ペイン: 選択したシナリオの詳細設定(Goal、タグ、Image assertionなど)を編集
  • ドラッグ&ドロップ: シナリオの順序変更や階層の調整が簡単

GUIでシナリオを作成・編集した内容は、YAMLファイルとして保存でき、CLI環境でも実行できます。

テスト実行と結果の可視化

テスト実行後は、以下の情報が視覚的に表示されます。

  • 左ペイン: シナリオリストと実行状態
  • 中央ペイン: 各ステップの詳細ログ(AIの判断、実行したアクション)
  • 右ペイン: Annotated Screenshot(AIがどの要素を認識したかを示すスクリーンショット)

特に、Annotated Screenshotは、AIがどのように画面を認識し、どの要素に対してアクションを実行したかを視覚的に確認できるため、テスト失敗時のデバッグに非常に有用です。

ログ出力の日本語化

Arbigentはデフォルトでは実行中のログなどは英語で出力されますが、画面上部にある歯車アイコンからプロジェクト設定を開いて「Additional System Prompt」の部分に日本語での出力を明記しておくとAIエージェントの行動ログを日本語で出力できます。

Initialization MethodsとMaestro連携

Arbigentには、テストシナリオの実行前に特定の処理を実行するための「Initialization Methods」という機能があります。

この機能を使うことで、テストを実行する前にアプリの状態を整えたり、テストに必要な初期設定ができます。

Initialization Methodsには以下のような選択肢があります。

  • NoOp: 何もしない
  • Wait: 待機する
  • Cleanup app data: アプリデータをクリアする(私の環境では動作しませんでした)
  • Back: 戻る
  • Open link: リンクを開く
  • Launch app: アプリを起動する
  • Maestro YAML: Maestroのシナリオを実行する

Maestro YAMLを使ったアプリデータクリア

アプリデータのクリアには「Cleanup app data」オプションが用意されていますが、環境によっては正常に動作しないケースがあります。そのような場合でも、Maestro YAMLを使うことで確実にアプリデータをクリアできます。

Arbigentには Maestro と連携する仕組みが組み込まれています。Initialization MethodsとしてMaestro YAMLを選択することで、既存のMaestroシナリオをテスト実行前の初期化処理として利用できます。

例えば、アプリをクリーンな状態で起動するためのMaestro YAMLシナリオを作成できます。

appId: jp.co.giftmall
---
- launchApp:
    clearState: true

このシナリオをInitialization Methodsとして設定することで、各テスト実行前に必ずアプリデータがクリアされた状態からテストを開始できます。

既存のMaestroアセットの活用

すでにMaestroを使用してUIテストを実装している場合、そのシナリオをArbigentのInitialization Methodsとして再利用できます。これにより、次のようなメリットがあります:

  1. 複雑なセットアップの自動化: ログインフローなど、確実に実行したいセットアップ処理をMaestroで定義できる
  2. 既存資産の有効活用: すでに作成・メンテナンスされているMaestroシナリオを無駄なく活用
  3. 決定的な処理とAIの組み合わせ: 正確性が求められる初期化処理はMaestroで、柔軟な検証はAIエージェントで、という使い分けが可能

例えば、ログイン処理を確実に実行してからAIエージェントによる探索的テストを行う、といった使い方が効果的です。

CLIセットアップの実装

ArbigentはGUIだけでなくCLIでも実行できます。このセクションでは、CLIベースのセットアップとCI環境での実行を前提とした実装方法を紹介します。

バイナリベースのインストール

Arbigentの導入にあたり、チーム全体で統一されたバージョンを使用できるよう、バイナリベースのセットアップスクリプトを実装しました。

# Makefileからバージョン管理されたインストールが可能
make install_arbigent

インストールスクリプト(install_arbigent.sh)の特徴:

  • バージョン管理: MakefileARBIGENT_VERSIONを定義し、バージョンを一元管理
  • 自動バージョンチェック: インストール済みのバージョンと目標バージョンを比較し、必要に応じて自動更新
  • GitHub Releasesからの自動ダウンロード: 指定バージョンのバイナリを自動取得
# インストール先
.arbigent/bin/

# バージョン情報の保存
.arbigent/bin/.version

実行スクリプトの作成

テスト実行を簡単にするため、ラッパースクリプト(run_arbigent.sh)を実装しました。

主な機能:

  1. 自動インストールチェック: 実行前にArbigentのインストール状態を確認し、未インストールの場合は自動でインストール
  2. 環境変数によるAPI鍵管理: OPENAI_API_KEYをコマンドライン履歴に残さず安全に指定
  3. 設定ファイルの管理: 静的設定ファイル(.arbigent/settings.local.yml)でAIモデルやログレベルなどを管理
# 事前に環境変数でAPIキーを設定したうえでテスト実行
make arbigent ARGS="run --tags guest"

結果フォーマット機能

Arbigentの実行結果はYAML形式などで出力されますが、人間が読みやすいよう、フォーマット表示スクリプト(format_arbigent_result.sh)を追加しました。

# テスト結果を見やすく表示
make arbigent_result

出力内容:

  • シナリオIDと最終目標
  • 成功/失敗のステータス
  • 各タスクの実行結果
  • ステップごとの画面状態、メモ、実行アクション
  • 実行時間の記録

テストシナリオの実装

シナリオ定義

Arbigentでは、YAMLファイルでテストシナリオを定義します。前述のGUIアプリケーションで作成することも、直接YAMLを編集することも可能です。

arbigent.ymlに、ログインフローとゲストログインフローを実装しました。

scenarios:
  - id: "guest-complete-flow"
    goal: "ホーム画面が表示される"
    dependency: "guest-dismiss-notification-or-promotion"
    maxRetry: 1
    tags:
      - name: "guest"
      - name: "auth"
      - name: "critical"
    imageAssertions:
      - assertionPrompt: "画面上部にホームタブがある"
      - assertionPrompt: "画面上部に季節特集のタブがある"

ここで注目すべきは、imageAssertionsでの検証方法です。例えば「画面上部に季節特集のタブがある」という表現は、従来のテストでは「クリスマス特集」「バレンタイン特集」のように具体的な季節名を指定する必要がありました。

しかし、Arbigentでは抽象的な表現が可能です。AIが画面を認識し、「クリスマス特集」や「お正月特集」など、季節によって変わる具体的なタブ名を季節特集として認識してくれます。これにより、季節ごとにテストコードを書き換える必要がなくなり、保守性が大幅に向上します。

シナリオの依存関係

Arbigentの特徴的な機能として、シナリオ間の依存関係を定義できます。これにより、複雑なフローを小さな単位に分割し、テストの再利用性を高められます。

例:ゲストログインフロー

  1. login-show-onboarding: ウェルカム画面の表示
  2. guest-continue: 「ゲストで続ける」ボタンのタップ
  3. guest-dismiss-notification-or-promotion: 通知許可/プロモーションの表示
  4. guest-complete-flow: ホーム画面の表示確認

各ステップは独立したシナリオとして定義され、dependencyフィールドで依存関係を表現します。

タグによる実行制御

テストシナリオには複数のタグを設定でき、タグベースでの実行が可能です。

# ゲスト関連のテストのみ実行
make arbigent ARGS="run --tags guest"

# クリティカルなテストのみ実行
make arbigent ARGS="run --tags critical"

# 特定のシナリオを実行
make arbigent ARGS="run --scenario-ids guest-complete-flow"

定義しているタグ:

  • guest / login: 認証方法による分類
  • critical: ビジネスクリティカルなフロー
  • smoke: スモークテスト対象
  • regression: リグレッションテスト対象
  • quick / standard: 実行時間による分類

Maestroからの移行

既存のMaestroテストシナリオのうち、起動チェック、ゲストログイン、会員ログインのテストファイルをArbigentに移行しました。

移行の実例

Maestro(従来):

- assertVisible: "ゲストで続ける"
- tapOn: "ゲストで続ける"
- assertVisible: "次へ"
- tapOn: "次へ"

Arbigent(新):

- id: "guest-continue"
  goal: "ウェルカム画面で「ゲストで続ける」ボタンを押すと、「ギフトモールへようこそ」のモーダルが表示される"
  imageAssertions:
    - assertionPrompt: "ギフトモールへようこそ が表示される"
    - assertionPrompt: "次へ ボタンが表示される"
- id: "guest-promotion"
  goal: "会員登録促進ポップアップが表示される"
  dependency: "guest-continue"

Arbigentでは要素の詳細な指定が不要になり、自然言語での目標記述により意図が明確になります。

実行結果の例

実際にゲストログインフローを実行した際の結果を見てみましょう。

================================================================================
  Arbigent Test Results
================================================================================

Scenario: guest-complete-flow
--------------------------------------------------------------------------------
Final Goal: ホーム画面が表示される

Status: ✅ Success

[Task 1] ギフトモールのウェルカム画面が表示される
  Result: ✅ Goal Achieved
  Duration: 31s

  Steps: (4 total)
    Step 1:
      Screen: Androidのホーム画面。下部のドック右端に「Giftmall Dev」と表示されたアイコンがある。
      Memo: ギフトモールのアプリを起動してウェルカム画面へ進むため、ホーム画面の「Giftmall Dev」をタップする。
      Action: Click on index: 9

[Task 2] ウェルカム画面で「ゲストで続ける」ボタンを押すと、「ギフトモールへようこそ」のモーダルが表示される
  Result: ✅ Goal Achieved
  Duration: 17s

  Steps: (4 total)
    Step 1:
      Screen: ギフトモールのウェルカム画面。「ログインする」「会員登録(無料)する」「ゲストで続ける」の3つのボタンが下部に表示されている。
      Memo: ウェルカム画面で「ゲストで続ける」をタップしてモーダルを表示させる
      Action: Click on index: 2

各ステップで、AIが画面をどう認識し、どのような判断でアクションを実行したかが記録されます。これにより、テスト失敗時のデバッグが容易になります。

メリットと課題

導入により得られたメリット

  • テストコードの可読性向上: 自然言語での記述により、非エンジニアでも理解しやすいテスト定義
  • UIの変更への耐性: 要素IDに依存しないため、レイアウト変更の影響を受けにくい
  • テスト保守コストの削減: 詳細な要素指定が不要になり、テストの更新が容易
  • 抽象的な表現への対応: 「季節特集のタブ」のような抽象的な記述で、「クリスマス特集」「バレンタイン特集」など季節によって変わる要素を検証可能。季節ごとのテストコード変更が不要に
  • 実行ログの充実: AIの判断プロセスが記録され、テスト失敗時の原因特定が迅速化

現時点での課題

  • 実行時間: AIによる画像認識と判断処理により、従来のテストより実行時間が長い
  • APIコスト: LLM APIの利用に費用が発生する
  • 安定性: AIの判断に依存するため、同じシナリオでも実行ごとに動作が異なる可能性がある

今後の展開

今回の導入では、環境構築と基本的なログイン・ゲストログインフローの移行を完了しました。今後は以下の対応を予定しています。

  • CI環境での実行: GitHub ActionsなどのCI環境でのArbigent実行環境構築
  • 追加シナリオの移行: 他のMaestroテストシナリオのArbigentへの段階的移行
  • カスタムアサーションの拡充: プロジェクト固有の検証ロジックの追加
  • 実行時間の最適化: シナリオの並列実行や不要な待機時間の削減

まとめ

Arbigentの導入により、UIテストの記述がより直感的になり、保守性が向上しました。従来のテストツールとAIベースのテストツールは一長一短があるため、今後は両者を併用しながら、それぞれの強みを活かしたテスト戦略を構築していきます。

AIを活用したテスト自動化は、まだ発展途上の分野です。今回の導入事例が、同様の課題を抱えるチームの参考になれば幸いです。

参考資料