### Install Swift Testing Pro Skill Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/README.md Use this command to install the Swift Testing Pro skill into your AI coding assistant. Ensure Node.js is installed first. ```bash npx skills add https://github.com/twostraws/swift-testing-agent-skill --skill swift-testing-pro ``` -------------------------------- ### Install Node.js via Homebrew Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/README.md If the 'npx: command not found' error occurs, install Node.js using Homebrew. Refer to Homebrew's documentation for initial installation if needed. ```bash brew install node ``` -------------------------------- ### Core Test Suite Structure with Structs Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `struct` for test suites and `init()` for setup. `@Suite` is optional and used for naming or traits. ```swift struct PlayerTests { let sut: Player // init() replaces setUp(); no tearDown needed for value types init() { sut = Player(name: "Natsuki Subaru") } @Test func nameIsCorrect() { #expect(sut.name == "Natsuki Subaru") } @Test func friendsListStartsEmpty() { #expect(sut.friends.isEmpty) } } // @Suite only when attaching traits or renaming @Suite(.tags(.networking)) struct NetworkPlayerTests { // ... } ``` -------------------------------- ### Test Network Fetching with Mock Session Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Write tests that inject a mock `URLSession` to simulate network responses. This example demonstrates fetching news stories and asserting the expected content, ensuring that the fetching logic works correctly without performing live network requests. ```swift @Test func newsStoriesAreFetched() async throws { let url = URL(string: "https://www.apple.com/newsroom/rss-feed.rss")! var news = News(url: url) let session = URLSessionMock() session.testData = Data("Hello, world!".utf8) try await news.fetch(using: session) #expect(news.stories == "Hello, world!") } ``` -------------------------------- ### Migrating XCTest to Swift Testing Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Convert XCTest suites to Swift Testing by switching to structs, removing `XCTestCase`, replacing assertions, and adding traits. This example shows the transformation from an XCTest class to a Swift Testing struct, including the use of `#require` for safe unwrapping. ```swift // XCTest — Before class UserTests: XCTestCase { var sut: User! override func setUp() { sut = User(name: "Taylor") } func testNameIsCorrect() { XCTAssertEqual(sut.name, "Taylor") } func testUsersListIsNotEmpty() { let users = loadUsers() XCTAssertFalse(users.isEmpty) let first = users.first! XCTAssertEqual(first.role, "admin") } } // Swift Testing — After struct UserTests { let sut: User init() { sut = User(name: "Taylor") } @Test func nameIsCorrect() { #expect(sut.name == "Taylor") } @Test func usersListIsNotEmpty() throws { let users = loadUsers() let first = try #require(users.first) // replaces force-unwrap #expect(first.role == "admin") } } ``` ```swift import Numerics #expect(celsius.isApproximatelyEqual(to: 0.0, absoluteTolerance: 0.000001)) ``` -------------------------------- ### Remove Hidden Dependencies with URLSession Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Refactor production code to inject URLSession for easier testing. This example shows the progression from a hidden dependency to dependency injection with a default value. ```swift struct News { var url: URL var stories = "" mutating func fetch() async throws { let (data, _) = try await URLSession.shared.data(from: url) stories = String(decoding: data, as: UTF8.self) } } ``` ```swift func fetch(using session: URLSession = .shared) async throws { let (data, _) = try await session.data(from: url) stories = String(decoding: data, as: UTF8.self) } ``` ```swift protocol URLSessionProtocol { func data(from url: URL) async throws -> (Data, URLResponse) } extension URLSession: URLSessionProtocol { } func fetch(using session: any URLSessionProtocol = URLSession.shared) async throws { let (data, _) = try await session.data(from: url) stories = String(decoding: data, as: UTF8.self) } ``` -------------------------------- ### Using #expect and #require Macros Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `#require` for preconditions that must pass to continue the test, and `#expect` for assertions that record failures but allow the test to proceed. Avoid negating Booleans directly within these macros. ```swift @Test func outstandingTasksStringIsPlural() throws { let sut = try createTestUser(projects: 3, itemsPerProject: 10) // Precondition: stop early if projects are missing try #require(sut.projects.isEmpty == false) // Unwrap optional safely — cleaner than force-unwrap let first = try #require(sut.projects.first) // Actual assertion #expect(sut.outstandingTasksString == "30 items") // Good: Boolean comparison #expect(sut.isActive == false) // Bad — defeats macro expansion, never do this: // #expect(!sut.isActive) } ``` -------------------------------- ### Apply Time Limits with `.timeLimit()` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Apply time limits to tests using `.timeLimit(.minutes(_:))`. Note that `.seconds()` is not available; only `.minutes()` can be used. ```swift // 1-minute limit on a single test @Test("Loading view model names", .timeLimit(.minutes(1))) func loadNames() async { let viewModel = ViewModel() await viewModel.loadNames() #expect(viewModel.names.isEmpty == false, "Names array must be populated.") } ``` ```swift // Suite-level limit applies to each test individually; shorter wins @Suite(.timeLimit(.minutes(2))) struct SlowNetworkTests { // This test uses the suite limit (2 min) @Test func fetchLargePayload() async throws { /* ... */ } // This test uses the shorter limit (1 min) @Test("Quick probe", .timeLimit(.minutes(1))) func quickHealthCheck() async throws { /* ... */ } } ``` -------------------------------- ### Struct Initialization for Test Suites Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/core-rules.md Use a struct with an initializer for test suites. Properties must have default values or be set in the initializer. ```swift struct PlayerTests { let sut: Player init() { sut = Player(name: "Natsuki Subaru") } @Test func nameIsCorrect() { #expect(sut.name == "Natsuki Subaru") } } ``` -------------------------------- ### Implement URLSession Mock Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Create a mock class that conforms to the network fetching protocol. This mock can be configured to return specific test data or throw predefined errors, enabling isolated testing of network-dependent code. ```swift class URLSessionMock: URLSessionProtocol { var testData: Data? var testError: (any Error)? func data(from url: URL) async throws -> (Data, URLResponse) { if let testError { throw testError } else { (testData ?? Data(), URLResponse()) } } } ``` -------------------------------- ### Verification Method with SourceLocation Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Create reusable verification methods that use `#_sourceLocation` to ensure failure messages point to the test site, not the verification method itself. The `#_sourceLocation` macro currently requires the underscore. ```swift func verifyDivision(_ result: (quotient: Int, remainder: Int), expectedQuotient: Int, expectedRemainder: Int, sourceLocation: SourceLocation = #_sourceLocation) { #expect(result.quotient == expectedQuotient, sourceLocation: sourceLocation) #expect(result.remainder == expectedRemainder, sourceLocation: sourceLocation) } ``` -------------------------------- ### Create Local UserDefaults Instance for Testing Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Instantiate a local UserDefaults instance within a test to avoid interference from global settings. Ensure the instance is cleaned up after the test using defer. ```swift let suite = "suite-\(UUID().uuidString)" let userDefaults = UserDefaults(suiteName: suite) defer { userDefaults?.removePersistentDomain(forName: suite) } ``` -------------------------------- ### Use #require for Preconditions Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/SKILL.md Employ the `#require` macro for preconditions in Swift Testing to safely unwrap optionals and halt execution on failure, rather than force-unwrapping with `#expect`. ```swift // Before #expect(users.isEmpty == false) let first = users.first! // After let first = try #require(users.first) ``` -------------------------------- ### Parameterized Tests with Pairwise Zip Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `zip()` with two collections for pairwise pairing of arguments, avoiding a Cartesian product explosion. ```swift @Test(arguments: zip(["a", "b", "c"], [1, 2, 3])) func pairedValues(letter: String, number: Int) { #expect(letter.count == 1) #expect(number > 0) } ``` -------------------------------- ### Using SourceLocation for Verification Helpers in Swift Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Wrap multiple expectations into helper functions and pass `SourceLocation` so failures report the caller's file/line, not the helper's. This ensures that test failures accurately point to the line of code that triggered the test, rather than an internal helper function. ```swift func verifyDivision( _ result: (quotient: Int, remainder: Int), expectedQuotient: Int, expectedRemainder: Int, sourceLocation: SourceLocation = #_sourceLocation ) { #expect(result.quotient == expectedQuotient, sourceLocation: sourceLocation) #expect(result.remainder == expectedRemainder, sourceLocation: sourceLocation) } @Test func divisionIsCorrect() throws { let result = divide(10, by: 3) verifyDivision(result, expectedQuotient: 3, expectedRemainder: 1) // Failures point here, not into verifyDivision() } ``` -------------------------------- ### Using confirmation() with an async worker Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Demonstrates how to use `confirmation(expectedCount:)` with an `async` worker. The test waits for the worker to complete its tasks before confirming. ```swift @Test func workerRunsThreeTimes() async { let worker = Worker() await confirmation(expectedCount: 3) { confirm in for _ in 0..<3 { await worker.run { // your work here } confirm() } } ``` -------------------------------- ### Testing Code that Calls `fatalError()` or `precondition()` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `#expect(processExitsWith:)` to test code that calls `fatalError()` or `precondition()`. This must be awaited as Swift Testing spawns a child process. ```swift struct Dice { func roll(sides: Int) -> Int { precondition(sides > 0) return Int.random(in: 1...sides) } } @Test func invalidDiceRollsFail() async throws { await #expect(processExitsWith: .failure) { let dice = Dice() _ = dice.roll(sides: 0) // triggers precondition → process exits } } ``` -------------------------------- ### Async Tests with `confirmation()` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `confirmation()` to verify async work completes the expected number of times. The tested code must finish before the `confirmation()` closure exits. `.serialized` only works on parameterized tests. ```swift // Async method — await it directly so confirmation() can track completion @Test func workerRunsThreeTimes() async { let worker = Worker() await confirmation(expectedCount: 3) { confirm in for _ in 0..<3 { await worker.run { /* simulated work */ } confirm() } } } ``` ```swift // Callback-based code — return the Task so tests can await it @Test func workerRunsThreeTimesCallback() async { let worker = LegacyWorker() await confirmation(expectedCount: 3) { confirm in for _ in 0..<3 { let task = worker.run { /* simulated work */ } await task.value // wait for task before confirming confirm() } } } ``` ```swift // Range-based confirmation (Swift 6.1+) @Test func fiveToTenFeedsAreLoaded() async throws { let loader = NewsLoader() await confirmation(expectedCount: 5...10) { confirm in for await _ in loader { confirm() } } } ``` -------------------------------- ### Mocking Networking with URLSession Protocol and Mock Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Wrap `URLSession` behind a protocol and inject a mock for fast, offline testing. The `News` struct demonstrates production code with an injected dependency. ```swift // Protocol wrapping the specific URLSession method(s) used protocol URLSessionProtocol { func data(from url: URL) async throws -> (Data, URLResponse) } extension URLSession: URLSessionProtocol {} // Mock for tests class URLSessionMock: URLSessionProtocol { var testData: Data? var testError: (any Error)? func data(from url: URL) async throws -> (Data, URLResponse) { if let testError { throw testError } return (testData ?? Data(), URLResponse()) } } // Production code with injected dependency struct News { var url: URL var stories = "" mutating func fetch(using session: any URLSessionProtocol = URLSession.shared) async throws { let (data, _) = try await session.data(from: url) stories = String(decoding: data, as: UTF8.self) } } // Test using mock @Test func newsStoriesAreFetched() async throws { let url = URL(string: "https://www.apple.com/newsroom/rss-feed.rss")! var news = News(url: url) let session = URLSessionMock() session.testData = Data("Hello, world!".utf8) try await news.fetch(using: session) #expect(news.stories == "Hello, world!") } ``` -------------------------------- ### Using confirmation() with a Task-returning worker Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Shows how to use `confirmation(expectedCount:)` when the worker returns a `Task`. The test explicitly awaits the task's value before calling `confirm()`. ```swift @Test func workerRunsThreeTimes() async { let worker = Worker() await confirmation(expectedCount: 3) { confirm in for _ in 0..<3 { let task = worker.run { // simulated work } await task.value confirm() } } ``` -------------------------------- ### Declaring and Applying Test Tags Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Define tags in a `Tag` extension for categorization and apply them to individual tests or entire suites using the `.tags()` parameter. ```swift // Declare tags once (typically in a shared file) extension Tag { @Tag static var networking: Self @Tag static var slow: Self @Tag static var edgeCase: Self @Tag static var smoke: Self } // Apply to a single test @Test(.tags(.networking)) func fetchUserProfile() async throws { // test code } // Apply to a whole suite — all tests inside inherit the tag @Suite(.tags(.networking, .slow)) struct RemoteDataTests { @Test func loadTimeline() async throws { /* ... */ } @Test func uploadAttachment() async throws { /* ... */ } } ``` -------------------------------- ### Use #require for Precondition Checks in Tests Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Employ #require to validate assumptions at the beginning of a test. If the condition is false, #require throws an error, halting test execution and preventing misleading subsequent failures. It also unwraps optionals cleanly. ```swift @Test func outstandingTasksStringIsPlural() throws { let sut = try createTestUser(projects: 3, itemsPerProject: 10) try #require(sut.projects.isEmpty == false) let rowTitle = sut.outstandingTasksString #expect(rowTitle == "30 items") } ``` ```swift let value = try #require(someOptional) ``` -------------------------------- ### Swift Testing Assertion Equivalents Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/migrating-from-xctest.md Direct mappings from XCTest assertions to Swift Testing's expectation macros. Use `#expect` for most assertions and `#require` for unwrapping optionals or enforcing boolean conditions. ```swift #expect(a == b) ``` ```swift #expect(a < b) ``` ```swift #expect(throws:) ``` ```swift try #require(optional) ``` ```swift Issue.record("message") ``` ```swift #expect(a === b) ``` -------------------------------- ### Define Network Fetching Protocol Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Create a protocol to abstract network fetching, such as mimicking `URLSession`'s `data(from:)` method. This allows for easy mocking of network operations in tests. ```swift protocol URLSessionProtocol { func data(from url: URL) async throws -> (Data, URLResponse) } extension URLSession: URLSessionProtocol { } ``` -------------------------------- ### Wrap Code with `withKnownIssue` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `withKnownIssue` to wrap code that has a known bug. Set `isIntermittent: true` for flaky issues under active investigation. ```swift @Test func renderingIsCorrect() { // Known bug: colors invert on dark mode — expected to fail withKnownIssue("Colors invert in dark mode (issue #214)") { #expect(renderer.backgroundColor == .white) } // Flaky issue: sometimes passes, sometimes fails withKnownIssue("Intermittent layout glitch", isIntermittent: true) { #expect(view.frame.width == 320) } } ``` -------------------------------- ### Handle Errors Separately with #expect(throws:) Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md The `#expect(throws:)` macro allows running the code and evaluating the thrown error separately. This requires Swift 6.1 or later. ```swift enum GameError: Error { case disallowedTime } func playGame(at time: Int) throws(GameError) { if time < 9 || time > 20 { throw GameError.disallowedTime } else { print("Enjoy!") } } ``` ```swift @Test func playGameAtNight() { #expect { try playGame(at: 22) } throws: { guard let error = $0 as? GameError else { return false } // perform additional error validation here return error == .disallowedTime } } ``` ```swift @Test func playGameAtNight() { // `error` will now be a GameError let error = #expect(throws: GameError.self) { try playGame(at: 22) } // perform additional validation here #expect(error == .disallowedTime) } ``` -------------------------------- ### Trigger Swift Testing Pro in Codex Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/README.md This is the command to invoke the Swift Testing Pro skill within Codex. You can append specific instructions for targeted reviews. ```bash $swift-testing-pro ``` -------------------------------- ### Replace XCTAssertEqual with #expect Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/SKILL.md Use the `#expect` macro for assertions in Swift Testing instead of `XCTAssertEqual` from XCTest. ```swift // Before XCTAssertEqual(user.name, "Taylor") // After #expect(user.name == "Taylor") ``` -------------------------------- ### Defining Custom Tags for Swift Testing Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/core-rules.md Create custom tags by extending the `Tag` type. These tags can then be applied to individual tests or entire suites. ```swift extension Tag { @Tag static var networking: Self } ``` -------------------------------- ### Parameterized Tests with Single Collection Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use a single collection for parameterized tests to run one test case per element. Ensure floating-point comparisons use appropriate tolerance. ```swift @Test(arguments: [ (input: 32.0, expected: 0.0), (input: 212.0, expected: 100.0), (input: -40.0, expected: -40.0), ]) func fahrenheitToCelsius(values: (input: Double, expected: Double)) { let result = (values.input - 32) * 5 / 9 #expect(result.isApproximatelyEqual(to: values.expected, absoluteTolerance: 0.001)) } ``` -------------------------------- ### Error Throwing Tests with `Issue.record()` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `do`/`catch` with `Issue.record()` for fine-grained error matching. Always name the specific error, never `Error.self`. ```swift // Fine-grained: catches specific error case @Test func playingUnpurchasedGameThrows() { let game = Game(name: "Minecraft") do { try game.play() Issue.record("Expected an error to be thrown.") } catch GameError.notPurchased { // success — expected path } catch { Issue.record("Wrong error thrown: \(error)") } } ``` -------------------------------- ### Testing for Specific Errors with #expect(throws:) Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Use `#expect(throws:)` to assert that a function throws a specific error. Avoid using `Error.self` as it passes for any error. ```swift // Bad – passes for any error #expect(throws: Error.self) { try game.play() } ``` ```swift // Good – asserts the exact error case #expect(throws: GameError.notInstalled) { try game.play() } ``` -------------------------------- ### Parameterized Tests with Two Collections (Cartesian Product) Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Combine two collections to create a Cartesian product of test cases. This generates `n * m` test cases. ```swift @Test(arguments: ["admin", "editor", "viewer"], [true, false]) func userRoleAccess(role: String, isActive: Bool) { let user = User(role: role, isActive: isActive) #expect(user.canLogin == isActive) } ``` -------------------------------- ### Floating-Point Comparison with Tolerance in Swift Testing Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/migrating-from-xctest.md When Swift Testing lacks built-in float tolerance, use the Swift Numerics library's `isApproximatelyEqual(to:absoluteTolerance:)` method for comparing floating-point values. Ensure the Swift Numerics library is available before use. ```swift #expect(celsius.isApproximatelyEqual(to: 0, absoluteTolerance: 0.000001)) ``` -------------------------------- ### Raw Identifiers with Parameterized Tests in Swift Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Combine raw identifiers with parameterized tests to create human-readable test names for complex scenarios. Requires Swift 6.2 or later. ```swift @Test("Ensure Fahrenheit to Celsius conversion is correct.", arguments: [ (32, 0), (212, 100), (-40, -40), ]) func fahrenheitToCelsius(values: (input: Double, output: Double)) { // test code here } ``` ```swift @Test(arguments: [ (32, 0), (212, 100), (-40, -40), ]) func `Ensure Fahrenheit to Celsius conversion is correct`(values: (input: Double, output: Double)) { // test code here } ``` -------------------------------- ### Trigger Swift Testing Pro in Claude Code Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/README.md This is the command to invoke the Swift Testing Pro skill within Claude Code. You can append specific instructions for targeted reviews. ```bash /swift-testing-pro ``` -------------------------------- ### Implement TestScoping Trait for Player Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Implements the TestTrait and TestScoping protocols to create a custom scope for the Player's @TaskLocal variable. Use this to set specific player values for tests. ```swift struct DefaultPlayerTrait: TestTrait, TestScoping { func provideScope( for test: Test, testCase: Test.Case?, performing function: () async throws -> Void ) async throws { let player = Player(name: "Natsuki Subaru") try await Player.$current.withValue(player) { try await function() } } } ``` -------------------------------- ### Async Worker for confirmation() Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md This worker is refactored to be `async`, allowing `confirmation()` to properly await its completion. This is the preferred approach when possible. ```swift struct Worker { func run(_ work: @escaping () -> Void) async { let start = CFAbsoluteTimeGetCurrent() work() print("Elapsed:", CFAbsoluteTimeGetCurrent() - start) } } ``` -------------------------------- ### Setting a time limit for an async test Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Applies a 1-minute time limit to an asynchronous test using the `.timeLimit(.minutes(1))` trait. Tests exceeding this duration will fail. ```swift @Test("Loading view model names", .timeLimit(.minutes(1))) func loadNames() async { let viewModel = ViewModel() await viewModel.loadNames() #expect(viewModel.names.isEmpty == false, "Names should be full of values.") } ``` -------------------------------- ### Attaching Debug Data to Failing Tests Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Conform to `Attachable` to attach debug data to failing tests. Foundation and `Codable` enable automatic JSON encoding. ```swift import Foundation import Testing struct Character: Attachable, Codable { var id = UUID() var name: String } func makeCharacter() -> Character { Character(name: "Ram") } @Test func defaultCharacterNameIsCorrect() { let result = makeCharacter() #expect(result.name == "Rem") // intentional mismatch — test fails Attachment.record(result, named: "Character") // JSON-encoded Character attached to failure } ``` -------------------------------- ### Specify Actor for Closures with confirmation() and withKnownIssue() Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Use `confirmation()` or `withKnownIssue()` to specify a particular actor for a closure within a test. This allows a specific block of asynchronous code to run on a designated actor (like `MainActor.shared` or a custom actor) while the rest of the test may execute elsewhere. ```swift @Test("Loading view model names") func loadNames() async { await withKnownIssue("Names can sometimes come back with too few values", isolation: MainActor.shared) { // test code here } } ``` -------------------------------- ### Worker with completion closure Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md This worker implementation uses a completion closure and a `Task` that cannot be directly monitored by `confirmation()`, leading to potential test failures. ```swift struct Worker { func run(_ work: @escaping () -> Void) -> Task { Task { let start = CFAbsoluteTimeGetCurrent() work() print("Elapsed:", CFAbsoluteTimeGetCurrent() - start) } } } ``` -------------------------------- ### Define @TaskLocal Property for Player Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Defines a Player struct with a @TaskLocal static property 'current' to manage player state concurrently. This is useful for sharing test configurations safely. ```swift struct Player { var name: String var friends = [Player]() @TaskLocal static var current = Player(name: "Anonymous") } func createWelcomeScreen() -> String { var message = "Welcome, \(Player.current.name)!\n" message += "Friends online: \(Player.current.friends.count)" return message } ``` -------------------------------- ### Concise Error Checks with `#expect(throws:)` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `#expect(throws:)` for concise single-error checks. This returns the error for further validation (Swift 6.1+). Assert no error is thrown using `Never.self`. ```swift // Concise: returns the error for further validation (Swift 6.1+) @Test func playGameAtNight() { let error = #expect(throws: GameError.self) { try playGame(at: 22) } #expect(error == .disallowedTime) } ``` ```swift // Assert no error is thrown @Test func playGameDuringDay() { #expect(throws: Never.self) { try playGame(at: 12) } } ``` -------------------------------- ### Function to Make Character Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md A simple production function that creates and returns a Character instance. This is used in conjunction with attachment tests. ```swift func makeCharacter() -> Character { Character(name: "Ram") } ``` -------------------------------- ### Test Function Not Throwing with #expect(throws: Never.self) Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Use `#expect(throws: Never.self)` to assert that a function does not throw any errors. ```swift #expect(throws: Never.self) { try game.play() } ``` -------------------------------- ### Migrate XCTestClass to Swift Testing Struct Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/SKILL.md When migrating from XCTest, replace classes inheriting from XCTestCase with plain structs for test suites in Swift Testing. ```swift // Before class UserTests: XCTestCase { // After struct UserTests { ``` -------------------------------- ### Wrap Legacy Callback Code with `withCheckedContinuation` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use `withCheckedContinuation` to wrap callback-based code. Assertions must be placed inside the callback before resuming the continuation. ```swift @Test("Loading view model readings") func loadReadings() async { let viewModel = ViewModel() await withCheckedContinuation { continuation in viewModel.loadReadings { readings in // Assert inside the callback, before resuming #expect(readings.count >= 10, "At least 10 readings must be returned.") continuation.resume() } } } ``` -------------------------------- ### Extend Trait with Custom Player Trait Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Provides a convenient static property 'defaultPlayer' to easily apply the custom DefaultPlayerTrait in tests. This simplifies trait application. ```swift extension Trait where Self == DefaultPlayerTrait { static var defaultPlayer: Self { Self() } } ``` -------------------------------- ### Test Character Name and Record Attachment Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Tests the default character name and records the created character as an attachment named 'Character'. This demonstrates how to attach custom data to test results for debugging. Requires Swift 6.2 or later. ```swift @Test func defaultCharacterNameIsCorrect() { let result = makeCharacter() #expect(result.name == "Rem") Attachment.record(result, named: "Character") } ``` -------------------------------- ### Minimum Count Confirmation with Ranges in Swift Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Assert that an async sequence yields at least a minimum number of items using a partial range with the `confirmation()` function. Requires Swift 6.1 or later. ```swift await confirmation(expectedCount: 5...) { confirm in for await _ in loader { confirm() } } ``` -------------------------------- ### Range-Based Confirmations for Async Sequences in Swift Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Use range-based confirmations with the `confirmation()` function to assert that an async sequence yields a specific number of items within a given range. Requires Swift 6.1 or later. ```swift @Test func fiveToTenFeedsAreLoaded() async throws { let loader = NewsLoader() await confirmation(expectedCount: 5...10) { confirm in for await _ in loader { confirm() } } } ``` -------------------------------- ### Test Function Throwing an Error with Issue.record() Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Use `Issue.record()` within a `do`/`try`/`catch` block to test that a function throws a specific error. If no error is thrown, `Issue.record()` fails the test. ```swift @Test func playingMinecraftThrows() { let game = Game(name: "Minecraft") do { try game.play() Issue.record("Expected an error to be thrown.") } catch GameError.notPurchased { // success } catch { Issue.record("Wrong error thrown: \(error)") } } ``` -------------------------------- ### Apply Custom Player Trait to Test Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Applies the custom '.defaultPlayer' trait to a test function, ensuring the test runs with the 'Natsuki Subaru' player context. This demonstrates how to integrate custom scoping traits. ```swift @Test(.defaultPlayer) func welcomeScreenShowsName() { let result = createWelcomeScreen() #expect(result.contains("Natsuki Subaru")), } ``` -------------------------------- ### Custom Test Description for Enum Cases Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Add a `CustomTestStringConvertible` conformance to custom types to make them appear more readable in test results. This conformance should not be added in production code. ```swift extension GameError: @retroactive CustomTestStringConvertible { public var testDescription: String { switch self { case .notPurchased: "This game has not been purchased." case .notInstalled: "This game is not currently installed." case .parentalControlsDisallowed: "This game has been blocked by parental controls." } } } ``` -------------------------------- ### Use Raw Identifiers for Test Names in Swift Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Use raw identifiers with backticks to write test names as natural strings, improving readability over camel case. Requires Swift 6.2 or later. ```swift @Test("Strip HTML tags from string") func stripHTMLTagsFromString() { // test code } ``` ```swift @Test func `Strip HTML tags from string`() { // test code } ``` -------------------------------- ### Applying Custom Tags to Tests Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/core-rules.md Apply custom tags to individual tests or entire suites using the `.tags()` trait. This allows for categorized test execution and filtering. ```swift @Test(.tags(.networking)) func fetchUserProfile() async throws { // test code here } ``` -------------------------------- ### Pin Tests to `MainActor` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Pin tests to `@MainActor` or a custom actor at the test or suite level. Pass `isolation:` to `confirmation()` or `withKnownIssue()` for per-closure actor control. ```swift // Single test on main actor @MainActor @Test func uiStateUpdatesOnMainThread() async { let vm = ViewModel() await vm.load() #expect(vm.isReady) } ``` ```swift // Whole suite on main actor @MainActor struct UITests { @Test func titleIsVisible() { /* ... */ } @Test func buttonIsEnabled() { /* ... */ } } ``` ```swift // Per-closure actor for withKnownIssue @Test func intermittentMainActorIssue() async { await withKnownIssue("Flaky on main thread", isIntermittent: true, isolation: MainActor.shared) { #expect(UIState.shared.isReady) } } ``` -------------------------------- ### Test Critical Failure with processExitsWith Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Tests code that is expected to cause a critical failure using #expect(processExitsWith:). This allows verification of fatal errors or preconditions without crashing the test runner. Requires Swift 6.2 or later. ```swift @Test func invalidDiceRollsFail() async throws { await #expect(processExitsWith: .failure) { let dice = Dice() let _ = dice.roll(sides: 0) } } ``` -------------------------------- ### Wrap Pre-Concurrency Code with withCheckedContinuation Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md When testing older Swift code that uses callback functions instead of `async`/`await`, use `withCheckedContinuation` to safely wrap the callback-based code. Ensure the test waits for the completion handler to be called before making assertions. ```swift class ViewModel { func loadReadings(completion: @Sendable @escaping ([Double]) -> Void) { let url = URL(string: "https://hws.dev/readings.json")! URLSession.shared.dataTask(with: url) { data, response, error in if let data { if let numbers = try? JSONDecoder().decode([Double].self, from: data) { completion(numbers) return } } completion([]) }.resume() } } ``` ```swift @Test("Loading view model readings") func loadReadings() async { let viewModel = ViewModel() await withCheckedContinuation { continuation in viewModel.loadReadings { readings in #expect(readings.count >= 10, "At least 10 readings must be returned.") continuation.resume() } } } ``` -------------------------------- ### Using Raw Identifiers for Human-Readable Test Names Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Use backtick-quoted function names as raw identifiers to write human-readable test names without a separate string label, thus avoiding duplication. This also works with parameterized tests. ```swift // Before: string label duplicates the method name @Test("Strip HTML tags from string") func stripHTMLTagsFromString() { /* ... */ } // After: raw identifier eliminates duplication @Test func `Strip HTML tags from string`() { /* ... */ } // Also works with parameterized tests @Test(arguments: [(32.0, 0.0), (212.0, 100.0), (-40.0, -40.0)]) func `Fahrenheit to Celsius conversion is accurate`(values: (input: Double, expected: Double)) { let result = (values.input - 32) * 5 / 9 #expect(result.isApproximatelyEqual(to: values.expected, absoluteTolerance: 0.001)) } ``` -------------------------------- ### Track Bugs with `.bug` Trait Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Attach a bug ID or URL to a test using the `.bug` trait for future reference. This provides context for any failures that occur. ```swift // Bug by ID @Test("Headings should always be italic", .bug(id: 182)) func headingsAreItalic() { let heading = Heading(text: "Title") #expect(heading.isItalic) } ``` ```swift // Bug by URL @Test("Cart total must include tax", .bug("https://github.com/you/repo/issues/99")) func cartTotalIncludesTax() { let cart = Cart(items: [Item(price: 10.0)]) #expect(cart.total > 10.0) } ``` -------------------------------- ### Test Scoping Traits with `@TaskLocal` Source: https://context7.com/twostraws/swift-testing-agent-skill/llms.txt Implement `TestTrait & TestScoping` to provide concurrency-safe per-test configuration, often combined with `@TaskLocal` for managing task-local state. ```swift struct Player { var name: String @TaskLocal static var current = Player(name: "Anonymous") } // Scoping trait sets up task-local state for each test struct DefaultPlayerTrait: TestTrait, TestScoping { func provideScope( for test: Test, testCase: Test.Case?, performing function: () async throws -> Void ) async throws { let player = Player(name: "Natsuki Subaru") try await Player.$current.withValue(player) { try await function() } } } extension Trait where Self == DefaultPlayerTrait { static var defaultPlayer: Self { Self() } } @Test(.defaultPlayer) func welcomeScreenShowsName() { #expect(Player.current.name == "Natsuki Subaru") } ``` -------------------------------- ### Define Dice Struct with Precondition Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Defines a Dice struct with a roll method that uses a precondition to ensure the number of sides is positive. This code is designed to fail hard if the precondition is not met. ```swift struct Dice { func roll(sides: Int) -> Int { precondition(sides > 0) return Int.random(in: 1...sides) } } ``` -------------------------------- ### Define Attachable Character Struct Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Defines a Character struct that conforms to Attachable and Codable protocols. This allows instances of Character to be encoded and attached to test results. ```swift import Foundation import Testing struct Character: Attachable, Codable { var id = UUID() var name: String } ``` -------------------------------- ### Tag Tests with Bug IDs or URLs Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/writing-better-tests.md Use the .bug trait with @Test to associate tests with specific bug tracking IDs or URLs. This provides valuable context for future debugging if the bug reappears. ```swift @Test("Headings should always be italic", .bug(id: 182)) ``` ```swift @Test("Headings should always be italic", .bug("https://github.com/you/repo/issues/182")) ``` -------------------------------- ### Mark Test Suites with @MainActor Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Apply the `@MainActor` attribute to an entire test suite (a struct containing tests) to enforce that all tests within that suite run on the main actor. This is a convenient way to group related tests that require main actor isolation. ```swift @MainActor struct DataHandlingTests { @Test("Loading view model names") func loadNames() async { // test code here } } ``` -------------------------------- ### Mark Individual Tests with @MainActor Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/async-tests.md Use the `@MainActor` attribute to ensure a specific asynchronous test runs on the main actor. This is useful for tests that interact with UI elements or other main actor-bound code. ```swift @MainActor @Test("Loading view model names") func loadNames() async { // test code here } ``` -------------------------------- ### Evaluate Condition Trait Outside Tests Source: https://github.com/twostraws/swift-testing-agent-skill/blob/main/swift-testing-pro/references/new-features.md Use the `evaluate()` method on a condition trait to check conditions outside of test functions. This requires Swift 6.2 or later. ```swift struct TestManager { static let inSmokeTestMode = true } @Test(.disabled(if: TestManager.inSmokeTestMode)) func runLongComplexTest() { // test code here } ``` ```swift func checkForSmokeTest() async throws { let trait = ConditionTrait.disabled(if: TestManager.inSmokeTestMode) if try await trait.evaluate() { print("We're in smoke test mode") } else { print("Run all tests.") } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.