xiaohongshu
xiaohongshu
axiom-testing-async
Use when testing async code with Swift Testing. Covers confirmation for callbacks, @MainActor tests, async/await patterns, timeout control, XCTest migration, parallel test execution.
Full skill instructions
Modern patterns for testing async/await code with Swift Testing framework.
✅ Use when:
❌ Don't use when:
| 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 |
@Test func fetchUser() async throws {
let user = try await api.fetchUser(id: 1)
#expect(user.name == "Alice")
}
For APIs without async overloads:
@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)
}
When a callback should fire exactly once:
@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()
}
}
@Test func delegateCalledMultipleTimes() async {
await confirmation(expectedCount: 3) { confirm in
delegate.onProgress = { progress in
confirm() // Called 3 times
}
startDownload() // Triggers 3 progress updates
}
}
@Test func noErrorCallback() async {
await confirmation(expectedCount: 0) { confirm in
delegate.onError = { _ in
confirm() // Should never be called
}
performSuccessfulOperation()
}
}
@Test @MainActor func viewModelUpdates() async {
let vm = ViewModel()
await vm.load()
#expect(vm.items.count > 0)
#expect(vm.isLoading == false)
}
@Test(.timeLimit(.seconds(5)))
func slowOperation() async throws {
try await longRunningTask()
}
@Test func invalidInputThrows() async throws {
await #expect(throws: ValidationError.self) {
try await validate(input: "")
}
}
// Specific error
@Test func specificError() async throws {
await #expect(throws: NetworkError.notFound) {
try await api.fetch(id: -1)
}
}
@Test func firstVideo() async throws {
let videos = try await videoLibrary.videos()
let first = try #require(videos.first) // Fails if nil
#expect(first.duration > 0)
}
@Test("Video loading", arguments: [
"Beach.mov",
"Mountain.mov",
"City.mov"
])
func loadVideo(fileName: String) async throws {
let video = try await Video.load(fileName)
#expect(video.isPlayable)
}
Arguments run in parallel automatically.
Swift Testing runs tests in parallel by default (unlike XCTest).
// ❌ Shared mutable state — race condition
var sharedCounter = 0
@Test func test1() async {
sharedCounter += 1 // Data race!
}
@Test func test2() async {
sharedCounter += 1 // Data race!
}
// ✅ Each test gets fresh instance
struct CounterTests {
var counter = Counter() // Fresh per test
@Test func increment() {
counter.increment()
#expect(counter.value == 1)
}
}
When tests must run sequentially:
@Suite("Database tests", .serialized)
struct DatabaseTests {
@Test func createRecord() async { /* ... */ }
@Test func readRecord() async { /* ... */ } // After create
@Test func deleteRecord() async { /* ... */ } // After read
}
Note: Other unrelated tests still run in parallel.
// ❌ Flaky — arbitrary wait time
@Test func eventFires() async {
setupEventHandler()
try await Task.sleep(for: .seconds(1)) // Hope it happened?
#expect(eventReceived)
}
// ✅ Deterministic — waits for actual event
@Test func eventFires() async {
await confirmation { confirm in
onEvent = { confirm() }
triggerEvent()
}
}
// ❌ Data race — ViewModel may be MainActor
@Test func viewModel() async {
let vm = ViewModel()
await vm.load() // May cause data race warnings
}
// ✅ Explicit isolation
@Test @MainActor func viewModel() async {
let vm = ViewModel()
await vm.load()
}
// ❌ Test passes immediately — doesn't wait for callback
@Test func callback() async {
api.fetch { result in
#expect(result.isSuccess) // Never executed before test ends
}
}
// ✅ Waits for callback
@Test func callback() async {
await confirmation { confirm in
api.fetch { result in
#expect(result.isSuccess)
confirm()
}
}
}
// ❌ Tests interfere with each other
@Test func writeFile() async {
try! "data".write(to: sharedFileURL, atomically: true, encoding: .utf8)
}
@Test func readFile() async {
let data = try! String(contentsOf: sharedFileURL) // May fail!
}
// ✅ Use unique files or .serialized
@Test func writeAndRead() async {
let url = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString)
try! "data".write(to: url, atomically: true, encoding: .utf8)
let data = try! String(contentsOf: url)
#expect(data == "data")
}
// XCTest
func testFetch() {
let expectation = expectation(description: "fetch")
api.fetch { result in
XCTAssertNotNil(result)
expectation.fulfill()
}
wait(for: [expectation], timeout: 5)
}
// Swift Testing
@Test func fetch() async {
await confirmation { confirm in
api.fetch { result in
#expect(result != nil)
confirm()
}
}
}
// XCTest
class MyTests: XCTestCase {
var service: Service!
override func setUp() async throws {
service = try await Service.create()
}
}
// Swift Testing
struct MyTests {
let service: Service
init() async throws {
service = try await Service.create()
}
@Test func example() async {
// Use self.service
}
}
WWDC: 2024-10179, 2024-10195
Docs: /testing, /testing/confirmation
Skills: axiom-swift-testing, axiom-ios-testing
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience