tezvyn:

Locating XCUITest elements without accessibility identifiers

AI-drafted, machine-checkedSource: interviewintermediate
WHAT IT TESTS

navigating the element query hierarchy.

OUTLINE

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

RED FLAG

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

WHAT THIS TESTS 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.

A GOOD ANSWER COVERS 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.

COMMON WRONG ANSWERS 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.

LIKELY FOLLOW-UPS 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?

ONE 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.

Read the original → developer.apple.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.