Use when testing async code with Swift Testing. Covers confirmation for callbacks, @MainActor tests, async/await patterns, timeout control, XCTest migration, parallel test execution.
View on GitHubSelect agents to install to:
npx add-skill https://github.com/CharlesWiltgen/Axiom/blob/main/.claude-plugin/plugins/axiom/skills/axiom-testing-async/SKILL.md -a claude-code --skill axiom-testing-asyncInstallation paths:
.claude/skills/axiom-testing-async/# Testing Async Code — Swift Testing Patterns
Modern patterns for testing async/await code with Swift Testing framework.
## When to Use
✅ **Use when:**
- Writing tests for async functions
- Testing callback-based APIs with Swift Testing
- Migrating async XCTests to Swift Testing
- Testing MainActor-isolated code
- Need to verify events fire expected number of times
❌ **Don't use when:**
- XCTest-only project (use XCTestExpectation)
- UI automation tests (use XCUITest)
- Performance testing with metrics (use XCTest)
## Key Differences from XCTest
| XCTest | Swift Testing |
|--------|---------------|
| `XCTestExpectation` | `confirmation { }` |
| `wait(for:timeout:)` | `await confirmation` |
| `@MainActor` implicit | `@MainActor` explicit |
| Serial by default | **Parallel by default** |
| `XCTAssertEqual()` | `#expect()` |
| `continueAfterFailure` | `#require` per-expectation |
## Patterns
### Pattern 1: Simple Async Function
```swift
@Test func fetchUser() async throws {
let user = try await api.fetchUser(id: 1)
#expect(user.name == "Alice")
}
```
### Pattern 2: Completion Handler → Continuation
For APIs without async overloads:
```swift
@Test func legacyAPI() async throws {
let result = try await withCheckedThrowingContinuation { continuation in
legacyFetch { result, error in
if let result {
continuation.resume(returning: result)
} else {
continuation.resume(throwing: error!)
}
}
}
#expect(result.isValid)
}
```
### Pattern 3: Single Callback with confirmation
When a callback should fire exactly once:
```swift
@Test func notificationFires() async {
await confirmation { confirm in
NotificationCenter.default.addObserver(
forName: .didUpdate,
object: nil,
queue: .main
) { _ in
confirm() // Must be called exactly once
}
triggerUpdate()
}
}
```
### Pattern 4: Multip