In what order do XCTest’s class and instance setup, teardown blocks and tearDown run, and what does continueAfterFailure change?

22.9.1 · L3 · Interview

Predict first

What order do class setUp, setUp, the body, two teardown blocks, tearDown and class tearDown run in, and which later lines run after a failed assertion?

// === Package.swift ===
// swift-tools-version:6.0
import PackageDescription
let package = Package(name: "Lib", targets: [.target(name: "Lib"), .testTarget(name: "LibTests", dependencies: ["Lib"])])
// === Sources/Lib/Lib.swift ===
public func square(_ x: Int) -> Int { x * x }
// === Tests/LibTests/T.swift ===
import XCTest
@testable import Lib
final class LifeTests: XCTestCase {
    override class func setUp() { print("ORDER class setUp") }
    override class func tearDown() { print("ORDER class tearDown") }
    override func setUpWithError() throws { print("ORDER setUp") }
    override func tearDownWithError() throws { print("ORDER tearDown") }
    func testOne() {
        addTeardownBlock { print("ORDER teardown block A") }
        addTeardownBlock { print("ORDER teardown block B") }
        print("ORDER body")
    }
}
final class ContinueTests: XCTestCase {
    func testKeepsGoing() {
        XCTAssertEqual(1, 2)
        print("ORDER after first failure (default)")
    }
    func testStops() {
        continueAfterFailure = false
        XCTAssertEqual(1, 2)
        print("ORDER after first failure (stopped)")
    }
    func testThrowsStops() throws {
        let x: Int? = nil
        let v = try XCTUnwrap(x)
        print("ORDER unreachable", v)
    }
}
  • class setUp, setUp, body, block B, block A, tearDown, class tearDown; the line after a failed assert runs by default but not with continueAfterFailure = false or after a failed XCTUnwrap
  • Blocks run in registration order
  • The line after a failed assertion never runs

Mental model. addTeardownBlock is like putting your coat on a peg when you arrive: when you leave you collect the last item first, which is also the first you can reach.

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 is created and setUpWithError() runs, then the test, then the teardown blocks registered with addTeardownBlock run in reverse order of registration (B before A in the check), and only after them tearDownWithError(). Teardown blocks are the right place for cleanup tied to something a test created (a temporary file), because they live next to the code that created it and still run when the test fails or throws. Prefer them to a growing tearDown.

By default a failed assertion does not stop the test: later lines still run (the check prints the line after a failed XCTAssertEqual), which is useful for seeing several failures but dangerous when the next line needs a value. Setting continueAfterFailure = false in the test (or in setUp) makes the first failure end it, and try XCTUnwrap(…) and any thrown error also end it. Swift Testing’s #expect and #require split the same choice into two macros (Q443). Keep shared fixtures in setUp small and per-test, because class-level state is shared by every test in the class.

Teardown blocks run last-in first-out before tearDownWithError; failures continue unless you opt out.

Common traps

  • Putting per-test state in class-level setUp. It is created once and shared, so tests influence one another.
  • Assuming a test stops at the first failed assertion. Without continueAfterFailure = false it keeps running, and later lines may crash.

They might follow up with

  • Does tearDown run when a test fails? Yes, and so do teardown blocks.
  • Where does XCTest run async setup? setUp() async throws is supported on the instance.

Related questions

  • 22.9.2 How do XCTestExpectation tests fail: timeouts, inverted expectations, ordering, over-fulfilment and…
  • 22.9.4 On which thread do tests run in Swift Testing, and how do you test code isolated to the main actor?
  • 22.2.1 How do XCTest and Swift Testing differ, and when do you still use XCTest?
  • 22.3.1 How do you test async code: async test functions, expectations, confirmations, actors and the main actor?

How do XCTestExpectation tests fail: timeouts, inverted expectations… →