In Appium on iOS, what changes when you swap the `id` strategy for `accessibility id`?
answer
- three doors, one room on iOS
- one attribute versus two attributes
- the swap is cosmetic on one platform
- name is not an Android strategy
- all three route through name
basics
~20 sNothing changes on iOS. XCUITest aliases id, name and accessibility id onto the same name attribute, so all three return the same element. On Android the swap changes the matched attribute entirely, and the results diverge.
solid answer
~40 sOn **Apple platforms** the swap is a no-op. The XCUITest driver declares `id`, `name` and `accessibility id` as separate strategy names, but all three resolve against the single `name` attribute, so the same value returns the same element whichever one you send. On **Android** the same swap is a real change: UiAutomator2's `id` matches the element's `resource-id` while `accessibility id` matches a different attribute set by different app code, and a value that works for one usually returns nothing for the other. That asymmetry is why cross-platform advice about "just use accessibility id" reads as harmless on iOS and consequential on Android — three strategies collapse into one on one platform and stay genuinely distinct on the other.
go deeper
Be ready to say that on iOS the id, name and accessibility id strategies all end up at the same attribute, so choosing between them there changes nothing.
Explain where the iOS name attribute comes from and why Android's two strategies stay distinct, and be able to state what a swap costs on each platform.
Show how you would prove the collapse on a real device rather than asserting it, and how you spot a suite whose convention was inherited from an iOS-first history.
Own the contract question: shared locators assert that two independent app-side fields agree, and you should be able to say who guarantees that and how it is enforced.
## The asymmetry in one sentence On **Apple platforms** three locator strategies point at one attribute; on **Android** the equivalent strategies point at genuinely different attributes. Everything else in this question follows from that. ## What XCUITest actually declares The XCUITest driver's native strategy list is longer than the Android one, and it includes `id`, `name` and `accessibility id` as three separate entries. Reading that list, it is natural to assume three matchers. There are not three: - `id` resolves against the element's `name` attribute. - `name` resolves against the element's `name` attribute. - `accessibility id` resolves against the element's `name` attribute. So the three are **spelling variants of one lookup**. Sending `accessibility id` instead of `id` with the same value produces the same request outcome, the same element, and the same failure when the value is absent. There is no fallback from one strategy to another, because there is nothing to fall back to — they were already the same comparison. Where does `name` come from? XCUITest computes it from the element's `accessibilityIdentifier`, the field app code sets explicitly for automation. When that field is empty, the driver falls back to the element's accessibility label, which is the user-facing, **localised** string. That fallback is the reason an iOS `id` lookup can pass in one language and fail in another, and it applies identically to all three strategy names because they are one matcher. ## What UiAutomator2 declares The Android side declares `id` and `accessibility id` too, and there they are **different matchers over different attributes**: - `id` compares against `resource-id`, the package-qualified identifier fixed in the app's build, for example `com.example.app:id/login_button`. - `accessibility id` compares against a separate accessibility attribute, populated by different app-side code and by no means guaranteed to hold the same string. So on Android the swap is a genuine change of target. A value that resolves under one strategy commonly returns nothing under the other, and that is not a bug — the two attributes are simply not the same field. ## Side by side | strategy | Android (UiAutomator2) | Apple platforms (XCUITest) | |---|---|---| | `id` | matches `resource-id` | alias for `name` | | `name` | not declared | matches `name` | | `accessibility id` | matches a separate accessibility attribute | alias for `name` | | effect of swapping `id` for `accessibility id` | different attribute, usually different result | no effect at all | | number of distinct matchers involved | two | one | ## Why this matters when you read someone else's suite 1. **An iOS-only suite gives you no signal.** If the team standardised on `accessibility id` while shipping iOS first, the choice was free there; it becomes a real requirement the moment Android is added, because a second app-side field now has to be populated. 2. **A green iOS run does not validate the Android locator.** The strategies collapse on one platform and not the other, so identical test code exercises different app-side contracts. 3. **"We use `name` everywhere" is an Apple-only sentence.** `name` is not on UiAutomator2's declared strategy list, so that convention cannot be carried across as written. 4. **The label fallback is a shared hazard of the collapsed matcher.** Because all three iOS names route through `name`, none of them is safe from silently matching a translated caption when app code left the identifier unset. ## How to check rather than assume - Fetch the live tree with `GET /session/:sessionId/source` on each platform and read what the element actually carries; the attribute names in the source are the ground truth for that device. - Try the same value under both strategies on Android. If one returns an element and the other does not, you have just proved the two attributes hold different content in that build. - When an iOS lookup succeeds, check whether the value you matched is also a visible caption. If it is, you may be riding the label fallback rather than a real identifier, and a translation will break it. - Keep the platform in the name of the locator constant. A constant that both runs share is asserting that two different app-side fields agree, which is a claim someone has to have verified. ## The one-line answer to give On Apple platforms `id`, `name` and `accessibility id` are three doors into one room, so swapping between them is cosmetic; on Android they are separate rooms, so swapping changes what you find. Anyone who says the strategies behave the same way on both platforms has generalised from whichever platform they shipped first.
- If the strategies are equivalent on iOS, why does XCUITest declare all three?For portability of client code. Suites written against Android or the browser reach for `id`, WebDriver clients expose `name`, and cross-platform helpers reach for `accessibility id`; accepting all three lets that code run unchanged. The convenience is real, but it hides the fact that only one attribute is ever consulted on this platform.
- Does the same collapse happen for `class name` on iOS?No. `class name` targets the element's `type`, an `XCUIElementType` value, and nothing else aliases onto it. The collapse is specific to the identifier-shaped strategies routing through `name`, which is why a locator that mixes an identifier and a type is doing two genuinely different lookups.
saying these in an interview costs you the question
- Says id and accessibility id differ on iOS too
- Expects a fallback from one strategy to another
- Uses the name strategy in an Android locator
- Assumes a green iOS run proves the Android locator
- Thinks the label fallback applies to only one of the three names