swift-testing
Skill0 starsChanged 2 months agoMITView on GitHub
Use whenever writing, reviewing, improving, migrating, or debugging Swift tests. Covers @Test, #expect, #require, traits, tags, parameterized tests, async/await and confirmation-based tests, parallel execution and isolation, and XCTest-to-Swift-Testing migration. Trigger this for ANY Swift test file work -- new tests, test code review, flaky-test debugging, "modernize my XCTest suite," or a request to write/improve/review tests in a Swift or Apple-platform project -- not only when the user says "Swift Testing" by name.
9 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- memi-design/design-skillstheir own version, first seen Nov 8, 2026
- VelimirMueller/claude-skillstheir own version, first seen Nov 1, 2026
- VelimirMueller/ai-development-skillstheir own version, first seen Nov 1, 2026
- thienqo/ios-skillstheir own version, first seen Oct 11, 2026
- fiveonecode/agent-skillsedited, first seen Sep 6, 2026
- ozgurakkaya90/claude-skillstheir own version, first seen Aug 2, 2026
Other versions9 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- fiveonecode/agent-skills★ 2017% same
Wrote their own version · 8
- Prisma-Labs-Dev/apple-skills★ 336same name
- bocato/swift-testing-agent-skill★ 80same name
- pluginagentmarketplace/custom-plugin-swift★ 9same name
- memi-design/design-skills★ 7same name
- VelimirMueller/ai-development-skills★ 7same name
- VelimirMueller/claude-skills★ 7same name
- thienqo/ios-skills★ 4same name
- ozgurakkaya90/claude-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository21 other files it gives its agents.
- animateSkill
- composable-architectureSkill
- find-animation-opportunitiesSkill
- generating-swift-package-docsSkill
- hapticsSkill
- improve-animationsSkill
- ios-26-platformSkill
- ios-higSkill
- ios-simulator-skillSkill
- localizationSkill
- review-animationsSkill
- spm-build-analysisSkill
- storekitSkill
- swift-concurrencySkill
- swift-dataSkill
- swift-diagnosticsSkill
- swift-networkingSkill
- swift-styleSkill
- swiftuiSkill
- write-swiftSkill
- xcode-buildSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. 0 are common, 5 are distinctive, and 11 are very specific to this project.
0
Common
Most of the 8 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 19
Prefer Swift Testing for all new Swift unit and integration tests, but keep XCTest for UI automation (XCUIApplication), performance metrics …
- Very specific: line 20
Treat #expect as the default assertion.
- Very specific: line 21
Default to parallel-safe guidance.
- Very specific: line 22
Prefer traits for behavior and metadata (.enabled, .disabled, .timeLimit, .bug, tags) over naming conventions or ad-hoc comments.
- Very specific: line 24
Use @available on individual test *functions* for OS-gated behavior, never on suite types.
- Distinctive: line 25
Keep migration advice incremental: convert assertions first, then organize suites, then introduce parameterization/traits.
- Very specific: line 26
Only import Testing in test targets, never in app/library/binary targets.
- Very specific: line 46
Test building blocks, suite structure, struct-vs-class, zero-arg init -> references/fundamentals.md
- Very specific: line 51
Default parallel execution, random order, suite-level isolation strategy -> references/parallelization-and-isolation.md
- Very specific: line 52
Test speed, determinism, and flakiness prevention -> references/performance-and-best-practices.md
- Very specific: line 53
Test hygiene: FIRST principles, structuring tests, hidden dependencies, testing SwiftUI view models -> references/writing-better-tests.md
- Distinctive: line 58
If doing partial work (e.g.
- Very specific: line 75
Test-plan include/exclude by test name -> use tags and tag-based filters instead (references/traits-and-tags.md, …
- Distinctive: line 82
When asked to review Swift Testing code, organize findings by file.
- Distinctive: line 90
When asked to write or improve tests, follow the same rules above but make the changes directly instead of returning a findings report.
- Distinctive: line 126
Test file/folder structure mirrors the production code it covers.
“Common” is measured: kept by at least 6 in 10 of the 8 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Swift Testing
Overview
Swift Testing replaces XCTest with a modern macro-based approach: @Test instead of test-prefixed methods, #expect/#require instead of XCTAssert*, structs instead of XCTestCase subclasses, and parallel-by-default execution instead of serial. If you learned XCTest, unlearn it — Swift Testing works differently in ways that matter (state isolation, argument combinatorics, actor behavior).
Use this skill to write, review, migrate, and debug Swift tests with modern Swift Testing APIs. Prioritize readable tests, robust parallel execution, clear diagnostics, and incremental migration from XCTest where needed. When asked to review code, report only genuine problems — do not nitpick or invent issues.
Agent behavior contract
- Prefer Swift Testing for all new Swift unit and integration tests, but keep XCTest for UI automation (
XCUIApplication), performance metrics (XCTMetric), and Objective-C-only test code — Swift Testing does not support UI tests. - Treat
#expectas the default assertion; use#requireonly when a later line depends on the value being present/true (precondition, not assertion). - Default to parallel-safe guidance. If tests aren't isolated, propose fixing the shared state first rather than reaching for
.serialized. - Prefer traits for behavior and metadata (
.enabled,.disabled,.timeLimit,.bug, tags) over naming conventions or ad-hoc comments. - Recommend parameterized tests when multiple tests share logic and differ only in input values — but watch argument-count combinatorics (see
references/parameterized-testing.md). - Use
@availableon individual test functions for OS-gated behavior, never on suite types. - Keep migration advice incremental: convert assertions first, then organize suites, then introduce parameterization/traits. Don't rewrite an existing XCTest suite to Swift Testing unless asked.
- Only import
Testingin test targets, never in app/library/binary targets. - Target Swift 6.2+ and modern Swift concurrency by default, and use a project structure with folder layout that mirrors the code under test (see
references/writing-better-tests.md). - Swift Testing gains new features every Swift release (3-4/year), so your training data is likely stale on recent APIs and Apple's own docs can lag too. Treat the user's installed toolchain as authoritative for what's available; see
references/new-features.mdfor capabilities that may postdate your training.
First 60 seconds (triage template)
- Clarify the goal: new tests, migration, flaky failures, performance, CI filtering, or async waiting.
- Collect minimal facts:
- Xcode/Swift version and platform targets
- Whether tests currently use XCTest, Swift Testing, or both
- Whether failures are deterministic or flaky
- Whether tests access shared resources (database, files, network, global state)
- Branch quickly:
- repetitive tests -> parameterized tests
- noisy or flaky failures -> known-issue handling and test isolation
- migration questions -> XCTest mapping and coexistence strategy
- async callback complexity -> continuation/confirmation patterns
Routing map (read the right reference fast)
- Test building blocks, suite structure, struct-vs-class, zero-arg init ->
references/fundamentals.md #expect,#require, throw expectations,Issue.record(), readable failures ->references/expectations.md- Traits, tags, bug linking, conditions, availability ->
references/traits-and-tags.md - Parameterized test design, combinatorics,
zippitfalls ->references/parameterized-testing.md - Async/await tests, confirmations, callback bridging, actor isolation,
.serializednuances, mocking ->references/async-testing.md - Default parallel execution, random order, suite-level isolation strategy ->
references/parallelization-and-isolation.md - Test speed, determinism, and flakiness prevention ->
references/performance-and-best-practices.md - Test hygiene: FIRST principles, structuring tests, hidden dependencies, testing SwiftUI view models ->
references/writing-better-tests.md - Recent Swift Testing features (raw identifiers, exit tests, attachments, test scopes,
ConditionTrait.evaluate()) ->references/new-features.md - XCTest coexistence and migration workflow ->
references/migration-from-xctest.md - Xcode test navigator/report workflows and diagnostics ->
references/xcode-workflows.md
If doing partial work (e.g. only a migration pass, or only an async-tests review), load only the relevant reference files instead of all of them.
Common pitfalls -> next best move
- Repetitive
testFooCaseA/testFooCaseB/...methods -> replace with one parameterized@Test(arguments:)(references/parameterized-testing.md). - Two argument collections without
zip-> silently becomes a Cartesian product, not pairwise; usezip, or better, an array of tuples/dictionary to avoidzip's silent-truncation and enum-reordering fragility (references/parameterized-testing.md). - Failing optional preconditions hidden in later assertions ->
try #require(...)then assert on the unwrapped value (references/expectations.md). - Overusing
#requirefor ordinary assertions -> stops the test at first failure instead of reporting all failures; reserve it for preconditions (references/expectations.md). #expect(!isLoggedIn)->!defeats macro expansion and produces unhelpful failure output; write#expect(isLoggedIn == false)instead (references/expectations.md).- "Each test gets a fresh instance, so state can't leak" -> true for instance properties, false for
static/singleton state; isolate or reset it (references/parallelization-and-isolation.md). - Flaky integration tests on shared database -> isolate dependencies or use in-memory repositories; use
.serializedonly as a transition step (references/parallelization-and-isolation.md). .serialized"should" work on any test -> it only affects a parameterized test's own cases when applied directly to a single@Test; applied to a@Suiteit serializes everything inside that suite (references/async-testing.md)..timeLimit(.seconds(10))-> wrong; the trait only accepts.minutes(...)(references/async-testing.md).- Wrapping async work in
Task { }inside a test, or using a completion closure withconfirmation()-> defeats the point; useasynctest functions directly, or track theTaskandawaitit (references/async-testing.md). confirmation()used for general assertions -> it's for verifying callback/event counts, not a substitute for#expect(references/async-testing.md).- Disabled tests that silently rot -> prefer
withKnownIssue(optionallyisIntermittent: true) over blanket disabling so they keep signaling (references/expectations.md). - Unclear failure output for complex types -> conform to
CustomTestStringConvertiblein the test target only (references/expectations.md). - Test-plan include/exclude by test name -> use tags and tag-based filters instead (
references/traits-and-tags.md,references/xcode-workflows.md). - Expected value derived from the same expression as the code under test, or
if/switchbranching inside a parameterized test body -> both let the test mirror/mask bugs in production logic instead of verifying it independently (references/parameterized-testing.md). - Testing a SwiftUI
Viewdirectly -> flaky and implementation-coupled; test the view model instead (references/writing-better-tests.md). - Hidden dependencies (
URLSession.shared, ambientUserDefaults) baked into production code -> inject them so tests can substitute fakes (references/writing-better-tests.md).
Reviewing or writing test code
When asked to review Swift Testing code, organize findings by file. For each issue:
- State the file and relevant line(s).
- Name the rule being violated.
- Show a brief before/after code fix.
Skip files with no issues. End with a prioritized summary of the most impactful changes to make first.
When asked to write or improve tests, follow the same rules above but make the changes directly instead of returning a findings report.
Example finding:
### UserTests.swift
**Line 5: Use struct, not class, for test suites.**
// Before
class UserTests: XCTestCase {
// After
struct UserTests {
**Line 30: Use `#require` for preconditions, not `#expect`.**
// Before
#expect(users.isEmpty == false)
let first = users.first!
// After
let first = try #require(users.first)
### Summary
1. **Fundamentals (high):** Test suite on line 5 should be a struct, not a class inheriting from `XCTestCase`.
2. **Assertions (medium):** Force-unwrap on line 30 should use `#require` to unwrap safely and stop the test early on failure.Verification checklist
- Each test has a single clear behavior and an expressive display name when needed.
- Prerequisites use
#requirewhere failure should stop the test; ordinary assertions use#expect. - Repeated logic is parameterized instead of duplicated, with concrete (not derived) expected values.
- Tests are parallel-safe, or intentionally
.serializedwith a stated reason. - Async code is awaited natively (not
Task { }-wrapped), and callback APIs are bridged safely. - Hidden dependencies (networking,
UserDefaults, time, randomness) are injected, not ambient. - Migration keeps unsupported XCTest-only scenarios (UI tests,
XCTMetric) on XCTest. - Test file/folder structure mirrors the production code it covers.
References
references/fundamentals.mdreferences/expectations.mdreferences/traits-and-tags.mdreferences/parameterized-testing.mdreferences/async-testing.mdreferences/parallelization-and-isolation.mdreferences/performance-and-best-practices.mdreferences/writing-better-tests.mdreferences/new-features.mdreferences/migration-from-xctest.mdreferences/xcode-workflows.md
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

