Thuta Learning
AdvancedMobile Developmentintermediate

Testing iOS Apps (XCTest)

Relax. We'll talk through this in plain words — no textbook voice.

What you'll walk away with

  • Understand Testing iOS Apps (XCTest) with nothing to be intimidated by
  • Get comfortable running Xcode/SwiftUI code yourself
  • Be able to apply this concept in a real project right away

Let's think about it this way for a second

A unit test tests an individual function/class (ViewModel logic, data transformation) without needing UI/device — it uses the XCTest framework (built into Xcode), runs fast, and can run frequently in a CI pipeline. A UI test (XCUITest), on the other hand, automates actual UI interaction (button taps, text input) on the Simulator — you can use `XCUIApplication` to verify things like 'does the text change when I tap this button'.

Let's connect this to a real-world scenario

To unit test the logic of `TodoViewModel.addTodo()`, you could write `func testAddTodo_increasesListSize() { viewModel.addTodo(title: "Test"); XCTAssertEqual(viewModel.todos.count, 1) }` — for a UI test, you could write `app.buttons["Add"].tap(); XCTAssertTrue(app.staticTexts["Test"].exists)` to verify that the todo item actually shows up on screen after tapping the button.

Let's look at it together

swift
// Unit test
import XCTest
@testable import MyApp

final class TodoViewModelTests: XCTestCase {
    func testAddTodo_increasesListSize() {
        let viewModel = TodoViewModel()
        viewModel.addTodo(title: "Buy milk")
        XCTAssertEqual(viewModel.todos.count, 1)
    }
}

// UI test
final class TodoAppUITests: XCTestCase {
    func testTappingAddButton_showsNewTodo() {
        let app = XCUIApplication()
        app.launch()
        app.buttons["Add"].tap()
        XCTAssertTrue(app.staticTexts["Buy milk"].exists)
    }
}
You should see
$ xcodebuild test
Test Suite 'All tests' passed — 2 tests, 0 failures

5-minute try-it

Write a unit test yourself for `TodoViewModel`'s `addTodo()` function, and run it with Xcode's 'Run Test' (◇ icon) button.

A quick heads-up

Don't aim for 100% test coverage — prioritize testing critical business logic (payment, data integrity); tests for UI details (color, spacing) tend to have a low ROI.

Easy traps

  • Putting off tests with 'I'll write them after the code is done' — as features pile up, manual re-testing takes longer and longer
  • Running UI tests directly against the real network/database — tests can become flaky (passing sometimes, failing other times); you should use a fake/mock dependency instead

Now try it yourself

Write a unit test yourself for `TodoViewModel`'s `addTodo()` function, and run it with Xcode's 'Run Test' (◇ icon) button.

You'll know it worked when: $ xcodebuild test Test Suite 'All tests' passed — 2 tests, 0 failures

Testing iOS Apps (XCTest) | Thuta Learning