| name | swift-testing |
| description | Generates unit, view-model, and snapshot tests for Swift/SwiftUI iOS and macOS projects, using Swift Testing (@Test/#expect) for new code and XCTest where it already exists. Tests the ObservableObject/@Observable view model directly rather than trying to introspect a SwiftUI view's private tree. Use when the user asks to write Swift or SwiftUI tests, test a ViewModel/@Observable class, or mentions .xcodeproj, Package.swift, XCTest, Swift Testing, @Test, or swift-snapshot-testing. |
| license | MIT |
| compatibility | Requires Xcode / the Swift toolchain (xcodebuild or swift test) available. Requires a .xcodeproj, .xcworkspace, or Package.swift. |
| metadata | {"platform":"swift","report-source":"testing-methodologies-deep-research-report.txt Part 5 and Part 8"} |
| allowed-tools | Read, Write, Edit, Grep, Glob, Bash |
| paths | ["**/*.swift","Package.swift"] |
Swift / SwiftUI Testing
Writes unit, view-model, and snapshot tests for Swift/SwiftUI projects.
The central pattern: SwiftUI has no public view-tree introspection, so
business logic is tested via the view model, not the view — see
reference/view-model-testing.md before
generating anything against a view file directly. Writing the test files
is the deliverable. Running the suite and verifying it — including the
fault-injection self-check — is a separate, optional step this skill
offers but never runs without being asked. See
Step 6.
Progress checklist
Copy this into your response and check items off as you go:
- [ ] 1. Detect stack + existing test framework (scripts/detect_stack.sh)
- [ ] 2. Audit project structure and existing conventions
- [ ] 3. Ask the user what to test (layer + scope) — do not assume
- [ ] 4. State the test plan explicitly
- [ ] 5. Generate tests following AAA, boundary-only mocking/fakes
- [ ] 6. Report what was written; offer to run + verify — do not run yet
- [ ] 7. Only if asked: run tests, fault-injection self-check, report results
Step 1 — Detect stack
Run scripts/detect_stack.sh from the project root. It confirms this is a
Swift project (.xcodeproj/.xcworkspace/Package.swift) and reports
whether Swift Testing (@Test), XCTest, or both are already in use, plus
swift-snapshot-testing, ViewInspector, and Core Data/SwiftData
presence.
If a test framework is already in use, follow it even if a different tool
is this skill's default recommendation (Swift Testing for new code). Never generate
an XCTAssert* call inside a @Test function or vice versa — see
reference/swift-testing-vs-xctest.md;
the two frameworks are not cross-compatible and a misplaced assertion
silently never registers as a failure.
Step 2 — Audit project structure
Before writing anything:
- Classify the target: a plain type/service (fully testable in isolation)
vs a view model (
ObservableObject/@Observable — test this directly,
never the view) vs a SwiftUI view itself (needs extraction or
ViewInspector — see
reference/view-model-testing.md) vs
UI automation/performance (XCTest-only, Swift Testing does not cover
these — see
).