iOSのUIテストを実装する上で有用な要素検索のTipsをまとめました。
要素検索APIのクラス構成を把握する
UIテストの実装に慣れていないと、要素検索のメソッドチェーンを書こうとするときにどこでどのメソッドを使うのかわからなくなって、APIドキュメントとコードを行ったり来たりしてしまいます。
let element = app.tables.firstMatch.containing( // あれ、containingがない...? let element = app.buttons["GreatButton"].matching // あれ、ここでmatching使えないんだっけ...?
要素検索コードの実装で迷わないようにするには、要素検索APIのクラス構成を把握してしまえば良いのでは?と考えました。
ざっくり以下4つを理解しておけばいいかなと思います。
- XCUIApplication
- XCUIElement
- XCUIElementQuery
- XCUIElementTypeQueryProvider
先の例でいうと、firstMatchはXCUIElementを返すので、matching(:)やcontaining(:)といったメソッドは呼べません。
subscriptはXCUIElementを返すので、同じくmatching(:)やcontaining(:)といったメソッドは呼べません。
各プロパティやメソッドがXCUIElementとXCUIElementQueryのどっちを返すのかを意識すると良いです。
UI構造のスナップショットを見ながら検索コードを書く
UI構造が複雑なアプリでは、実装した検索コードで思うように要素が取得できないことがあります。
要素が取得できるようになるまでコードを修正してはテストを動かして、とやっていると効率が悪いので、LLDBデバッガを活用しましょう。
検索コードの行にブレークポイントを仕込み、UIテストを一時停止させます。
そして、Xcodeのデバッグコンソールでpo app
を入力します。すると、UI構造のスナップショットが確認できます。
さらに、このコンソールで検索コードを入力し、目的の要素がヒットするか確かめてみましょう。
テストコードの実行は停止していますが、アプリの実行は継続しているため、例えば目的の要素が画面に表示されるように手動で調整してから検索コードを試してみるということもできます。
NSPredicateを使った条件検索
要素タイプやaccessibilityIdentifierを使った検索以外に、NSPredicateを使った条件検索が可能です。
例えば、セル内のラベルの文字列にBambooが含まれるセルを検索するコードはこんな感じです。
app.tables.firstMatch.cells.containing(NSPredicate(format: "label CONTAINS 'Bamboo'")).firstMatch
検索条件に指定可能なオブジェクト(この例ではlabel
)は、XCUIElementAttributesプロトコルに準拠しているものに限られます。
例えば、label
の他に、title
やplaceholderValue
といったものがあります。
条件文(この例ではCONTAINS
)は他にも色々指定可能です。以下の記事でわかりやすくまとまっていたので参考にしてみてください。
まとめ
要素検索のTipsについてご紹介しました。
今後も便利なTipsが見つかったら追記していこうと思います。