Swiftdata testing
Skill akshaypimprikar/ios-swiftdata-testing-agent-skill/swiftdata-testing
Writes and reviews SwiftData test code — in-memory ModelContainer fixtures, mock repository patterns, @ModelActor test isolation, Decimal money-value assertions, and content-hash dedup testing. Use when writing or reviewing unit/integration tests for a SwiftData-backed app.From its SKILL.md
npx -y skills add akshaypimprikar/ios-swiftdata-testing-agent-skill --skill swiftdata-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 23 days oldThe repository was created 23 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
3.9 KB, 798 tokens by cl100k_base, as published. Nobody here has run it
Write and review SwiftData test code so it runs in isolation, never touches the device's persistent store, and catches the failure modes specific to @Model, @ModelActor, and money-typed data. Report only genuine problems — do not nitpick or invent issues.
Test-writing process:
- For repository/integration tests, use
references/model-container-fixtures.mdfor the in-memoryModelContainersetup. - For ViewModel unit tests, use
references/mock-repositories.md— never construct a realModelContainerjust to unit test a ViewModel. - If the code under test uses
@ModelActor, usereferences/model-actor-testing.mdfor actor-isolation-safe test patterns. - If the model stores currency/money values, use
references/decimal-money-values.md—Decimalrequires different assertion patterns thanDouble. - If the code deduplicates records via a content hash (e.g. CSV/API import), use
references/import-hash-dedup.md.
If doing partial work, load only the relevant reference files.
Core Instructions
- Target Swift 6.2+ with the
Testingframework (@Suite,@Test,#expect,#require) — not XCTest, for unit and integration tests. - Every test that touches SwiftData must use
isStoredInMemoryOnly: true. A test that writes to the real persistent store is not a unit test — it's a device-state mutation with a#Testlabel on it. - Never share a
ModelContextorModelContainerinstance across tests. Build a fresh one per@Test— SwiftData containers are cheap, and cross-test state leakage produces the kind of intermittent failure that looks like flakiness but is actually a fixture bug. - Domain/business-logic tests should not need a
ModelContainerat all. If a test importsSwiftDatajust to instantiate a value it never persists or fetches, that's a sign business logic isn't cleanly separated from the persistence layer yet — flag it rather than writing around it. - Never move a
@Modelinstance across an actor boundary — not even in test code. PassPersistentIdentifieror a value-type DTO and re-fetch inside the target actor.
Output Format
If the user asks for a review, 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 fixes.
If the user asks you to write or fix tests, follow the same rules above but make the changes directly instead of returning a findings report.
Known Gotcha: migrationPlan + isStoredInMemoryOnly don't mix
Applying a SchemaMigrationPlan to an in-memory-only ModelConfiguration causes save() to fail — sometimes silently, sometimes non-deterministically depending on device load, which makes it look flaky rather than broken. An in-memory store starts fresh on every launch, so there is nothing to migrate.
// Before — breaks intermittently under isStoredInMemoryOnly
let container = try ModelContainer(
for: schema,
migrationPlan: AppMigrationPlan.self,
configurations: [config]
)
// After — branch on isStoredInMemoryOnly before applying the migration plan
if config.isStoredInMemoryOnly {
return try ModelContainer(for: schema, configurations: [config])
}
return try ModelContainer(for: schema, migrationPlan: AppMigrationPlan.self, configurations: [config])
This applies to both @main app-launch code (for UI test targets) and any test helper that happens to reuse the app's production container builder instead of a dedicated in-memory one.
What ships with it: 5 files
15.3 KB alongside SKILL.md
references/
- decimal-money-values.md3.1 KB
- import-hash-dedup.md3.9 KB
- mock-repositories.md2.4 KB
- model-actor-testing.md3.4 KB
- model-container-fixtures.md2.5 KB