पाठ 23 / 25
Testing with Swift Testing and XCTest
Write unit tests with the Swift Testing framework and XCTest.
Tests for Swift code
Swift has two testing frameworks. Swift Testing, introduced in 2024 with Xcode 16 and Swift 6, uses modern language features: import Testing, functions marked with @Test, expectations with the #expect(...) macro (which shows the values of sub-expressions when it fails) and #require(...) to stop a test when a precondition fails (for example unwrapping an optional). Tests can be parameterised with arguments:, grouped in suites (types marked @Suite), tagged, and run in parallel by default. XCTest is the long-standing framework (XCTestCase subclasses, XCTAssertEqual and friends) and is still required for UI tests and performance tests; the two can coexist in one project. Both support async tests. Use @testable import to test internal code. Make code testable with protocols for dependencies (a PaymentGateway protocol with a fake in tests), value-type models and pure functions. Run tests with Xcode's test navigator, swift test, or xcodebuild test in CI.
Swift Testing with parameterised cases and an async test
#expect shows values on failure; #require stops early.
import Testing
@testable import Pricing
@Suite("Shipping fees")
struct ShippingFeeTests {
@Test("Fee depends on total and speed", arguments: [
(totalPaise: 99_999, express: false, expected: 4_900),
(totalPaise: 99_999, express: true, expected: 9_900),
(totalPaise: 100_000, express: true, expected: 0),
])
func fee(totalPaise: Int, express: Bool, expected: Int) {
#expect(ShippingCalculator().feePaise(total: totalPaise, express: express) == expected)
}
@Test func parsesAmount() throws {
let money = try #require(Money(rupees: "499.00")) // fails the test if nil
#expect(money.paise == 49_900)
}
@Test func checkoutChargesOnce() async throws {
let gateway = FakePaymentGateway()
let checkout = Checkout(gateway: gateway)
_ = try await checkout.pay(orderId: "o-1", amountPaise: 49_900)
#expect(gateway.charges.count == 1)
}
}An inspector who shows the measurements
A plain assertion says "failed". #expect is an inspector who writes down every measurement: "fee was 9900, expected 4900, total was 99999", so you know immediately what went wrong.
त्वरित जाँच: In the Swift Testing framework, which macro checks a condition and reports sub-expression values on failure?
- XCTAssertTrue
- #expect
- @Test
- @testable
Answer
#expect — #expect is Swift Testing's primary expectation macro.