ここでは、ユニークIDの具体的な付与方法についてご案内します。
目次
1. iOSの場合
1.1. UIKitベースのUIの場合
Xcode右側ペインのIdentity Inspector > Accessibilityの項目にて、図1のように各UI要素にIdentifierを指定してください。このプロパティはaccessibilityIdentifierというUI自動操作のためのプロパティで、通常のアプリ利用者からは見えません。
図1 XcodeからaccessibilityIdentifierを指定
なお、リストの行のようにアプリの実行時に動的に生成される要素については、上記のようにIdentity Inspectorは使えません。そのような場合は、図2のようにプログラム中でaccessibilityIdentifierプロパティをセットしてください。
tableViewCell2.accessibilityIdentifier = "toDoListLine2"
2. Android の場合
2.1. ViewベースのUI(XML)の場合
2.1.1. Android StudioでリソースIDをセットする
Android Studioの右側ペインのAttributes > IDの項目にて、図4のように各UI要素にIDを指定してください。この属性は、リソースIDというプログラム上で要素を一意に識別するための属性です。
2.1.2.プログラム中でcontentDescription属性をセットする
Androidの場合、リスト行のような動的生成される要素にリソースIDを振るのは、様々な制約があり大変です (詳しくはHow to set Id of dynamic created layout?を参照してください)。こういった動的生成される要素に対しては、contentDescription属性を指定することを検討してください(text属性を持つ要素については、そちらでも可)。
動的生成される要素に対しては、図4のようにプログラム中でsetContentDescriptionメソッドを使ってcontentDescription属性をセットできます。
view.setContentDescription("toDoListLine2");図5 contentDescriptionをセットするJavaコード
contentDescription属性は視力が不自由な人のための音声読み上げ機能などが使用する情報ですが、この情報があるとMagicPod側でUI要素の特定が容易になります。(ただしcontentDescription属性やtext属性はアプリの画面変更の際に変更されることもあるので、リソースIDと比べ画面変更の影響は受けやすいです。)
2.2. ComposeベースのUI(Jetpack Compose)の場合
2.2.1. プログラム中でtestTagをセットする
- testTagsAsResourceId = trueを、testTagを利用したいツリーの最上部で宣言してください。この設定によって、指定したIDを自動化エンジン側から認識可能になります。
- testTag修飾子に、以下の形式で文字列を設定してください。
<<パッケージ名>>:id/<<任意の文字列>>
2.2.2. プログラム中でcontentDescription属性をセットする
3. Flutterの場合
FlutterではいくつかユニークIDを付与する方法がありますが、ここでは3つの方法を紹介します。1つのテストケースでiOSとAndroidアプリ両方のテストを行いたい場合はSemanticsウィジェットのlabelをセットする か ウィジェットにsemanticLabelをセットするようにしてください。
3.1. Semanticsウィジェットのlabelをセットする
ユニークIDを付与する対象となるウィジェットをSemanticsウィジェットでラップし、Semanticsウィジェットのlabelプロパティに任意の値を設定してください。こうすることでiOSおよびAndroidでaccessibility idロケータが使用可能になります。例えば、以下のElevatedButtonウィジェットにユニークIDを付与したい場合、
3.2. Semanticsウィジェットのidentifierをセットする
ユニークIDを付与する対象となるウィジェットをSemanticsウィジェットでラップし、Semanticsウィジェットのidentifierプロパティを以下の形式となるようにセットしてください。
<<パッケージ名>>:id/<<任意の文字列>>
こうすることでiOSとAndroidでそれぞれaccessibility idロケータとidロケータが使用可能になります。なお、identifierプロパティ値にアプリパッケージ名が必要となるのは、Android側のテスト自動化エンジン上の制約です (iOSでは必要ありません) 。以下の例だと「com.trident-qa.sample_app:id/magicpodIdentifier」という値のaccessibility idロケータとidロケータがそれぞれiOSとAndroidで使用可能になります。
3.3. ウィジェットにsemanticLabelをセットする
対象となるウィジェットのsemanticLabelプロパティの値をセットすることでもユニークIDの付与が可能な場合があります。例えば、以下のように ImageウィジェットのsemanticLabelプロパティに値をセットすると、iOSおよびAndroidで「magicpodFlutterImage」という値を持つaccessibility idロケータが使用可能になります。
semanticLabelプロパティは Text、SelectableText、ProgressIndicator、Icon、Imageウィジェット等で使用可能です。また、IconButtonやFloatingActionButtonウィジェット等で使用可能なtooltipプロパティの値はiOSの場合にaccessibility idロケータとして使用可能なようです。
4. React Nativeの場合
testIDプロパティ(iOS用)とaccessibilityLabelプロパティ(Android用)を設定することで、iOS・Android両方でユニークIDが付与されます。
例:
<Pressable
testID="login-button"
accessibilityLabel="login-button"
onPress={handleLogin}
>
<Text>ログイン</Text>
</Pressable>
5. WebViewの場合
「WebViewをスキャン」オプションを使用すると、WebViewに対するテストスクリプトのメンテナンス性を向上させることができます。詳細はWebViewのテストを参考にしてください。
また、こちらを参考にdata-testid属性を付与してください。
6. ブラウザの場合
Webアプリケーションの場合は、単純にHTMLタグのid属性を付与するだけでユニークIDとして認識させることができます。また、アプリケーションのフレームワークの都合上固定のidを付与しづらい場合には、代わりにdata-testid属性を付与することをおすすめしています。data-testid属性はReactなどで実装されたアプリケーションでテスト対象を示すための属性として一般的に使われているため、MagicPodでもユニークIDとして扱います。
<div id="user-name">XXX</div>
<div data-testid="user-name">XXX</div>
data-testid 属性の他にも、アクセシビリティ属性を適切に設定することで、一意で安定したロケーターを生成できます。
例えば、imgタグの要素にはalt属性を付与すると、css=img[alt=商品一覧についての説明]といった保守性の高いロケータを設定できます。
他の要素(buttonタグなど)では、テキスト情報を持つものはそれが通常アクセシビリティ情報となりますが、無い場合にはaria-label属性などを使ってアクセシビリティ情報を付与すると良いでしょう。
他にも、以下の画像のように「商品名」というラベルが入力フィールドに紐づいている場合、xpath=//input[@id=//label[text()='商品名']/@for] というロケーターが候補として表示されます。
このロケーターは、入力フィールドの id が変わっても、ラベルのテキストが変わらない限り壊れない、保守性の高い書き方です。