22.9 · XCTest lifecycle and expectations, Sendable doubles, and the main actor in tests
Details the first pass skipped: the exact order of XCTest’s lifecycle, how expectations fail, how to write test doubles that compile in Swift 6, and which thread a test runs on.
Mental model. A test is a small program with a lifecycle, a thread and an isolation domain. Most mystifying failures come from not knowing one of the three.
XCTest mechanics
Lifecycle order and how expectations fail.
- In what order do XCTest’s class and instance setup, teardown blocks and
tearDownrun, and what doescontinueAfterFailurechange?
For a test class, override class func setUp() runs once before the first test and class func tearDown() once after the last. For each test method an instance… - How do
XCTestExpectationtests fail: timeouts, inverted expectations, ordering, over-fulfilment and forgetting to wait?
Each way an expectation goes wrong has its own message, and they are worth recognising. A timeout reports “Asynchronous wait failed: Exceeded timeout of 0.1…
Concurrency in tests
Sendable doubles and where a test runs.
- Why does a hand-written spy fail to compile in Swift 6 when a protocol is
Sendable, and how do you write doubles that are safe?
Test doubles are usually classes that mutate recorded calls, and they are passed into code that may call them from several tasks. In Swift 6 language mode a… - On which thread do tests run in Swift Testing, and how do you test code isolated to the main actor?
In Swift Testing, a plain test function is not run on the main thread: both a synchronous and an async plain test reported they were off the main thread in the…
More in Testing
- 22.1 · The pyramid, and what not to test
- 22.2 · XCTest and Swift Testing
- 22.3 · Async tests, expectations and controlling time
- 22.4 · Fakes, mocks and the inputs that make tests random
- 22.5 · Snapshot tests and UI tests
- 22.6 · Testing SwiftUI, tvOS focus, and watchOS logic
- 22.7 · Flakes, hermetic CI, and a quality system for a large team
- 22.8 · Swift Testing in depth: arguments, traits, errors, confirmations, isolation and scoping