with one click
swift-testing
// Expert guidance on Swift Testing for writing, reviewing, migrating, and debugging tests. Use when developers mention Swift Testing, @Test, @Suite,
// Expert guidance on Swift Testing for writing, reviewing, migrating, and debugging tests. Use when developers mention Swift Testing, @Test, @Suite,
Operate the Ducko XMPP CLI tool. Use when asked to send XMPP messages, start an interactive XMPP session, list accounts, check roster, view history, manage presence, or test the CLI. Covers running commands, authentication, output formats, and all subcommands.
End-to-end UI testing for the Ducko macOS app using pre-built helper scripts. This skill should be used when the user asks to "test ducko", "test the app", "run E2E tests", "test the app end-to-end", "test the UI", "send a test message", or wants to verify DuckoApp works from login through messaging.
Scaffold, build, and package SwiftPM-based macOS apps without an Xcode project. Use when you need a from-scratch macOS app layout, SwiftPM targets/resources, a custom .app bundle assembly script, or signing/notarization/appcast steps outside Xcode.
Background-safe macOS app UI testing using Peekaboo CLI and osascript. This skill should be used when the user asks to "test the app UI", "check the UI", "interact with the running app", "take a screenshot of the app", "fill in the form", "click the button", "verify the UI state", "automate the app", or wants to automate interaction with a running macOS application without stealing keyboard/mouse focus from the user.
Use when working with iOS/macOS Keychain Services (SecItem queries, kSecClass, OSStatus errors), biometric authentication (LAContext, Face ID, Touch ID), CryptoKit (AES-GCM, ChaChaPoly, ECDSA, ECDH, HPKE, ML-KEM), Secure Enclave, secure credential storage (OAuth tokens, API keys), certificate pinning (SecTrust, SPKI), keychain sharing across apps/extensions, migrating secrets from UserDefaults or plists, or OWASP MASVS/MASTG mobile compliance on Apple platforms.
Expert guidance on Swift Concurrency correctness, modern API usage, and async/await pitfalls in Swift 6.2+. Use when developers mention async/await, actors, tasks, @MainActor, Sendable, isolation, Swift 6 migration, strict concurrency diagnostics, AsyncSequence/AsyncStream, async_without_await lint warnings, or data-race issues.
| name | swift-testing |
| description | Expert guidance on Swift Testing for writing, reviewing, migrating, and debugging tests. Use when developers mention Swift Testing, @Test, @Suite, |
| license | MIT |
Write and review Swift Testing code for correctness, modern API usage, and adherence to project conventions. Report only genuine problems — do not nitpick or invent issues.
Before diving in, clarify the goal and collect minimal facts:
Branch quickly:
If doing partial work, load only the relevant reference files.
XCUIApplication on XCTest. Also keep XCTMetric performance tests and Objective-C-only test code on XCTest.Testing in test targets, never in app/library/binary targets.#expect as the default assertion; use #require when subsequent lines depend on a prerequisite value or when you need hard-stop semantics..serialized..enabled, .disabled, .timeLimit, .bug, tags) over naming conventions or ad-hoc comments.@available on test functions for OS-gated behavior instead of runtime #available checks inside test bodies; never annotate suite types with @available.Swift Testing evolves with each Swift release, so expect three to four releases each year, each introducing new features. Training data will naturally be outdated. Treat the user's installed toolchain as authoritative, but note that Apple's documentation about the APIs is often stale — handle it carefully.
@Test, #expect, #require, @Suite) for all new tests, not XCTest.#if DEBUG, not in test targets.#if DEBUG, not in test targets.#expect for soft assertions (continue on failure) and #require for hard assertions (stop on failure).| Principle | Description | Application |
|---|---|---|
| Fast | Tests execute in milliseconds | Mock expensive operations |
| Isolated | Tests don't depend on each other | Fresh instance per test |
| Repeatable | Same result every time | Mock dates, network, external deps |
| Self-Validating | Auto-report pass/fail | Use #expect, never rely on print() |
| Timely | Write tests alongside code | Use parameterized tests for edge cases |
| Type | Purpose | Verification |
|---|---|---|
| Dummy | Fill parameters, never used | N/A |
| Fake | Working implementation with shortcuts | State |
| Stub | Provides canned answers | State |
| Spy | Records calls for verification | State |
| SpyingStub | Stub + Spy combined (most common) | State |
| Mock | Pre-programmed expectations, self-verifies | Behavior |
Place doubles close to the interface they implement, not in test targets:
public protocol RepositoryProtocol: Sendable {
func getAll() async throws -> [Record]
func save(_ record: Record) async throws
}
#if DEBUG
public final class RepositorySpyingStub: RepositoryProtocol {
// Spy: captured calls
public private(set) var savedRecords: [Record] = []
// Stub: configurable responses
public var recordsToReturn: [Record] = []
public var errorToThrow: Error?
public func getAll() async throws -> [Record] {
if let errorToThrow { throw errorToThrow }
return recordsToReturn
}
public func save(_ record: Record) async throws {
if let errorToThrow { throw errorToThrow }
savedRecords.append(record)
}
}
#endif
Place fixtures next to the model with #if DEBUG guards:
#if DEBUG
extension Record {
public static func fixture(
id: UUID = UUID(),
value: Double = 100.0
) -> Record {
Record(id: id, value: value)
}
}
#endif
For full patterns see references/test-doubles.md and references/fixtures.md.
+-------------+
| UI Tests | 5% - End-to-end flows
| (E2E) |
+-------------+
| Integration | 15% - Module interactions
| Tests |
+-------------+
| Unit | 80% - Individual components
| Tests |
+-------------+
Structure every test with clear phases:
@Test func calculateTotal() {
// Given
let cart = ShoppingCart()
cart.add(Item(price: 10))
cart.add(Item(price: 20))
// When
let total = cart.calculateTotal()
// Then
#expect(total == 30)
}
testFooCaseA/testFooCaseB/... methods → one parameterized @Test(arguments:).try #require(...) then assert on the unwrapped value..serialized only as a transition step.withKnownIssue for temporary known failures to preserve signal.CustomTestStringConvertible for focused diagnostics..serialized on a non-parameterized test → it has no effect. It only applies to parameterized tests (and propagates across a suite's parameterized tests)..timeLimit(.seconds(...)) → only .minutes(...) is accepted.#require where failure should stop the test.XCTMetric, ObjC-only) on XCTest.If the user asks for a review, organize findings by file. For each issue:
Skip files with no issues. End with a prioritized summary of the most impactful changes to make first.
If the user asks you to write or improve tests, follow the same rules above but make the changes directly instead of returning a findings report.
Example output:
Line 5: Use struct, not class, for test suites.
// Before
class UserTests: XCTestCase {
// After
struct UserTests {
Line 12: Use #expect instead of XCTAssertEqual.
// Before
XCTAssertEqual(user.name, "Taylor")
// After
#expect(user.name == "Taylor")
Line 30: Use #require for preconditions, not #expect.
// Before
#expect(users.isEmpty == false)
let first = users.first!
// After
let first = try #require(users.first)
XCTestCase.XCTAssertEqual on line 12 should be migrated to #expect.#require to unwrap safely and stop the test early on failure.End of example.
init/deinit over setUp/tearDown, parallel execution, parameterized tests, withKnownIssue, tags.#expect vs #require, Issue.record(), #expect(throws:), verification methods.#expect, #require, and throw expectations.ConditionTrait.evaluate(), updated #expect(throws:) return value..serialized, isolation strategy.confirmation(), time limits, actor isolation, pre-concurrency code, networking mocks, cancellation, callback bridging, legacy-waiting anti-patterns.stride-chunked withTaskGroup; waitForSent(count: N) deadlocks at chunk boundaries.@Suite enums for layered test targets, swift test --filter regex semantics, async teardown without defer, credential gating.