在testcase espresso之前清除数据库

时间:2018-02-08 08:49:39

标签: android kotlin ui-automation android-espresso

我正在使用espresso清除我的应用中的数据库 我设置这样的活动

@Rule
    @JvmField
    val activity = ActivityTestRule<PhotoPrinterActivity>(PhotoPrinterActivity::class.java,false,false)

这是我之前的功能

    @Before
    open fun setup() {
        clearDatabase()
        activity.launchActivity(null)
        // Waiting for start app success fully

    }

这是我清晰的数据库代码

 fun clearDatabase() {
        val databaseList = InstrumentationRegistry.getInstrumentation().targetContext.databaseList()
        for (database in databaseList) {

            // when transaction rollback files exists they are always locked so we can't delete them
            if (database.contains(".db-journal")) {
                InstrumentationRegistry.getTargetContext().deleteDatabase(database)
                continue
            }

            // when using transaction write ahead logging then this db files are listed but often they don't exist
            if (database.contains(".db-wal") || database.contains(".db-shm")) {
                InstrumentationRegistry.getTargetContext().deleteDatabase(database)
                continue
            }
            Log.v("EspressoMacchiato", "deleting " + database)
            var databasePath = InstrumentationRegistry.getInstrumentation().targetContext.getDatabasePath(database)
            if (databasePath.exists()) {
                InstrumentationRegistry.getInstrumentation().targetContext.deleteDatabase(database)
            }
        }

    }

问题是当数据库成功清除并执行将一些数据添加到数据库中时,

android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:786)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)

任何人都请帮助我!非常感谢!

3 个答案:

答案 0 :(得分:4)

在espresso测试中使用@BeforeClassInstrumentationRegistry删除数据库:

@BeforeClass
public static void beforeClass() {
    InstrumentationRegistry.getTargetContext().deleteDatabase("database_name");
}

要防止一次执行多个espresso测试时出现错误,请使用Android Test Orchestrator。它将分别执行所有这些操作。

答案 1 :(得分:0)

每个测试班一次清除数据库

将以下代码添加到您的Android测试类:

companion object {
    @BeforeClass
    fun clearDatabase() {
        InstrumentationRegistry.getInstrumentation().uiAutomation.executeShellCommand("pm clear PACKAGE_NAME").close()
    }
}

在每次测试前清除数据库

在每次测试运行前清除数据库的另一种方法是在使用Android Test Orchestrator时设置clearPackageData标志。这将“在每次测试后从设备的CPU和内存中删除所有共享状态:”

在项目的build.gradle文件中添加以下语句:

android {
  defaultConfig {
   ...
   testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

   // The following argument makes the Android Test Orchestrator run its
   // "pm clear" command after each test invocation. This command ensures
   // that the app's state is completely cleared between tests.
   testInstrumentationRunnerArguments clearPackageData: 'true'
 }

  testOptions {
    execution 'ANDROIDX_TEST_ORCHESTRATOR'
  }
}

dependencies {
  androidTestImplementation 'androidx.test:runner:1.1.0'
  androidTestUtil 'androidx.test:orchestrator:1.1.0'
}

答案 2 :(得分:0)

如果由于弃用而无法使接受的答案起作用,我相信 Instrumentation api 已更新为: InstrumentationRegistry .getInstrumentation() .getTargetContext()

因此:

InstrumentationRegistry.getInstrumentation().getTargetContext().deleteDatabase("database_name")

或者,您可以获得实际的应用程序上下文(“目标”):

ApplicationProvider.getApplicationContext<YOUR-APPLICATION>().deleteDatabase("database_name")