我有一个Android应用程序,其数据库版本为1。
现在我想更改数据库的结构并编写所有迁移代码等。
我遇到的问题是如何测试。
我需要反复使用旧版本的旧版DB,以便我可以使用新数据库多次测试新应用的更新过程。
我想简化我制作项目副本的事情,然后重新命名 - 将清单和所有内容保持不变!!!!
我的想法是使用Eclipse运行/安装具有旧数据库结构的应用程序的旧版本,以便我可以创建更新的开始情况。
现在模拟用户对新应用程序版本的更新我再次使用Eclipse将其安装在旧版本上 - 但即使没有更改数据库,我也会收到数据库已存在的错误???
我很困惑(我只更改了项目名称,而不是清单)我原本期望我可以在旧版本上安装新版本,并在此测试应用程序的用户更新。
但这不起作用。
我最好怎么做? (在同一个项目中没有旧的和新的数据库代码。因为如果我有相同的项目,我有两个不同的数据库结构,需要在交换机中构建它应该如何启动,即旧的或新的我发现用新的数据库结构编写应用程序的新版本更加清晰。
答案 0 :(得分:1)
会议室是数据库内容的Android架构组件之一。
会议室提供测试Maven工件以协助此测试过程。
首先,您需要通过在room.schemaLocation
文件中设置build.gradle
注释处理器属性来导出数据库方案
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
}
}
@RunWith(AndroidJUnit4.class)
public class MigrationTest {
private static final String TEST_DB = "migration-test";
@Rule
public MigrationTestHelper helper;
public MigrationTest() {
helper = new MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
MigrationDb.class.getCanonicalName(),
new FrameworkSQLiteOpenHelperFactory());
}
@Test
public void migrate1To2() throws IOException {
SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1);
// db has schema version 1. insert some data using SQL queries.
// You cannot use DAO classes because they expect the latest schema.
db.execSQL(...);
// Prepare for the next version.
db.close();
// Re-open the database with version 2 and provide
// MIGRATION_1_2 as the migration process.
db = helper.runMigrationsAndValidate(TEST_DB, 2, true, MIGRATION_1_2);
// MigrationTestHelper automatically verifies the schema changes,
// but you need to validate that the data was migrated properly.
}
}
您可以阅读官方文件for more info
答案 1 :(得分:1)
您可以创建主文件'create.sql'和名为'1.sql,2.sql,..,n.sql'的迁移文件。 例如,将所有这些文件存储在资产中。
如果用户没有数据库,请应用create.sql 如果用户需要从A到Z的数据库升级,则应用+ 1.sql,+ 2.sql,...,z.sql。
您需要实现applyUpgrades方法,该方法将用于升级版本的DB和迁移测试。它看起来像:
fun Context.applyUpgrades(db: SQLiteDatabase, from: Int, to: Int): Unit =
(from+1..to).forEach { index ->
val migrationSql = getMigrationFromAssets(index)
db.execSQL(migrationSql)
}
您的迁移测试将如下所示:
@Test
fun upgrade10to11() { // when you upgrade from 10 to 11
val db = SQLiteDatabase.create(null)
// apply all previous migrations
applyUpgrades(db, from = INITIAL, to = 10)
val valuesBefore = ..
// our new migration
applyUpgrades(db, from = 10, to = 11)
val valuesAfter = ..
// assert that valuesBefore and valuesAfter are correct
}
此外,您可以检查是否忘记了新迁移的写入测试:
@Test
public void hasAllNecessaryTests() {
assertEquals(DB_VERSION, 11);
}
答案 2 :(得分:0)
由于您只需要数据和结构来测试迁移,您可以备份旧数据库并在测试中使用它们。
所以对于每个测试:
这样你只需要进行一次备份,并可以在每次测试时恢复它们。 如果您的测试是自动化的,您甚至可以自动恢复备份。
对于SQLite,进行备份就像复制数据库文件一样简单,但几乎每个数据库都有办法制作和恢复备份。
您的更新应用似乎尝试再次创建数据库(而不是内部数据),但旧应用程序的数据库仍然存在,但仍无法正常工作。 这可能是因为应用程序没有注意到之前安装过它。