10

我有一个带有版本 1 数据库的 Android 应用程序。

现在我喜欢更改数据库的结构并编写所有迁移代码等。

我遇到的问题是如何测试这个。

我需要反复使用旧版本的应用程序及其旧数据库,这样我就可以使用新数据库多次测试新应用程序的更新过程。

我想简化一些事情,我复制了我的项目并将其重命名为新的 - 保持清单和所有内容不变!!!!

这个想法是使用 Eclipse 运行/安装具有旧数据库结构的旧版本应用程序,这样我就可以创建更新的启动情况。

现在模拟用户更新到新的应用程序版本,我再次使用 Eclipse 将它安装在旧版本上) - 但即使没有更改数据库,我也会收到数据库已经存在的错误???

我很困惑(我只更改了项目名称,而不是清单)我本来希望我可以在旧版本上安装新版本,并在此测试应用程序的用户更新。

但这不起作用。

我将如何最好地做到这一点?(在同一个项目中没有旧的和新的数据库代码。因为如果我有同一个项目,我有两个不同的数据库结构,需要建立一个开关它应该如何启动,即旧的或新的. 我觉得用新的数据库结构编写新版本的应用程序会更干净)

4

3 回答 3

2

Room是用于数据库内容的 Android 架构组件之一。

Room提供了一个测试 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.
    }
}

您可以阅读官方文档以获取更多信息

于 2017-06-23T11:40:05.607 回答
1

您可以创建主文件“create.sql”和名为“1.sql、2.sql、..、n.sql”的迁移文件。例如,将所有这些文件存储在资产中。

如果用户没有数据库,则应用 create.sql 如果用户需要将数据库从 A 升级到 Z,则应用 a+1.sql, a+2.sql, ..., z.sql。

您需要实现将在数据库升级版本和迁移测试中使用的 applyUpgrades 方法。它看起来像:

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);
}

特雷罗保佑

于 2017-07-04T18:16:55.137 回答
0

由于您只需要数据和结构来测试迁移,因此您可以备份旧数据库并在测试中使用它们。

所以对于每个测试:

  • 安装应用程序,放入数据,进行备份(一次)
  • 恢复备份,运行测试(经常)

这样,您只需进行一次备份,并且可以在每次测试时恢复它们。如果您的测试是自动化的,您甚至可以自动恢复备份。

对于 SQLite,制作备份就像复制数据库文件一样简单,但几乎每个数据库都有制作和恢复备份的方法。

您更新后的应用程序似乎再次尝试创建数据库(而不是内部数据),但旧应用程序的数据库仍然存在,这将无法正常工作。这可能是由于应用程序没有注意到它之前安装过造成的。

于 2016-01-01T16:17:21.327 回答