by the wayUnstable tests due to UI changes can lead to frustrating failures. To keep your tests running smoothly – even after app updates – structure your app using the tips below.
Table of contents
- Unique ID
- How to assign unique IDs for iOS
- How to assign unique IDs for Android
- Flutter
- WebView
- How to assign unique IDs for Browser
1. Unique IDs
To ensure that your automated tests remain stable when your app is updated, follow these two golden rules:
- Assign a unique ID to each UI element during development. This ID should be distinct from all other elements on the screen.
- Never change the unique ID when modifying your app’s UI.
MagicPod identifies UI elements using internal system information from the app. If unique IDs are missing or changed it can lead to test failures. By consistently assigning and maintaining unique IDs for each UI element, you can create a robust foundation for automated testing.
Below are specific methods for assigning IDs. If you need to request ID assignments from your development team, share these tips with them.
2. How to assign unique IDs for iOS
2.1. UIKit based UI
In Xcode, assign an Identifier to each UI element via Identity Inspector > Accessibility in the right pane, as shown below. This property, called accessibilityIdentifier, is used for UI automation and is invisible to regular app users.
The Identity Inspector cannot be used for dynamically generated elements (e.g., list rows). In such cases, set the accessibilityIdentifier property programmatically, as shown below:
tableViewCell2.accessibilityIdentifier = "toDoListLine2"
2.2. SwiftUI based UI
Set the accessibilityIdentifier property, as shown below:
TextField("First Name",
text: $viewModel.firstName,
prompt: Text("First Name")
).accessibilityIdentifier("First Name")
3. How to assign unique IDs for Android
The method for assigning IDs depends on whether your UI is View-based or built with Jetpack Compose.
3.1. View-based UI (XML)
You can set a unique identifier in two ways. You can set the resource ID on the Android Studio GUI, or set the contentDescription attribute in your source code. However, if you want to run one test case on both iOS app and Android app, you cannot use resource IDs and must use contentDescription attributes instead.
3.1.1. Setting a resource ID in Android Studio
In Android Studio, specify an ID for each UI element under Attributes > ID, as shown below. The resource ID uniquely identifies elements in the program.
3.1.2. Setting the contentDescription attribute in code
For dynamically generated elements such as list rows, assigning a resource ID is challenging due to some constraints (see How to set ID of dynamically created layout). In such cases, consider using the contentDescription attribute instead. See the Java code for setting contentDescription below:
view.setContentDescription("toDoListLine2");
The contentDescription attribute is typically used for screen readers and accessibility features, but it also helps MagicPod identify UI elements. However, since contentDescription and text attributes may change when the UI is updated, they are more susceptible to screen changes than resource IDs.
3.2. Compose-based UI (Jetpack Compose)
3.2.1. Using testTag
- Declare testTagsAsResourceId = true at the highest level of the UI tree where testTag will be used. This setting allows the automation engine to recognize the assigned ID.
- Assign a string in the following format to the testTag modifier:
<<package_name>>:id/<<custom_string>>
Below is an example of defining a custom resourceID modifier and assigning a test tag with a package name prefix.
3.2.2. Using contentDescription
Assign the contentDescription attribute programmatically, as shown below.
4. Flutter
This section demonstrates three ways to configure widgets for assigning unique IDs to elements. If you want to run a single test case on both iOS and Android apps, consider using either the label property on the Semantics Widget or the semanticLabel property on Widget.
4.1. Using the label property on the Semantics Widget
Wrap the widget to which you want to assign a unique ID with Semantics widget. Then, configure the label property with an arbitrary value. This will make the accessibility id locator available for the UI element on both iOS and Android.
For example, suppose you want to assign a unique ID to the following EleveatedButton widget.
Wrap the EleveatedButton widget and assign the label property of the Semantics widget as shown below:
As a result, the accessibility id with "magicpodLabel" value will be available.
4.2. Using the identifier property on Semantics Widget
Wrap the widget to which you want to assign a unique ID with Semantics widget. Then, configure the identifier property in the following format:
<<package_name>>:id/<<custom_string>>
By doing this, both an accessibility id locator and an id locator will be available on iOS and Android, respectively.
- Note that the test automation engine on Android requires the format specified above, while on iOS the locator does not this format.
- The following example demonstrates how to assign an accessibility id locator and an id locator for iOS and Android.
The value of the locators is:
com.trident-qa.sample_app:id/magicpodIdentifier
This will be recognized by both platforms.
4.3. Using the semanticLabel property on Widget
You can also assign unique ids by configuring semanticLabel property on the widget.
The following example demonstrates how to assign an accessibility id locator for both iOS and Android using the semanticLabel property.
For both platform, the value of the locator is:
magicpodFlutterImage
This property is available on some widgets such as Text, SelectableText, ProgressIndicator, Icon, and Image.
Additionally, for widgets such as IconButton and FloatingActionButton, configuring the tooltip property will assign an accessibility id to a UI element on iOS.
5. WebView
Using the Enable WebView Scan option improves the maintainability of test scripts. See WebView tests for more details.
6. How to assign unique IDs for Browser
For web applications, simply adding an id attribute to an HTML tag is sufficient to be recognized as a unique ID.
If If a fixed id isn’t possible due to framework constraints, consider using the data-testid attribute instead. This attribute is commonly used in React and other frameworks for test element identification, and MagicPod also treats it as a unique ID.
<div id="user-name">XXX</div>
<div data-testid="user-name">XXX</div>