0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Maestro 入門

Posted at

Maestro とは?

公式ドキュメントの内容

Maestro の導入

前提

  • OS: macOS
  • Xcode14 以上をインストールしておく

maestro をインストール

前提としてhomebrewをインストールした上で、以下コマンドを実行してmaestroをインストールします。(homebrewのインストールは公式ドキュメントを参照)

brew tap mobile-dev-inc/tap
brew install maestro

以下公式ドキュメントを参考にしています。
https://docs.maestro.dev/getting-started/installing-maestro

Maestro で行う UI テストを書く

Maestro Studio による GUI ツールでのテスト作成

Maestro Studio の起動

シミュレーターをあらかじめ起動しておく必要があります。
以下でシミュレーターを起動できます。(またはXcodeでアプリを実行して任意のシミュレーターを起動しましょう)
open -a Simulator

Maestro の UI テストを GUI で作成するツールが、Maestro 側で用意されています。
以下コマンドで、そのツールを立ち上げます。
maestro studio

実行時ログは以下になります。

% maestro studio
Running on iPhone 16 - iOS 18.2 - 566836CA-C153-4F8B-AFEA-FCD9966B1C55

複数のシミュレーターが立ち上がっている状態で、maestro studioを実行すると、以下のようにどのシミュレータで実行するかを選択することもできます。

% maestro studio
iOS

[1] iPhone 16 - iOS 18.1 - 63E10B92-8C1E-4CC3-97A1-561536C41F7A
[2] iPhone 16 Pro - iOS 18.2 - D2AE3E98-6626-45C2-BDF9-0D1E522385E7

Multiple running devices detected. Choose a device to run on.

Enter a number from the list above:

maestro studioが立ち上がると、ブラウザの GUI ツールが立ち上がります。

image.png

Maestro Studio で動作確認する

試しにあるボタンをタップしてみると、以下のようなポップアップが表示されます。

image.png

再生ボタンを押下すると、アプリの画面がボタンを押下した時の挙動をとります。

image.png

今回のアプリではボタンを押すと、別画面へ遷移するのでブラウザ上のアプリの画面も画面遷移しています。
また、右画面には先ほど実行したコマンドが表示されています。

image.png

このコマンドが、Maestroテストを構成するコマンドになります。

以下のように、直接自分でコマンドを入力してコマンドの動作確認をすることもできます。
ちなみに以下は"Diary List"という文言が画面に表示されているかを検証するコマンドです。

image.png

アプリを自動で動作させる様々なコマンドがあるので、一度公式のリファレンスを見ることをお勧めします。
https://docs.maestro.dev/api-reference/commands

Maestro Studio でテストコードを出力する

いろいろいじってみたらコマンドが溜まってきたので、今まで触ってきた操作を自動化してもらえると嬉しいですよね。
Maestro Studioで使用したコマンドは、実際にテストを行うときに使用するymlファイルにエクスポートすることもできます。

例として、まず以下のようにMaestro Studioで画面を操作します。すると右側にコマンドが溜まっていきます。
image.png

実際にテストで使用したいコマンドにチェックをつけます。
image.png

チェックをつけたら、"Export"ボタンを押下します。
image.png

以下のような画面が表示されるので、"Save"ボタンを押下するとymlファイルがダウンロードされます。
image.png

export すると以下のような yml ファイルが出力されます。

appId: null
---
- tapOn: "graph_circle"
- tapOn:
    point: "11%,9%"
- tapOn:
    point: "14%,14%"
- tapOn:
    point: "66%,25%"

UIテストを実行する

作成したテストコード(yml ファイル)を使って、UI テストを実行するには、以下コマンドを実行すれば OKです。

maestro test <ymlファイルのパス>

上記実行時にも、シミュレーターは立ち上げておく必要ありです。

今回は以下のような yml でテストを行ってみます。

appId: <アプリのバンドルID>
---
# 初期状態にする
- clearState
# アプリ起動
- launchApp

- tapOn: "graph_circle"
- tapOn:
    point: "11%,9%"
- tapOn:
    point: "14%,14%"
