Skip to content
tezvyn:
Menu

Locating XCUITest elements without accessibility identifiers

Source: interviewMediumHow cards are made

Summary

navigating the element query hierarchy.

Key points

query by type, label, predicate, or index; chain queries to narrow scope.

Watch out for

relying on brittle absolute indices or visible label text that breaks under localization and layout changes.

What's really being asked

The interviewer wants to see that you understand the XCUIElement query model and can still automate a screen that was not built with testing in mind, while recognizing that this is a workaround, not a best practice.

The full answer

XCUITest exposes elements through XCUIElementQuery. You can filter by element type such as app.buttons or app.staticTexts, then narrow by visible label like app.buttons["Continue"], by NSPredicate with matching(_:) for partial or case-insensitive matches, or by position using element(boundBy:). Crucially you should scope the query to a parent, for example app.cells.element(boundBy: 0).buttons.firstMatch, so the search is constrained and less ambiguous. You can also use firstMatch to short-circuit the query for performance.

The mistakes people make

Defaulting to absolute indices that break the moment content reorders, or matching on user-facing text that changes under localization or copy edits. Querying the whole app tree repeatedly is also slow because each query resolves the full element snapshot.

What usually comes next

Why are accessibility identifiers preferable? How do identifiers help users with assistive technology as well as tests? How would you persuade the team to add identifiers, and where do you set them in SwiftUI versus UIKit?

A concrete example

A settings row has no identifier. You write let row = app.tables.cells.containing(.staticText, identifier: nil).element(boundBy: 2) which is fragile. A better stopgap is app.cells.staticTexts["Notifications"].firstMatch, but the durable fix is to set accessibilityIdentifier("settings.notifications.row") in code so the test reads app.cells["settings.notifications.row"]. Identifiers are invisible to users, immune to localization, and form a stable contract between code and tests, which is why they beat label and index queries.

Interview question

Why is matching an element by its visible label text considered more brittle than using an accessibility identifier?

  • a.Accessibility identifiers are slower to resolve than labels
  • b.Visible text changes with localization and copy edits, breaking the queryCorrect
  • c.Labels can only be read after the element is tapped once
  • d.Label queries are not supported on physical devices
Why?

Visible labels change across languages and copy revisions, so label-based queries break easily, while identifiers are stable and hidden from users. Identifiers are not slower, and label queries work on real devices.

Just read this? Test yourself on what you have been reading.

Read the original → developer.apple.com

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on ios — each one lists the topics its interview covers.

See open roles