Swift Testing
Add the SPM package and depend on TraceraTesting:
.package(url: "https://github.com/tracera-dev/tracera-swift.git", from: "0.1.0"),
// …
.product(name: "TraceraTesting", package: "tracera-swift"),
Requires Swift ≥ 6 (macOS 15 / Xcode 16; see Autotest adapters).
Environment variables and run mode: Autotest adapters.
Bind testCaseId and autotestName
Preferred declarative bind:
@Test("checkout", .traceraId(42))
func checkout() {
// …
}
@Test("login as {user}", .traceraId(42), arguments: ["alice", "bob"])
func login(user: String) {
// …
}
When the id is not a compile-time constant, open a pin with .tracera and bind imperatively:
@Test("checkout", .tracera)
func checkout() {
Tracera.testCase(42)
// Tracera.testCase(42, "e2e/checkout")
}
Skip
Use skip("reason") so the reason is added to the result as comment:
@Test("checkout", .traceraId(42))
func checkout() throws {
try skip("needs a seeded account")
}
Steps
Use Tracera.step("…") { … } (sync or async). Steps inside setup / teardown go to Setup / Teardown; other steps go to Test.
@Test("checkout", .traceraId(10))
func checkout() throws {
try setup("open shop") {}
try Tracera.step("add item") {
Tracera.step("nested leaf") {}
}
try teardown("close shop") {}
}
Comments, errors, and attachments
Limits and allowed MIME types: Autotest adapters.
Tracera.comment, Tracera.error, and attachments are added to the open step, or to the result when no step is open. Tracera.attachmentFile takes a file path; Tracera.attachmentBytes takes a name and bytes (MIME type is optional). Attachments upload when the result is reported.
Tracera.comment("result-level note")
Tracera.error("result-level error")
Tracera.attachmentFile("Fixtures/screenshot.png")
Tracera.step("open login") {
Tracera.comment("step note")
Tracera.attachmentBytes("body.json", data: Data(#"{"ok":true}"#.utf8), mimeType: "application/json")
}
If you start a Task and call Tracera APIs there (steps, comments, errors, attachments), call getContext() in the test first and run the worker with runWithContext — otherwise those calls are not reported:
let ctx = getContext()
Task {
await runWithContext(ctx) {
Tracera.step("worker") { /* ... */ }
}
}
Parameterized
Each arguments row is a separate case. Put placeholders such as {user} or {0} in the @Test("…") title, or in .traceraId(…, name:), so each row gets its own autotestName:
@Test("login as {user}", .traceraId(7), arguments: ["alice", "bob"])
func login(user: String) {
Tracera.step("sign in") { /* ... */ }
}