Migration Testing
Migration testing validates that your schema migrations work correctly by loading real frozen databases and attempting to migrate them. This catches crashes and data corruption before production.The Problem
Fresh Installs vs. Migrations
When you test your app in the simulator, you’re almost always testing fresh installs:Migration Crashes Are Silent Killers
Production crashes from broken migrations:Data Corruption Is Worse Than Crashes
Sometimes migrations “succeed” but silently corrupt data:- Non-optional properties added without defaults → undefined behavior
- Transformable properties with changed types → old data becomes nil
- Properties removed → user data silently dropped
- Type conversions fail → data loss
The Solution: Load Real Databases
FreezeRay tests migrations using actual frozen databases from shipped versions:How It Works
1. Frozen Fixtures as Test Data
When you freeze a schema, FreezeRay captures the SQLite database:2. Generate Migration Tests
When you start working on v2.0.0, generate the migration test:3. Runtime Migration Testing
FreezeRayRuntime.testMigration() does the following:
- Copies the frozen v1.0.0 database to a temporary location
- Creates a ModelContainer with your
SchemaMigrationPlan - Attempts migration from v1.0.0 → v2.0.0
- Throws if migration fails or crashes
Test Types
Generated Migration Tests
Created when you start working on a new schema version:- Migration doesn’t crash
- SwiftData can open the migrated database
- Basic migration mechanics work
- Data integrity validation
- Custom migration logic correctness
- Performance
Custom Data Validation
You should add validation to check data integrity:Multi-Hop Migrations
SwiftData runs migrations sequentially: V1 → V2 → V3 FreezeRay tests each hop:- Users might skip app versions (1.0 user updates directly to 3.0)
- Cumulative migrations can expose bugs not visible in single hops
- Data transformations across multiple hops can cause unexpected issues
Common Migration Issues
Issue 1: Modified Shipped Schema
Issue 2: Missing Models
Issue 3: Data Loss in Custom Migrations
Best Practices
Add Meaningful Assertions
Test Edge Cases
Run Tests in CI
Migration tests should run on every PR:Troubleshooting
”Fixture not found” error
Cause: Fixtures not included in test bundle Fix:- Add
FreezeRay/folder to test target resources - Ensure folder reference is “folder” (blue) not “group” (yellow)
Migration test passes locally, fails in CI
Cause: Fixtures not committed to git Fix:Test crashes with “cannot open database”
Cause: Database file permissions in test bundle Fix: Copy fixture to writable location before testing (FreezeRayRuntime does this automatically)Next Steps
Testing Migrations Guide
Step-by-step tutorial for custom validation
Drift Detection
Catch schema changes before testing migrations
Schema Freezing
Learn how to create frozen fixtures
CI Integration
Run migration tests in your CI pipeline