Android Room - 在迁移单元测试期间验证数据库索引的正确性

Android Room - Verify the correctness of DB indices during migration unit test

我们刚刚开始接触迁移单元测试代码。我们喜欢它,因为它可以帮助我们识别一些错误。

有助于我们验证预期的table结构。

但是,我注意到迁移代码无法检查是否正确创建了索引。如果我故意从迁移中遗漏索引创建代码,单元测试仍然通过。

我注意到在生成的架构 json 文件中,它们包含索引信息。因此,我希望迁移测试代码应该能够捕获丢失的索引。

这是我们的迁移测试代码。

@RunWith(AndroidJUnit4.class)
public class MigrationTest {
    private static final String TEST_DB = "migration-test";

    // Array of all migrations
    private static final Migration[] ALL_MIGRATIONS = new Migration[]{
            new Migration_1_2(),
            new Migration_2_3(),
            new Migration_3_4(),
            new Migration_4_5(),
            new Migration_5_6(),
            new Migration_6_7(),
            new Migration_7_8(),
            new Migration_8_9(),
            new Migration_9_10(),
            new Migration_10_11(),
            new Migration_11_12(),
            new Migration_12_13(),
            new Migration_13_14(),
            new Migration_14_15(),
            new Migration_15_16(),
            new Migration_16_17(),
            new Migration_17_18(),
            new Migration_18_19(),
            new Migration_19_20(),
            new Migration_20_21(),
            new Migration_21_22(),
            new Migration_22_23(),
            new Migration_23_24()
    };

    @Rule
    public MigrationTestHelper helper;

    public MigrationTest() {
        helper = new MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
                MyAppRoomDatabase.class.getCanonicalName(),
                new FrameworkSQLiteOpenHelperFactory());
    }

    @Test
    public void migrateAll() throws IOException {
        // Create earliest version of the database.
        SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1);
        db.close();

        // Open latest version of the database. Room will validate the schema
        // once all migrations execute.
        MyAppRoomDatabaseappDb = Room.databaseBuilder(
                InstrumentationRegistry.getInstrumentation().getTargetContext(),
                MyAppRoomDatabase.class,
                TEST_DB)
                .addMigrations(ALL_MIGRATIONS).build();
        appDb.getOpenHelper().getWritableDatabase();
        appDb.close();
    }
}

我们有什么办法可以验证数据库索引的正确性吗?

您可以直接查询 table sqlite_master - 或使用 PRAGMA 扩展。

这将是 PRAGMA index_list(tablename) & PRAGMA index_info(indexname);还有 PRAGMA schema.index_xinfo(indexname)。我不知道有任何更简洁的方法来检查它,因为 androidx.room:room-testing 似乎不支持它。然而,当将这样的查询包装到测试方法中时(例如,将 table-name 和 index-name 作为参数),这仍然可能足够方便,可以将其视为 acceptable。 SQLite FAQ也描述了。


class的源代码MigrationTestHelper confirms that method onValidateSchema() (line 430) does not query for WHERE type='index'. You still could file a feature request on the issue tracker: https://issuetracker.google.com/issues/new?component=413107&template=1096568

他们能够提供权威的答案。

未验证索引的原因是我正在使用本地单元测试 - https://developer.android.com/training/testing/unit-testing/local-unit-tests

但是,Robolectric 在模拟正确行为时遇到问题

使用 Instrument 单元测试更安全 - https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests

https://developer.android.com/training/data-storage/room/testing-db#test

中提到了这一点

这是 Room 开发团队的一些解释 - https://issuetracker.google.com/issues/176457306