DEV Community

Cover image for XCUITest Assertions: Validating iOS App Behavior
QAPulse by SK
QAPulse by SK

Posted on Originally published at skakarh.com

XCUITest Assertions: Validating iOS App Behavior

XCUITest Assertions are the validation layer that determines whether an iOS application behaves as expected during automated UI testing. After an interaction such as tapping a button, entering text, or submitting a form, assertions verify the resulting UI state, element properties, values, and application behavior.

What are XCUITest Assertions?

XCUITest assertions use XCTest assertion APIs to compare expected application behavior with the actual state observed through XCUITest.

A typical test follows this architecture:

Launch Application
       ↓
Locate XCUIElement
       ↓
Perform Action
       ↓
Observe UI State
       ↓
XCUITest Assertion
       ↓
Pass / Fail
Enter fullscreen mode Exit fullscreen mode

For example:

let app = XCUIApplication()

let loginButton =
    app.buttons["login.submitButton"]

loginButton.tap()

let dashboard =
    app.staticTexts["Dashboard"]

XCTAssertTrue(
    dashboard.waitForExistence(timeout: 10)
)
Enter fullscreen mode Exit fullscreen mode

The interaction alone does not prove that login succeeded.

The assertion provides the validation.

Definition

XCUITest assertions are XCTest-based validation statements used to verify UI elements, values, states, visibility, existence, and expected application behavior during iOS UI automation.

Key Points

  • Assertions validate test outcomes.
  • XCTAssertTrue validates a Boolean condition.
  • XCTAssertFalse validates that a condition is false.
  • XCTAssertEqual compares expected and actual values.
  • XCTAssertNotEqual validates that two values differ.
  • XCTAssertNil validates that a value is nil.
  • XCTAssertNotNil validates that a value exists.
  • exists validates an element’s presence in the UI hierarchy.
  • isHittable helps validate whether an element can receive interaction.
  • Element values can be validated through value.
  • Assertions should validate behavior, not merely implementation details.
  • Every important user action should lead to a meaningful verification.

Why Assertions Matter in iOS UI Testing

A UI automation script without assertions can execute successfully while the application behaves incorrectly.

Consider:

loginButton.tap()
Enter fullscreen mode Exit fullscreen mode

The tap may complete without an automation error even if:

  • Login fails.
  • The wrong screen opens.
  • An error message appears.
  • The button triggers no action.
  • The application remains on the login screen.

A meaningful assertion detects the expected outcome:

loginButton.tap()

XCTAssertTrue(
    app.staticTexts["Dashboard"]
        .waitForExistence(timeout: 10)
)
Enter fullscreen mode Exit fullscreen mode

The test now validates application behavior rather than merely executing a sequence of gestures.

Common XCUITest Assertion Types

The appropriate assertion depends on what the test is trying to prove.

1. Validating Element Existence

One of the most common validations is checking whether an element exists.

let app = XCUIApplication()

let welcomeTitle =
    app.staticTexts["Welcome"]

XCTAssertTrue(
    welcomeTitle.exists
)
Enter fullscreen mode Exit fullscreen mode

This verifies that the element is currently present in the accessibility hierarchy.

For dynamic screens, use synchronization:

XCTAssertTrue(
    welcomeTitle.waitForExistence(timeout: 10)
)
Enter fullscreen mode Exit fullscreen mode

This is generally stronger than immediately checking exists when the screen may take time to load.

2. Validating Element Absence

Sometimes the expected behavior is that an element disappears.

For example, after successful login:

loginButton.tap()

XCTAssertFalse(
    loginButton.exists
)
Enter fullscreen mode Exit fullscreen mode

A disappearing loading indicator can also be validated:

XCTAssertFalse(
    app.activityIndicators["loading.indicator"].exists
)
Enter fullscreen mode Exit fullscreen mode

The important distinction is that the assertion represents an expected state transition.

Before Action
     ↓
Loading Indicator Exists
     ↓
Submit / Load
     ↓
Loading Indicator Disappears
     ↓
Assertion
Enter fullscreen mode Exit fullscreen mode

3. Validating Hittability

An element may exist but not be interactable.

let checkoutButton =
    app.buttons["checkout.payButton"]

XCTAssertTrue(
    checkoutButton.exists
)

XCTAssertTrue(
    checkoutButton.isHittable
)
Enter fullscreen mode Exit fullscreen mode

This is useful for validating UI state before an interaction.

For example:

XCTAssertTrue(
    checkoutButton.waitForExistence(timeout: 10)
)

XCTAssertTrue(
    checkoutButton.isHittable
)

checkoutButton.tap()
Enter fullscreen mode Exit fullscreen mode

This provides a clear interaction contract.

4. Validating Text

Text validation is essential for confirming messages, labels, titles, and status information.

let title =
    app.staticTexts["profile.title"]

XCTAssertEqual(
    title.label,
    "Profile"
)
Enter fullscreen mode Exit fullscreen mode

For dynamic text:

let message =
    app.staticTexts["payment.successMessage"]

XCTAssertEqual(
    message.label,
    "Payment successful"
)
Enter fullscreen mode Exit fullscreen mode

When the exact text is part of the acceptance criteria, exact equality is appropriate.

For dynamic content, avoid over-constraining the test.

5. Validating Text Field Values

Text fields can be validated through their value.

let emailField =
    app.textFields["login.emailField"]

emailField.tap()
emailField.typeText("qa@example.com")

XCTAssertEqual(
    emailField.value as? String,
    "qa@example.com"
)
Enter fullscreen mode Exit fullscreen mode

This verifies that the expected data reached the UI control.

For secure text fields:


👉 Continue reading the full article on skakarh.com →

Originally published at skakarh.com/xcuitest-assertions.
Subscribe to QA Pulse by SK
weekly signal for QA, Test Automation and AI in Software Engineering.

Top comments (0)