- tapOn:
    point: "66%,25%"

実行結果は以下のような感じ
失敗したステップがあればその場で中断し、緑のチェックではなく赤のマークがつきます。

Running on iPhone 16 - iOS 18.2 - 566836CA-C153-4F8B-AFEA-FCD9966B1C55

 ║
 ║  > Flow
 ║
 ║    ✅  Clear state of morimori.Macho
 ║    ✅  Launch app "morimori.Macho"
 ║    ✅  Tap on "graph_circle"
 ║    ✅  Tap on point (11%,9%)
 ║    ✅  Tap on point (14%,14%)
 ║    ✅  Tap on point (66%,25%)
 ║

╭───────────────────────────────────────────────────────────────────────────────╮
│                                                                               │
│   A new version of the Maestro CLI is available (1.39.13). Upgrade command:   │
│   curl -Ls "https://get.maestro.mobile.dev" | bash                            │
│                                                                               │
╰───────────────────────────────────────────────────────────────────────────────╯

検証方法

UI テストなので、何かしら検証する必要があります。
検証の主な手法としては、特定の要素が画面に表示されているかを確認することだと思います。
Maestro では、assertVisibleというコマンドが提供されています。

例えば、アプリを起動して以下のような画面が表示されるとします。

image.png

画面に"表示する日記がありません"という文言が表示されることを検証したい場合は、以下のような yml を書きます。

main.yml
appId: <アプリのバンドルID>
---
# 初期状態にする
- clearState
# アプリ起動
- launchApp
# 検証
- assertVisible: "表示する日記がありません"

これでmain.ymlがあるディレクトでmaestro test main.ymlを実行すると、以下のようにテストが実行され成功します。

Running on iPhone 16 - iOS 18.2 - 566836CA-C153-4F8B-AFEA-FCD9966B1C55

 ║
 ║  > Flow
 ║
 ║    ✅  Clear state of morimori.Macho
 ║    ✅  Launch app "morimori.Macho"
 ║    ✅  Assert that "表示する日記がありません" is visible
 ║

以下のように、期待する文言を変えるとテストは失敗します。

 appId: <アプリのバンドルID>
 ---
 # 初期状態にする
 - clearState
 # アプリ起動
 - launchApp
 # 検証
- - assertVisible: "表示する日記がありません"
+ - assertVisible: "表示する日記がありまてん"
Running on iPhone 16 - iOS 18.2 - 566836CA-C153-4F8B-AFEA-FCD9966B1C55

 ║
 ║  > Flow
 ║
 ║    ✅  Clear state of morimori.Macho
 ║    ✅  Launch app "morimori.Macho"
 ║    ❌  Assert that "表示する日記がありまてん" is visible
 ║

Assertion is false: "表示する日記がありまてん" is visible

assertion 系のコマンドは他にもいくつかあるので、必要なコマンドがないか公式リファレンスで調べてみると良いです。

https://docs.maestro.dev/api-reference/commands/assertnotvisible
https://docs.maestro.dev/api-reference/commands/extendedwaituntil

要素の指定方法について

Maestro でタップ(tapOn)や指定の要素があるかどうかの検証(assertVisible)を行うときなど、要素を指定することはたくさんあります(どの要素をタップするのか、どの要素が存在するのを検証するのかなどの用途)
Maestro では要素を指定方法をセレクターと呼び、いくつかの方法を提供してくれています。

公式ドキュメントでは以下方法で指定することができることを提示してくれています。

- tapOn: # or any other command that works with selectors
    text: 'Text'     # (optional) Finds element with text or accessibility text that matches the regular expression
    id: 'the_id'     # (optional) Finds element with accessibility identifier that matches the regular expression
    index: 0         # (optional) 0-based index of the view to select among those that match all other criteria
    point: 50%, 50%  # (optional) Relative position on screen. "50%, 50%" is the middle of screen
    point: 50, 75    # (optional) Exact coordinates on screen. x:50 y:50, in pixels
    width: 100       # (optional) Finds element of a given width
    height: 100      # (optional) Finds element of a given height
    tolerance: 10    # (optional) Tolerance to apply when comparing width and height
    enabled: true    # (optional) Searches for view with a given "enabled" state
    checked: true    # (optional) Searches for view with a given "checked" state
    focused: true    # (optional) Searches for view with a given "focused" state
    selected: true   # (optional) Searches for view with a given "selected" state

