房间迁移测试失败:未找到架构

Room Migration test failing : schema not found

我正在尝试对我的房间数据库实施 android 测试,以测试迁移。为此,我生成了所需的架构,并按照 Android documentation.

中的步骤操作

当我 运行 我的迁移测试时,它显示无法加载架构,尽管我在 Gradle 构建中添加了资产行。我添加了多种其他构建类型,但没有帮助。我做错了,但我找不到哪里。

房间版本2.3.0

错误:

Cannot find the schema file in the assets folder. Make sure to include the exported json schemas in your test assert inputs. See https://developer.android.com/training/data-storage/room/migrating-db-versions#export-schema for details. Missing file: Asset file database.Sauvegarde/1.json not found
java.io.FileNotFoundException: Cannot find the schema file in the assets folder. Make sure to include the exported json schemas in your test assert inputs. See https://developer.android.com/training/data-storage/room/migrating-db-versions#export-schema for details. Missing file: Asset file database.Sauvegarde/1.json not found
    at androidx.room.testing.MigrationTestHelper.loadSchema(MigrationTestHelper.java:326)
    at androidx.room.testing.MigrationTestHelper.createDatabase(MigrationTestHelper.java:152)
    at globalTests.migrations.MigrationTest.migrate1To2(MigrationTest.java:31)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.rules.TestWatcher.evaluate(TestWatcher.java:61)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner.evaluate(RobolectricTestRunner.java:575)
    at org.robolectric.internal.SandboxTestRunner.lambda$evaluate[=10=](SandboxTestRunner.java:263)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread[=10=](Sandbox.java:89)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

测试结构中:

迁移测试 :

package globalTests.migrations;
import ...;

@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(),
                Sauvegarde.class.getCanonicalName(),
                new FrameworkSQLiteOpenHelperFactory());
    }

    @Test
    public void migrate1To2() throws IOException {
        SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1);


        // 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, Migrations.MIGRATION_1_2);

        // MigrationTestHelper automatically verifies the schema changes,
        // but you need to validate that the data was migrated properly.
    }
}

gradle.build :


        testOptions {
            execution 'ANDROIDX_TEST_ORCHESTRATOR'
        }
        

        javaCompileOptions {
            annotationProcessorOptions {
                arguments += ["room.schemaLocation":
                                      "$projectDir/schemas".toString()]
            }
        }

        sourceSets {
            // Adds exported schema location as test app assets.
            debug.assets.srcDirs += files("$projectDir/schemas".toString())
            customDebugType.assets.srcDirs += files("$projectDir/schemas".toString())
            androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
            test.assets.srcDirs += files("$projectDir/schemas".toString())
        }

模式位置

问题是这样的one,但解决方案对我不起作用...

根据经验,这个问题的一个可能来源是在打包过程中剥离资产,即,如果您有类似下面的规则。它似乎应该只适用于发布版本,但是,唉,它也适用于调试,并且会从视图中删除你的模式文件。

buildTypes {

  debug {...}

  release {
    aaptOptions {
      ignoreAssetsPattern '!*.json'
    }
  }
}

您可以做的另一件事是查看在测试本身可用的各种上下文中哪些资产是可见的:

println("Instrumentation context.assets")
var assets = InstrumentationRegistry.getInstrumentation().context.assets
assets.list("")?.forEachIndexed { index, it ->
  println("$index -> $it")
}

println("Instrumentation targetContext.assets")
assets = InstrumentationRegistry.getInstrumentation().targetContext.assets
assets.list("")?.forEachIndexed { index, it ->
  println("$index -> $it")
}

println("ApplicationProvider context.assets")
assets = ApplicationProvider.getApplicationContext<App>().assets
assets.list("")?.forEachIndexed { index, it ->
  println("$index -> $it")
}

我发现了问题,

Roboelectric 没有为测试导入我的 Android 资源

您需要将此添加到 Gradle:

testOptions {
    unitTests{
       includeAndroidResources = true
    }
}

Source