一键导入
swift-testing
Use when writing tests with Swift Testing (@Test,
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when writing tests with Swift Testing (@Test,
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when building features with TCA (The Composable Architecture), structuring reducers, managing state, handling effects, navigation, or testing TCA features. Covers @Reducer, Store, Effect, TestStore, reducer composition, and TCA patterns.
Use when implementing iOS 26 features (Liquid Glass, new SwiftUI APIs, WebView, Chart3D), deploying iOS 26+ apps, or supporting backward compatibility with iOS 17/18.
Use when implementing iOS 17+ SwiftUI patterns: @Observable/@Bindable, MVVM architecture, NavigationStack, lazy loading, UIKit interop, accessibility (VoiceOver/Dynamic Type), async operations (.task/.refreshable), or migrating from ObservableObject/@StateObject.
Use when writing async/await code, enabling strict concurrency, fixing Sendable errors, migrating from completion handlers, managing shared state with actors, or using Task/TaskGroup for concurrency.
Use when implementing on-device AI with Apple's Foundation Models framework (iOS 26+), building summarization/extraction/classification features, or using @Generable for type-safe structured output.
Use when writing raw SQL with GRDB, complex joins across 4+ tables, window functions, ValueObservation for reactive queries, or dropping down from SQLiteData for performance. Direct SQLite access for iOS/macOS with type-safe queries and migrations.
| name | swift-testing |
| description | Use when writing tests with Swift Testing (@Test, |
Modern testing with Swift Testing framework. No XCTest.
Swift Testing replaces XCTest with a modern macro-based approach that's more concise, has better async support, and runs tests in parallel by default. The core principle: if you learned XCTest, unlearn it—Swift Testing works differently.
| Macro | Use Case |
|---|---|
#expect(expression) | Soft check — continues on failure. Use for most assertions. |
#require(expression) | Hard check — stops test on failure. Use for preconditions only. |
let user = try #require(await fetchUser(id: "123"))
#expect(user.id == "123")
import Testing
@testable import YourModule
@Suite
struct FeatureTests {
let sut: FeatureType
init() throws {
sut = FeatureType()
}
@Test("Description of behavior")
func testBehavior() {
#expect(sut.someProperty == expected)
}
}
| XCTest | Swift Testing |
|---|---|
XCTAssert(expr) | #expect(expr) |
XCTAssertEqual(a, b) | #expect(a == b) |
XCTAssertNil(a) | #expect(a == nil) |
XCTAssertNotNil(a) | #expect(a != nil) |
try XCTUnwrap(a) | try #require(a) |
XCTAssertThrowsError | #expect(throws: ErrorType.self) { } |
XCTAssertNoThrow | #expect(throws: Never.self) { } |
#expect(throws: (any Error).self) { try riskyOperation() }
#expect(throws: NetworkError.self) { try fetch() }
#expect(throws: NetworkError.timeout) { try fetch() }
#expect(throws: Never.self) { try safeOperation() }
@Test("Validates inputs", arguments: zip(
["a", "b", "c"],
[1, 2, 3]
))
func testInputs(input: String, expected: Int) {
#expect(process(input) == expected)
}
Warning: Multiple collections WITHOUT zip creates Cartesian product.
@Test func testAsync() async throws {
let result = try await fetchData()
#expect(!result.isEmpty)
}
@Test func testCallback() async {
await confirmation("callback received") { confirm in
let sut = SomeType { confirm() }
sut.triggerCallback()
}
}
extension Tag {
@Tag static var fast: Self
@Tag static var networking: Self
}
@Test(.tags(.fast, .networking))
func testNetworkCall() { }
#require — Use #expect for most checkszip for paired inputs.serialized — Apply for thread-unsafe legacy testsOverusing #require — #require is for preconditions only. Using it for normal assertions means the test stops at first failure instead of reporting all failures. Use #expect for assertions, #require only when subsequent assertions depend on the value.
Cartesian product bugs — @Test(arguments: [a, b], [c, d]) creates 4 combinations, not 2. Always use zip to pair arguments correctly: arguments: zip([a, b], [c, d]).
Forgetting state isolation — Swift Testing creates a new test instance per test method. BUT shared state between tests (static variables, singletons) still leak. Use dependency injection or clean up singletons between tests.
Parallel test conflicts — Swift Testing runs tests in parallel by default. Tests touching shared files, databases, or singletons will interfere. Use .serialized or isolation strategies.
Not using async naturally — Wrapping async operations in Task { } defeats the purpose. Use async/await directly in test function signature: @Test func testAsync() async throws { }.
Confirmation misuse — confirmation is for verifying callbacks were called. Using it for assertions is wrong. Use #expect for assertions, confirmation for callback counts.