自分としてはidにてaccessibility identifierを使った指定方法が良いと思っています。
理由としては、最もテストが壊れにくい指定方法と考えるからです。
座標指定(point)だとデバイスのサイズによっては意図した要素を指定できないこともあるので、デバイス依存のテストになってしまいます。
また、表示文言指定(text)だと、ローカライズしているなどの事情があれば、デバイスの言語設定に依存してしまいます。(ローカライズしていないアプリでも、OS 依存のダイアログなどはデフォルトでローカライズされているので、この問題の影響を受ける)
accessibility identifierであれば、上記懸念はないので最も壊れにくいテストになると思われます。

yml ファイルを分割する

確認項目が大きくなってくると、yml ファイルが巨大化してくることが予想できます。
それを防ぐために、画面毎などある程度の粒度で yml ファイルを分けられると嬉しいですね。

maestro では yml ファイルから別の yml ファイルのテストを呼び出すことが可能です。
実装例としては以下のような感じ。

main.yml
appId: <アプリのバンドルID>
---
# 初期状態にする
- clearState
# アプリ起動
- launchApp
# 別のymlファイルを呼び出す
- runFlow:
    file: "check_graph.yml"
check_graph.yml
appId: <アプリのバンドルID>
---
- tapOn: "graph_circle"
- tapOn:
    point: "11%,9%"
- tapOn:
    point: "14%,14%"
- tapOn:
    point: "66%,25%"

触ってみての感想

  • UI テストを書くコストはかなり低いように感じました。Maestro の GUI ツールで自分の期待する操作を行っていると、Export 機能によって自動で UI テストを生成できるので、非開発者でも UI テストを作れそうという気持ちです。

  • クロスプラットフォームに対応したツールなので、iOS と Android で共通で使うことも可能です。
    ただ、実際 iOS と Android で完全に同じ UI になることはあまりないなと思っている(OS のダイアログが違っていたり、微妙に画面のフローが違っているのはあるあるかと)ので、
    iOS と Android で共通化できるという目的で利用できるのはレアケースでしょう。
    もしやるなら、テキストもしくは AccessibilityId を iOS/Android で完全に揃えて、画面の遷移フローなどもすべて同じである必要があると思います。

  • OS で表示される一部画面ではうまく要素を認識してくれない問題に当たったりということがあったので、一部テストが難しい画面もあります。
    例えば、HealthKit の権限モーダルは maestro が要素の位置をうまく検出できなくて、テキストや ID での選択ができず座標指定しか使えなかったです、、

  • テストレポートについては、フロー毎(yml ファイルの粒度)に成功したかどうか程度の情報しか出せないので、テストカバレッジなどの高度なレポートは期待できません

  • 実機で Maestro を使用することができないので、シミュレーター上で行えるテストしかできません

入門してみての所感として、手軽な UI テストツールではありますが、一部かゆいところには手が届かず複雑なテストには向かないです。
手軽さ重視で自動化できないところは手動で行うことも辞さない場合は、非常に良いツールなのではと思いました。
逆に手動テストをほぼ全て自動化したい、カバレッジをとってどれぐらいケースを網羅できているのかを知りたいといった用途では Maestro は向かないように思いました。

おわり

今回は入門レベルでどんなことができるのか調べてみましたが、他にもできることがあるので応用編の記事を出す頃にはMaestroの感想も変わるかもです。
まだベータ版でしたが、AIの技術を用いた検証のコマンドがあったり、AIにテスト品質を解析してもらうといった機能もあったので、そのあたりはかなり楽しみですね。

https://docs.maestro.dev/api-reference/commands/assertwithai
https://docs.maestro.dev/cli/test-suites-and-reports#analyze

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?