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
我们刚刚开始接触迁移单元测试代码。我们喜欢它,因为它可以帮助我们识别一些错误。
有助于我们验证预期的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