From ios-platform
Writes, reviews, and improves Swift Testing code using modern APIs, TDD workflow, fixture philosophy, and best practices.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ios-platform:beepus-maximus-ios-swift-testingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Owns:** Swift Testing framework usage, test philosophy, fixture and mock data guidelines, TDD workflow, XCTest migration for unit/integration tests.
Owns: Swift Testing framework usage, test philosophy, fixture and mock data guidelines, TDD workflow, XCTest migration for unit/integration tests.
Does NOT own: UI testing / XCUITest, test execution / CI pipelines, performance profiling.
@Observable view models are directly testable without protocol wrappers.init() instead of setUp(). Only add @Suite when you need a display name or traits.sample1, sample2. Make synthetic data obviously synthetic.! in #expect. Write #expect(value == false) not #expect(!value) -- negation defeats macro expansion and produces unhelpful failure messages..serialized only on parameterised tests when truly needed.| Layer | Use it for | Framework |
|---|---|---|
| Unit tests | business rules, state machines, data transformations, errors | Swift Testing |
| Integration tests | persistence, cross-layer behaviour, migration verification | Swift Testing |
| UI tests | critical user-visible flows only | XCTest / XCUITest |
Dev-views and previews are useful debug aids. They are not a formal test layer — but previews are a valuable development tool when used deliberately (see below).
Previews are not tests, but they catch visual bugs that tests cannot: truncation, overflow, missing states, and layout breakage under extreme data. Use them as a fast feedback loop during implementation.
.previewLayout(.sizeThatFits) for components. Full-device previews waste space for small views.#Preview("Standard") {
MetricCard(title: "Steps", value: "8,432", unit: "steps")
}
#Preview("Long value") {
MetricCard(title: "Heart Rate Variability", value: "142.7", unit: "ms")
}
#Preview("Empty value") {
MetricCard(title: "Steps", value: "--", unit: "steps")
}
#Preview("Dark mode") {
MetricCard(title: "Steps", value: "8,432", unit: "steps")
.preferredColorScheme(.dark)
}
Turn the spec into a short list of behaviours: happy paths, business rules, error cases, integration points.
Preferred order:
Make the tests pass with the smallest production change that satisfies the spec.
Keep the test suite targeted and deterministic.
Run the specific tests you touched, then build the app, then run broader checks if the change is wide enough.
For a given function, aim to generate:
Good tests follow FIRST: Fast, Isolated, Repeatable, Self-verifying, Timely.
Date(timeIntervalSince1970:), not Date())UUID(uuidString:), not UUID())breakfastHighProtein), not vague names (sample1)If asked for a review, organise findings by file. For each issue:
Skip files with no issues. End with a prioritised summary of the most impactful changes.
If asked to write or improve tests, make the changes directly instead of returning a findings report.
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 force-unwrap.
// 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.Migration tests are integration tests against real on-disk stores, not fresh in-memory happy-path checks.
Required pattern: create old-schema store, seed old rows, reopen through real persistence, assert current-model contents survive. Guard tests must verify latest schema matches the migration-plan tail, adjacent versions are covered, and historical schemas use frozen snapshots.
See references/testing-strategy.md for full details.
references/core-patterns.md -- @Test, @Suite, #expect, #require, parameterised tests, struct-based suites, test organisation, tags, new features (raw identifiers, exit tests, attachments, test scopes).references/async-testing.md -- confirmation() for callbacks, @MainActor tests, async/await patterns, timeout control, serialisation, mocking networking, actor interface testing, task cancellation testing.references/xctest-migration.md -- XCTest to Swift Testing assertion mappings, conversion steps, floating-point tolerance.references/fixture-philosophy.md -- determinism rules, preview data, test fixtures, deterministic mocks, dev-view data, reuse threshold.references/testing-strategy.md -- TDD workflow, test layer matrix, migration testing, guard tests, backfill vs runtime repair, in-memory persistence.references/mocking-patterns.md -- protocol-based mocking for networking, dependency injection for tests, in-memory containers, hidden dependency removal, spy pattern for interaction verification, test double taxonomy (stub/spy/fake).references/snapshot-testing.md -- swift-snapshot-testing visual regression, device matrix parameterisation, named references, inline snapshots for text/JSON.Provides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.
npx claudepluginhub 4eleven7/claude-skills --plugin ios-platform