首页 > 解决方案 > Android Room - 在迁移单元测试期间验证数据库索引的正确性

问题描述

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

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

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

我注意到在生成的模式 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();
    }
}

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

标签: androidunit-testingandroid-sqliteandroid-roomandroidx

解决方案


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

这将是PRAGMA index_list(tablename)& PRAGMA index_info(indexname); 还有PRAGMA schema.index_xinfo(indexname)。我不知道有任何不那么冗长的方法来检查这一点,因为androidx.room:room-testing似乎不支持这一点。但是,当将这样的查询包装到测试方法中时(例如,将表名和索引名作为参数),这仍然可能足够方便,可以认为它是可以接受的。SQLite FAQ也描述了这一点。


类的源代码MigrationTestHelper确认方法onValidateSchema()(第 430 行)不查询WHERE type='index'. 您仍然可以在问题跟踪器上提交功能请求:https ://issuetracker.google.com/issues/new?component=413107&template=1096568

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


推荐阅读