You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Espresso和Junit在测试套件之间清除应用数据

问题根因

你当前的代码无法生效有两个核心原因:

  • 规则作用域错误:父套件RegressionTests上的@ClassRule只会在全部子测试套件执行完成后触发一次,不会在每个子套件执行的间隙执行,达不到套件之间清数据的需求
  • 执行逻辑错误:pm clear 包名会直接终止当前应用的所有进程,你的测试代码本身就运行在应用进程中,执行该命令后测试进程直接被杀,后续测试自然无法继续运行
解决方案

方案一:手动清理应用本地数据(推荐)

不需要执行shell命令,直接在代码内删除所有应用持久化数据,不会杀掉测试进程,后续测试可以正常运行。
首先实现通用清理方法:

import android.content.Context
import android.webkit.WebView
import java.io.File

fun clearAllAppData(context: Context) {
    // 清空所有SharedPreferences
    File(context.filesDir.parentFile, "shared_prefs").takeIf { it.exists() && it.isDirectory }
        ?.listFiles()?.forEach { it.delete() }
    // 删除所有本地数据库
    context.databaseList().forEach { context.deleteDatabase(it) }
    // 清空内部存储目录
    context.filesDir.deleteRecursively()
    // 清空缓存目录
    context.cacheDir.deleteRecursively()
    // 如有使用WebView,同步清空WebView缓存
    WebView(context).clearCache(true)
}

之后删除父套件RegressionTests里的ExternalResource规则,给每一个子测试套件(AuthenticationTests、AuthenticationInvalidTests、CreateAccountTests等)都添加如下@ClassRule:

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.ClassRule
import org.junit.rules.ExternalResource

class AuthenticationTests {
    companion object {
        @ClassRule
        @JvmField
        val clearDataRule = object : ExternalResource() {
            // 建议放在before执行,避免上个套件异常未走到after导致数据残留
            override fun before() {
                val targetContext = InstrumentationRegistry.getInstrumentation().targetContext
                clearAllAppData(targetContext)
            }
        }
    }

    // 原有测试用例逻辑
}

这样每个套件执行前都会保证应用处于干净状态,也不会影响后续测试运行。

方案二:需使用pm clear命令的场景

如果有特殊场景必须依赖pm clear执行清理,需要通过UIAutomation执行shell命令,避免直接调用Runtime阻塞进程,执行前需要确保测试应用已申请相关权限:

override fun before() {
    val context = InstrumentationRegistry.getInstrumentation().targetContext
    val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
    // 执行pm clear命令
    uiAutomation.executeShellCommand("pm clear ${context.packageName}").use {
        // 等待命令执行完成
        ParcelFileDescriptor.AutoCloseInputStream(it).readBytes()
    }
}

该方案稳定性低于手动清理,仅作为备选。

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:36:03