代码之家  ›  专栏  ›  技术社区  ›  Phạm Thành Nam

在testcase espresso之前清除数据库

  •  4
  • Phạm Thành Nam  · 技术社区  · 8 年前

    im使用espresso清除我应用程序中的数据库 Im设置这样的活动

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

    这是我的before函数

    @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 回复  |  直到 4 年前
        1
  •  8
  •   stedi    8 年前

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

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

    为了防止一次执行多个浓缩咖啡测试时出现错误,请使用 Android Test Orchestrator . 它将分别执行所有这些操作。

        2
  •  1
  •   HenriqueMS    5 年前

    如果由于不赞成,您无法使接受的答案生效,我相信检测api已更新为: 仪器注册表 .getInstrumentation() .getTargetContext()

    因此:

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

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

    ApplicationProvider.getApplicationContext<YOUR-APPLICATION>().deleteDatabase("database_name")
    
        3
  •  0
  •   Thomas Gales    6 年前

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

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

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

    每次测试前清除数据库

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

    将以下语句添加到项目的生成中。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'
    }