Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you've just hired a professional "mystery shopper" to test your new retail store. You don't give them the blueprints of the building or the employee handbook. Instead, you tell them: "Walk through the front door, find the shoes section, pick up a pair of sneakers, and try to pay for them at the register." The shopper doesn't care how the inventory database works or how the credit card API is written; they only care that the door opens, the shoes are on the shelf, and the register actually takes their money.

That is exactly what UI Testing is in Swift. While unit tests look at the internal plumbing (the "blueprints"), UI tests treat your app as a black box. We use the XCUITest framework to simulate a "robot user" who interacts with the screen just like a human would.

Teaching the Robot to See

Before our robot user can tap a button, it needs to find it. In the world of XCUITest, we start with an instance of XCUIApplication. Think of this as the robot's eyes. To find a specific element, we use "queries."

Let's say we're testing a simple "Task Manager" app. We want to find a text field where the user types a task and a "Add" button. Here is how we map the analogy to the code:

let app = XCUIApplication()
app.launch()

// The robot looks for a text field labeled "Task Name"
let taskField = app.textFields["Task Name"]

// The robot looks for a button labeled "Add"
let addButton = app.buttons["Add"]

I'll give you a tip here: accessibility identifiers are your best friend. Relying on the actual text (like "Add") is risky because if you change the button to say "Submit" for a rebranding, your tests will break. If you set an accessibilityIdentifier in your source code, the robot can find the button regardless of what the label says.

Simulating Human Touch

Once the robot has found an element, it needs to do something with it. The XCUITest framework provides a set of methods that mimic human interaction. The most common are .tap(), .typeText(""), and .swipeUp().

Continuing with our Task Manager example, we want to simulate the entire process of adding a task. It looks like this:

let app = XCUIApplication()
app.launch()

let taskField = app.textFields["Task Name"]
taskField.tap() // Focus the field
taskField.typeText("Buy almond milk")

let addButton = app.buttons["Add"]
addButton.tap()

Notice how we have to .tap() the text field before we .typeText()? This is because the robot is literal. A human doesn't magically start typing into a field without clicking it first, and neither does the UI test runner.

Verifying the Result

Tapping buttons is useless if we aren't checking the outcome. In unit tests, you use XCTAssert to check values. In UI tests, you use it to check if an element exists or if its label changed.

If our Task Manager works, the text "Buy almond milk" should now appear in a list on the screen. We verify this by querying for a static text element with that exact value:

let resultText = app.staticTexts["Buy almond milk"]
XCTAssertTrue(resultText.exists, "The task should appear in the list after clicking Add.")

I'll be honest with you: UI tests are slower than unit tests and can occasionally be "flaky" (meaning they fail even when the code is correct, perhaps because an animation didn't finish in time). Because of this, you shouldn't test every single edge case here. Save the heavy lifting for your unit tests, and use UI tests for the "Happy Path"β€”the critical journeys that must work for the user to be successful.




πŸ“‹ Practical Task

The Login Flow Validation Test

You are tasked with writing a UI test for a Login screen. The screen contains two text fields (one for "Username" and one for "Password") and a button labeled "Login". When the login is successful, the app navigates to a dashboard that displays a label saying "Welcome Back!".

Create a test function that performs the following sequence:

  • Launches the app using XCUIApplication().
  • Finds the username field and types "swift_dev".
  • Finds the password field and types "password123".
  • Taps the "Login" button.
  • Asserts that a static text element with the value "Welcome Back!" now exists on the screen.

Note: Assume the accessibilityIdentifier for the fields matches their labels ("Username" and "Password").

Rating
0 0

There are no comments for now.

to be the first to leave a comment.