Open6

XUITest: メモ

kabeyakabeya

swift-testingというのにそろそろ移行するんじゃ…というタイミングではありますが…。

どうやってテストやるのか調べたところをメモ。

kabeyakabeya

ソフトキーボードが表示されているかどうか確認する方法。

let softKeyboard = app.keyboards.firstMatch
XCTAssertTrue(softKeyboard.exists)

何かをタップしてソフトキーボードが表示されると.existstrueになります。
表示されていなければfalse

非表示→表示と状態遷移する場合、最初の表示されていないタイミングでfirstMatchを取ると、空振りして.existsfalseになります。存在してないからといってnilにはなりません。

また、表示されたあとに(.firstMatchを再度とったりはせずに)同じ変数に対して.existsを見るとtrueになっているんですね。 要は.exists`を参照するたびに動的に画面の要素の取り直しが行われて有無がチェックされます。

.firstMatchは、ツールチップには「The first element that matches query」とか書いてあるんですが、問い合わせの結果ではなくて、最初の結果を返せという問い合わせ自体が返ってくるような感じですね。

kabeyakabeya

複数のコンポーネントを1つのビューに入れて複合コントロールとし、それを親ビューに埋め込んでidentifierを設定している場合、例えばapp.buttons["何か識別子"]としても複合コントロール内にある複数のボタンが返ってきてしまうことがあります。

なので、identifier以外にlabelも使ってXCUIElementを取得したい。

let testButton = app.buttons.allElementsBoundByIndex.first(where: {$0.identifier == "何か識別子" && $0.label == "何かラベル"})
XCTAssertNotNil(testButton)
//例えばタップ
testButton!.tap()

こんな感じでしょうか。

kabeyakabeya

Image(systemName: "square")なんですが、XCUITestの場合、app.collectionViews.images["Square"]で参照することができます。

ですが、テストケースの先頭で、

let app = XCUIApplication()
app.launchArguments += ["-AppleLanguages", "ja"]
app.launchArguments += ["-AppleLocale", "ja_JP"]
app.launch()

のように日本語ロケールを指定すると、app.collectionViews.images["正方形"]でないと取れてこないようになります。
面倒くさい…

kabeyakabeya

Image(systemName:)とXCUITestでのlabelの関係をいちいちテストケース作成時に調べるのが面倒なので、対比表を作りました。
今日(2024/3/10)時点でSFSymbolsに入っていた5359件です。
でかいのでgithubに置きました。

https://github.com/takenori-kabeya/XCUITestSymbolNames/blob/main/sfSymbolNames.md

別のシンボルに同じ名前が割当されているケースもありますね。
その辺のケースではidentifierを明示的に割り振ったほうが良さそうです。

kabeyakabeya

XCUITestやってて気がつきましたが、Listで右スワイプすると表示される削除ボタン、これ日本語環境にしても「Delete」ってラベルが付きますね。

Listにモディファイアで.environment(\.locale, Locale(identifier: "ja_JP")って付けると「削除」になります。
DatePickerも同様に、モディファイアつけないとMar 10, 2024になります。
気を付けないと。
(ほんとかなって気がしますが)