Android O 迁移测试:Room

企业动态
在之前的一篇文章中,我们介绍了一下构件组件,其中就提到了使用 Room 来进行数据库操作。以下是您需要了解的有关 Room 迁移测试的内容。

之前的一篇文章中,我们介绍了一下构件组件,其中就提到了使用 Room 来进行数据库操作。但我们也有注意到,如果您错误地实施迁移,最严重的结果可能会导致您的应用崩溃或丢失用户数据。

[[204036]]

除此之外,Migration.migrate 在编译时不会检查在方法中执行的 SQL 语句,这导致了更多的问题。了解到这个情况之后,对迁移进行测试就成了一项必做任务。 Room 提供了 MigrationTestHelper 测试工具,这一工具允许您:

  • 在给定的版本中创建一个数据库
  • 在数据库上运行一组给定的迁移
  • 验证数据库 schema

当然,Room 不会验证数据库中的数据本身。这是您需要亲自去实现的东西。

以下是您需要了解的有关 Room 迁移测试的内容。

工作原理

[[204037]]

为了进行迁移测试,Room 需要知道您当前数据库版本的几个要素:版本号、Entity、Identity Hash,以及为创建和更新 room_master_table 而做出的查询请求。所有这些都由 Room 在编译时自动生成,并存储在schema JSON 文件中。

在 build.gradle 文件中指定一个文件夹,来放置这些生成的 schema JSON 文件。在更新 schema 时,最终会出现一些 JSON 文件,每个版本都将有一个对应的文件。确保将每个生成的文件提交给源代码管理工具。下次再次增加版本号码时,Room 可以使用 JSON 文件进行测试。

先决条件

要生成 JSON 文件,请使用以下内容更新 build.gradle 文件:

