Room Database Migrations: The Step Most Teams Skip
Schema migration tests are usually postponed until crashes appear in production. A tiny migration harness catches most breakages before release.
Step 1: Version every schema snapshot
@Database(entities = [Note::class], version = 5)
abstract class AppDb : RoomDatabase()
Step 2: Write migration tests from old version files
helper.createDatabase(TEST_DB, 4).close()
Room.databaseBuilder(context, AppDb::class.java, TEST_DB)
.addMigrations(MIGRATION_4_5)
.build()
.openHelper.writableDatabase
Step 3: Assert data integrity after migration
val count = db.query("SELECT COUNT(*) FROM notes").use { c -> c.moveToFirst(); c.getInt(0) }
assertEquals(12, count)
Pitfall
Using destructive migration fallback in production builds. It hides failure by deleting user data.
Verification
- All version-to-version paths are tested.
- Data survives migration unchanged.
- Release build disallows destructive fallback.