22.3 · Async tests, expectations and controlling time
Asynchronous code is where tests get slow and flaky: a sleep that is sometimes too short, a callback that never arrives. The cure is to wait on events, never on time, and to make time itself something the test controls.
Mental model. Await the thing, do not sleep for it. And whenever the code under test waits on a clock, give it a clock you can move by hand.
Waiting
Async test functions, expectations and confirmations.
- How do you test async code: async test functions, expectations, confirmations, actors and the main actor?
If the code under test is async, make the test async and await it: both XCTest and Swift Testing accept async throws test functions, so there is nothing to…
Time
Injectable clocks, debouncing and timeouts.
- How do you test code that depends on time: debounce, timeouts, retries and expiry?
Code that waits on real time is slow to test and flaky, because a one-second debounce costs a second and a 10 ms margin is sometimes missed. The fix is…
More in Testing
- 22.1 · The pyramid, and what not to test
- 22.2 · XCTest and Swift Testing
- 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
- 22.9 · XCTest lifecycle and expectations, Sendable doubles, and the main actor in tests