1. 定义 schema 位置

  1. defaultConfig { 
  2.   javaCompileOptions { 
  3.             annotationProcessorOptions { 
  4.                 arguments = ["room.schemaLocation":  
  5.                                 "$projectDir/schemas".toString()] 
  6.             } 
  7.         } 

2. 将 schema 位置添加到源码目录

  1. android { 
  2.      
  3.     sourceSets { 
  4.         androidTest.assets.srcDirs +=   
  5.                            files("$projectDir/schemas".toString()) 
  6.     } 

3. 将 Room 测试库添加到依赖列表中

  1. dependencies { 
  2. androidTestImplementation     
  3.                 “android.arch.persistence.room:testing:1.0.0-alpha5” 

迁移测试规则

创建数据库和 schema,打开和关闭数据库,运行迁移 —— 您几乎需要为每个测试编写大量这样的样板代码。为了避免过度重复劳动,请在迁移测试类中使用 MigrationTestHelper 测试工具。

为了创建数据库以及验证迁移,MigrationTestHelper 很大程度上依赖于生成的 JSON 文件。

  1. @Rule 
  2. public MigrationTestHelper testHelper = 
  3.         new MigrationTestHelper( 
  4.                 InstrumentationRegistry.getInstrumentation(), 
  5.                 <your_database_class>.class.getCanonicalName(), 
  6.                 new FrameworkSQLiteOpenHelperFactory() 

您可以在特定版本中创建数据库:

  1. // Create the database with version 2 
  2. SupportSQLiteDatabase db =  
  3.                          testHelper.createDatabase(TEST 

您可以运行一组迁移,并自动验证 schema 是否更新无误:

  1. db = testHelper.runMigrationsAndValidate(TEST_DB_NAME, 4, validateDroppe 

实施测试

测试策略很简单:

  1. 在特定版本中打开数据库;
  2. 插入一些数据;
  3. 运行迁移并验证 schema;
  4. 检查数据库中是否有正确的数据。

例如,数据库的版本 3 添加了一个新列:date 。因此,当测试从版本 2 到版本 3 的迁移时,我们检查插入到版本 2 的数据的有效性,也是我们新列的默认值。我们的 AndroidJUnitTest 看起来是这样的:

  1. @Test 
  2. public void migrationFrom2To3_containsCorrectData() throws  
  3.                                                        IOException { 
  4.     // Create the database in version 2 
  5.     SupportSQLiteDatabase db =  
  6.                          testHelper.createDatabase(TEST_DB_NAME, 2); 
  7.     // Insert some data 
  8.     insertUser(USER.getId(), USER.getUserName(), db); 
  9.     //Prepare for the next version 
  10.     db.close(); 
  11.  
  12.     // Re-open the database with version 3 and provide MIGRATION_1_2   
  13.     // and MIGRATION_2_3 as the migration process. 
  14.     testHelper.runMigrationsAndValidate(TEST_DB_NAME, 3,    
  15.               validateDroppedTables, MIGRATION_1_2, MIGRATION_2_3); 
  16.  
  17.     // MigrationTestHelper automatically verifies the schema   
  18.     //changes, but not the data validity 
  19.     // Validate that the data was migrated properly. 
  20.     User dbUser = getMigratedRoomDatabase().userDao().getUser(); 
  21.     assertEquals(dbUser.getId(), USER.getId()); 
  22.     assertEquals(dbUser.getUserName(), USER.getUserName()); 
  23.     // The date was missing in version 2, so it should be null in  
  24.     //version 3 
  25.     assertEquals(dbUser.getDate(), null); 

测试从 SQLiteDatabase 到 Room 的迁移

从标准 SQLiteDatabase 到 Room 的步骤虽然乍一看很直观,但我们觉得有必要详细介绍如何测试迁移实现。

因为原本的数据库没有使用 Room 实现,自然我们就没有相应的 JSON 文件,因此我们无法使用 MigrationTestHelper 创建数据库。

我们需要这么做:

  1. 扩展 SQLiteOpenHelper 类,并在 onCreate 执行创建数据库表的 SQL 查询操作;
  2. 在 @Before 测试方法中,创建数据库;
  3. 在 @After 测试方法中,清除数据库;
  4. 使用 SQLiteOpenHelper ,来插入测试所需的数据,检查从SQLiteDatabase 版本迁移到使用 Room 的版本;
  5. 使用 MigrationTestHelper 运行迁移和验证 schema;
  6. 检查数据库数据的有效性。

数据库版本 1 使用 SQLiteDatabase 实现,然后在版本 2 中,我们迁移到了 Room,而在版本 3 中,我们添加了一个新的列。检查从版本 1 到 3 的迁移测试如下所示:

  1. @Test 
  2. public void migrationFrom1To3_containsCorrectData() throws IOException { 
  3.     // Create the database with the initial version 1 schema and     
  4.     //insert a user 
  5.     SqliteDatabaseTestHelper.insertUser(1, USER.getUserName(), sqliteTestDbHelper); 
  6.  
  7.     // Re-open the database with version 3 and provide MIGRATION_1_2  
  8.     // and MIGRATION_2_3 as the migration process. 
  9.     testHelper.runMigrationsAndValidate(TEST_DB_NAME, 3, true, 
  10.             MIGRATION_1_2, MIGRATION_2_3); 
  11.  
  12.     // Get the latest, migrated, version of the database 
  13.     // Check that the correct data is in the database 
  14.     User dbUser = getMigratedRoomDatabase().userDao().getUser(); 
  15.     assertEquals(dbUser.getId(), 1); 
  16.     assertEquals(dbUser.getUserName(), USER.getUserName()); 
  17.     // The date was missing in version 2, so it should be null in    
  18.     //version 3 
  19.     assertEquals(dbUser.getDate(), null); 

挽起袖子试试吧!

[[204038]]

这里有一个示例 App:

https://github.com/googlesamples/android-architecture-components/tree/master/PersistenceMigrationsSample

您可以在此示例应用中查看实现。为了简化比较,每个数据库版本都是以自己的风格实现的,相信看完之后您已经能玩转典型的迁移路径了:

  1. sqlite:使用 SQLiteOpenHelper 和传统的 SQLite 界面;
  2. room :使用 Room 替换实现,并提供到版本 2 的迁移;
  3. room2:将数据库更新为新 schema,版本 3;
  4. room3: 将数据库更新为新的版本 4。提供从版本 2 到 3,版本 3 到 4,以及版本 1 到 4 的迁移路径。

使用 Room,您可以很容易地实施和测试迁移。MigrationTestHelper 允许您在任何版本打开数据库、运行迁移,并且只需几行代码就可以验证 schema。

【本文是51CTO专栏机构“谷歌开发者”的原创稿件,转载请联系原作者(微信公众号:Google_Developers)】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2017-06-30 09:36:10

Android OAPI兼容

2022-12-29 08:57:34

Android本地数据存储

2015-08-28 09:12:44

云测O2O

2022-01-19 12:23:36

云迁移云端

2019-03-25 12:20:29

数据MySQL性能测试

2017-09-18 10:26:05

Android OAndroid应用安装

2013-05-09 10:51:44

2017-08-16 14:08:46

Android O图标视觉

2011-12-14 10:06:55

UnixLinux服务器

2014-06-13 11:25:04

Android 5.0

2017-09-18 22:55:46

GoogleAndroidRTDB

2013-01-15 13:28:24

盈利模式移动互联网O2O

2015-10-15 09:57:08

光合资本

2013-01-15 13:59:14

2013O2O细分领域

2016-05-19 10:57:57

Android N谷歌开发者大会

2011-05-11 09:07:44

AndroidHoneycombAndroid mar

2011-05-24 10:27:18

GoogleAndroidChrome

2017-03-24 19:38:57

AndroidAndroid “O”谷歌

2009-05-31 08:29:02

AndroidGoogle移动OS

2011-12-14 09:46:14

LinuxUnix迁移
点赞
收藏

51CTO技术栈公众号