Maestroは本当に最もシンプルで効果的なのか

# Maestroって何？

サンフランシスコにあるmobile.dev incが作ったモバイル向けUIテストフレームワークです
対応プラットフォームは iOS, Android, ReactNative, Flutter
公式の説明によると

> Maestroは、最もシンプルで効果的なモバイルUIテストフレームワークです。
（原文をDeepL訳）

とあり、「最もシンプルで効果的」と言い切ってるところに興味を持ちました

テストシナリオはyamlでかきます
公式Exampleがわかりやすかったので、イメージとしてのせておきます

<img src="https://559345148-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5KVIOjVkVjYRyVWZ0yT%2Fuploads%2FBdkVbb4VQTkL4zLm6nvm%2Ftwitter_continuous_v3_fast.gif?alt=media&token=8a812b85-3b44-44f0-9137-3e74293b1acc" />

# 公式から読み取ったメリット

- 最もシンプルで効果的😇
- 対応プラットフォームが多い（iOS, Android, ReactNative, Flutter）
- OSS（Apache License 2.0）

# セットアップ（Mac）

Maestro cli を以下のコマンドでインストールします
```shell_session
$ curl -Ls "https://get.maestro.mobile.dev" | bash
```

なんと、これだけで使えます
※ただし、前提条件があります
- Xcode version 14 以上
コマンドラインツールがインストール済（iOSだけかも）
(Xcode -> Preferences -> Locations -> Command Line Tools)
- [facebook/idb](https://github.com/facebook/idb)　が必要（iOSだけかも）
- Androidは.apkのみ（.aabはダメ！）
- iOSは.appのみ（.ipaはダメ！）

# テスト対象アプリ

以下アプリを使います

https://github.com/a7ther/android-open-ai-sample

以前サンプルとして作成したOpenAI APIを叩くだけの簡単なアプリで、
動作イメージはこんな感じ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441643/053419f5-3e63-ea35-0969-4d227c5d33f6.gif" width="300" />

# シナリオ

1. アプリを起動する
1. プロンプトを入力する
1. Sendボタンをタップする
1. レスポンスを待ち、エラーメッセージ「HTTP 401」が表示されることを確認する

## シナリオを作る

https://maestro.mobile.dev/api-reference/commands

はじめにリファレンスです
驚くほどコマンドが少ないです

### 1. アプリを起動する

```yaml
appId: com.example.open_ai_sample.debug
---
- launchApp
```
説明するものがないほどシンプルですね
debug buildは`.debug`を忘れずに

### 2. プロンプトを入力する

入力する前にTextFeildを選択しないといけないですが、
どうやって（文字列？Id？）選択しようかな？ってなりますよね
そこで、Maestro Studioというツールがあります
ざっくり例えると簡易的なChromeデベロッパーツールのようなもので、
GUIで要素を選択するとtap, assert, conditionalなどの方法を提案してくれます
以下コマンドを打つとブラウザで起動します
```shell_session
$ maestro studio
```
詳しくはこちらへ

https://maestro.mobile.dev/getting-started/maestro-studio

Maestro StudioでTextFeildを確認した結果、今回は文字列でタップします
文字列の場合見たらわかるじゃん！ってなりますが、
Resourceを設定している場合、Idが取得できるので超有能ツールです
```yaml
- tapOn: "input prompt"
```

次にpromptを入力します
```yaml
- inputText: "Hello World"
```

:::note warn
version 1.29.0 では unicode charactersが入力できません
開発中みたいなので、今後に期待です
:::

### 3. Sendボタンをタップする
```yaml
- tapOn: "Send"
```

### 4. レスポンスを待ち、エラーメッセージ「HTTP 401」が表示されることを確認する

```yaml
- assertVisible: "ERROR : HTTP 401 "
```
文字列でassertします
最初、"HTTP 401"で試したのですが、assertionしてくれずにタイムアウトしてしまいました
ここで、Maestro Studioの出番です
一瞬で解決できました
（要素内の文字列の一部ではassertionしてくれない模様）

# 実行

作成したシナリオです。短すぎる！
```yaml: maestro/SampleScenario.yaml
appId: com.example.open_ai_sample.debug
---
- launchApp
- tapOn: "input prompt"
- inputText: "Hello World"
- tapOn: "Send"
- assertVisible: "ERROR : HTTP 401 "
```

以下コマンドで実行します🚀
```shell_session
$ maestro test ./maestro/SampleScenario.yaml
```
![maestro-sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441643/663bb91c-c8d3-2b61-60d0-0d1064ce9287.gif)

# 使ってみて、気になったこと
- まだ日本語入力ができない😭
- ReactNative, Flutterはyamlも1つでOKなのかどうか🤔
- スクロールを完全に同じ位置でとめることができるのか（1pxのズレも許しません）🤔
- センサーなどのOS固有機能を含んだテストができるのか🤔
- 通信のmock化がdeprecatedになっている（使いたい人は多いはずだが、代替が見当たらなかった）🤔

# まとめ

自分はAndroidのUI Test(Espresso, UI Autometor)としか比較できないため、
最もシンプルかどうかはわからないですが、Espresso, UI Autometorとは比べ物にならないほど簡単でした
これならエンジニア以外でもシナリオを作成できるため、シンプルで効果的というのは頷けます

今回作成したシナリオは以下のリポジトリのmaestroディレクトリに置いているので、
cloneしてお手元で試せます

https://github.com/a7ther/android-open-ai-sample/blob/main/maestro/SampleScenario.yaml

# 参考リンク

https://www.mobile.dev/

https://maestro.mobile.dev/

https://github.com/mobile-dev-inc/maestro