Accessibility ID as a locator strategy on Appium for iOS and Android apps

We‘re working on a Flutter app that connects to the Cars API API microservice to retrieve and display a list of cars. As testers working on this app, our primary motivation was to explore Flutter and gain a deeper understanding of how it supports cross-platform development. At the same time, we aimed to ensure that the testing process was smooth, efficient, and reliable across both iOS and Android. We focused on identifying platform-specific issues early, maintaining consistent test coverage, and minimizing duplicated effort when writing and executing tests for each platform. Early on, we ran into one of our first challenges: finding a reliable locator strategy that worked consistently across both platforms. In this short post, we’ll walk you through our journey, the approaches we explored, and the solution that worked best for us


The Problem with XPath for Cross-Platform apps

In our web automation tests, we typically rely on XPath because it’s flexible, expressive, and serves most scenarios well. Naturally, we extended this preference to our mobile automation too. However, when working with Flutter apps targeting both iOS and Android, we quickly ran into a problem: XPath expressions aren’t consistent across platforms. The same element may have entirely different paths on iOS and Android, like in this case the XPath for an element in the Android APP – //android.widget.ImageView[@content-desc="Swift"], the XPath for the same element on iOS is – //XCUIElementTypeImage[@name="Swift"]. This inconsistency makes it difficult to write stable tests that run reliably on both platforms. To build a truly robust and maintainable test suite for cross-platform apps, we needed a locator strategy that works uniformly, regardless of the underlying platform.


What Are Your Locator Options?

Here are a few common strategies we explored:

1. XPath:

We already use XPath in our Android mobile automation tests, but it didn’t work well for this project. XPath expressions vary between Android and iOS, and they generally perform slower because they traverse the entire UI hierarchy.

2. Class Name:

We tried using class name locators, but they didn’t suit our needs either. Android uses class names like `android.widget.TextView`, while iOS uses `XCUIElementType`, making it difficult to maintain consistency across platforms.

3. ID:

We also explored locating elements by ID, which is usually straightforward. However, the approach varies—Android uses the `resource-id` attribute, whereas iOS depends on the `name` attribute. This inconsistency made it harder to maintain a unified test strategy.

4. Accessibility ID:

We found Accessibility ID to be the best fit for this project. Originally designed to support assistive technologies, it also works well for test automation. Developers can assign it explicitly, and it provides a fast, consistent way to identify elements across both Android and iOS.

Picking Accessibility ID as the locator strategy worked seamlessly on both Android and iOS and helped us write clearer, more robust test scripts.


How to set useful Accessibility ID in Flutter

While the accessibility ID (or content-desc on Android and accessibilityIdentifier on iOS) can be used as a locator strategy in mobile test automation, if you don’t explicitly set this identifier using Flutter’s Semantics widget, Flutter may default to using the visible text of the widget as the accessibility ID. This can lead to unexpected locator behaviour, especially when the UI is dynamic or the text content changes. To ensure your test automation scripts have consistent and meaningful access to UI elements across both Android and iOS, you can request developers to wrap the intended widget in a Semantics widget and provide a label. This label becomes the accessibility ID that Appium can reliably use for element identification.
Here is what we added:

              Semantics(
                label: 'Swift_car',
                child: ExcludeSemantics(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
......

Enclosing the element widget in a Semantics widget and setting a label allowed us to use the label as the accessibility id.

Accessibility ID on Android and iOS

As you can notice from the Appium Inspector image for Android on the left and iOS on the right, the accessibility id is set to Swift_car. It is now easier for us to write a test that works on both Android and iOS platforms.


Cross-platform test automation brings its own set of challenges, especially when it comes to element identification. Through our exploration, we learned that while several locator strategies are available in Appium, not all are equally reliable across Android and iOS. Leveraging the accessibility ID strategy, combined with Flutter’s Semantics widget, allowed us to create tests that are both robust and maintainable. We hope this post helps other testers navigating similar challenges in their mobile automation journey.


UI test automation service from Qxf2

Qxf2 offers UI test automation service, helping businesses streamline their testing processes and ensure the highest quality in their applications. Our expertise in cutting-edge tools and frameworks, combined with our hands-on approach, allows us to design and execute tests that closely mimic real-world user interactions. Whether you’re testing a web app or a mobile app, Qxf2’s team delivers reliable, scalable, and efficient automation solutions. Reach out to [email protected] to learn more.


Leave a Reply

Your email address will not be published. Required fields are marked *