Espresso — 它是什么、工作原理及如何使用

作者: IT Sectr 发布日期: 2026-04-08 阅读时间: 8 分钟

Espresso 是一个由 Google 团队开发、属于 AndroidX Test 组件的 Android 应用程序自动化 UI 测试框架。与检查封闭组件的工具测试不同,Espresso 与真实 UI 交互:按下按钮、输入文本、检查元素显示。据 Google Android Developers 报道,Espresso 提供与 UI 线程的自动同步,消除了手动 Thread.sleep() 的必要性。

核心要点

  • Espresso — 具有自动线程同步功能的 Android UI 测试框架。
  • ViewMatcher — 根据 ID、文本、父级层级结构在屏幕上搜索 View 元素。
  • ViewAction — 对元素执行的操作:点击、输入文本、滑动。
  • ViewAssertion — 检查元素状态:显示、包含文本、活跃。
  • Idling Resource — 在 UI 检查之前等待异步操作完成的机制。

什么是 Espresso?

Espresso 是一个用于编写自动化 Android UI 测试的库,属于 Google AndroidX Test 的一部分。它提供了用于在屏幕上查找 View 元素、对它们执行操作(点击、输入、滑动)以及检查它们的状态(显示、包含文本、活跃)的 API。

Espresso 的关键特点是与应用程序主线程的自动同步。框架在执行下一步检查之前等待所有异步任务(协程、AsyncTask、Handler)的完成。这消除了与竞争条件相关的不稳定测试,并使 UI 测试稳定可靠 — 没有任何测试包含 Thread.sleep() 或等待循环。

Espresso 遵循 Three-Legged Dog(三脚狗)原则 — 测试由三个步骤组成:查找元素(ViewMatcher)、执行操作(ViewAction)、检查结果(ViewAssertion)。所有三个步骤都写在 onView().perform().check() 的链式调用中。这种概念使测试可预测并易于阅读 — 每个测试明确描述它在搜索什么、做什么以及检查什么。

Espresso 如何工作

架构 Espresso 基于三个组件:Espresso(入口点 — 静态方法 onView 和 onData)、ViewMatchers(搜索元素)、ViewActions(操作)和 ViewAssertions(检查)。在内部,框架使用 Idling Resource 与 UI 线程同步。

基础 Espresso 测试

最简单的测试根据 ID 查找按钮,执行点击并检查“完成”文本是否出现。从测试的角度看,所有操作都是同步执行的 — Espresso 保证 UI 线程在测试继续执行之前已完成事件处理。这是通过内置的等待机制实现的:onView 会阻塞测试执行,直到 UI 变得稳定。

kotlin
@Test
fun buttonClick_showsSuccessText() {
    // 按 ID 查找按钮并点击
    onView(withId(R.id.button_submit))
        .perform(click())

    // 检查“完成”文本是否显示
    onView(withText("完成"))
        .check(matches(isDisplayed()))
}

ActivityScenario 规则

为了启动 Espresso 测试,使用 ActivityScenario (AndroidX Test) 来创建所需状态的 Activity — 运行中、暂停、销毁。ActivityScenario 允许在纯 UI 之外测试 Activity 的生命周期。例如,可以检查数据是否在屏幕旋转时(Activity 重新创建)保存并在销毁后恢复。

ViewMatchers 是来自 Espresso.onView 类的一组方法,可以根据不同标准在屏幕上查找 View:资源标识符 (R.id)、文本、提示信息、父元素和层级结构。如果单个 matcher 没有唯一结果,可以通过 allOf() 组合 matcher。

Matcher用途
withId(R.id.name)根据资源 ID 查找
withText(“文本”)根据显示的文本查找
withHint(“提示”)根据 EditText 的 hint 属性查找
isDisplayed()检查元素是否在屏幕上可见
hasSibling(matcher)根据邻近元素查找
allOf(m1, m2)组合多个 matcher

组合 matcher

如果屏幕上有多个相同元素(例如,两个具有不同文本的 TextView),可以通过 allOf 组合 matcher:onView(allOf(withId(R.id.title), withText(“你好”)))。这保证选择唯一的元素。反向运算符 not() 从搜索中排除元素,而 hasSibling() 在已知元素旁边查找元素。

ViewActions:与 UI 交互

ViewActions 是 Espresso 对查找到的 View 执行的操作:click()typeText()clearText()scrollTo()swipeLeft() 等。操作传递给 perform() 方法,它可以接受多个连续的操作。

操作链

perform() 方法接受 vararg ViewAction,允许对一个元素执行一系列操作:清除字段、输入新文本、关闭键盘并按下按钮。所有操作按列表顺序执行,Espresso 保证前一个操作完成后下一个才开始。

kotlin
// 在 EditText 中输入文本并点击按钮
onView(withId(R.id.edit_email))
    .perform(
        clearText(),
        typeText("user@example.com"),
        closeSoftKeyboard()
    )

onView(withId(R.id.button_login))
    .perform(click())

通过 onData 检查

对于 AdapterView 内的元素(ListView、RecyclerView),使用 onData() 方法代替 onView。它与适配器数据工作,而非 View — 根据模型内容查找元素并返回相应的 View 以供后续操作。onData 使用 hamcrest matcher 根据数据模型的字段查找元素。

ViewAssertions:检查状态

ViewAssertions 检查 View 是否处于特定状态。基础方法 matches(matcher) 检查元素是否符合给定的 matcher。此外,Espresso 提供 doesNotExist()(元素不存在)和 selectedDescendantsMatch()(检查嵌套元素)。

常见检查

UI 测试中最常见的检查:元素显示 (isDisplayed)、元素包含特定文本 (withText)、元素活跃 (isEnabled)、元素未选中 (isNotChecked)。每个检查在失败时都会抛出详细的异常 — 包含屏幕上 View 层级结构的说明。这简化了调试:在错误消息中可以看到检查时刻屏幕上实际存在哪些元素。

自定义 ViewAssertions

如果标准检查不足,可以通过 ViewAssertion 接口创建自己的检查。自定义 assertion 接收 View 并可以用程序方式检查其状态 — 例如,文本颜色、边距或未通过标准 matcher 暴露的自定义组件状态。

kotlin
// 检查:TextView 显示并包含文本
onView(withId(R.id.text_welcome))
    .check(matches(isDisplayed()))
    .check(matches(withText("欢迎")))

// 检查:元素未显示
onView(withId(R.id.progress_bar))
    .check(doesNotExist())

用于异步操作的 Idling Resources

Idling Resource 是 Espresso 用于同步测试与异步操作的机制。默认情况下,Espresso 等待 Handler、AsyncTask 和协程(通过 coroutinesIdlingResource)完成。如果应用程序通过自己的线程或 Callback 服务执行后台工作,则需要注册自定义 Idling Resource。

使用协程的示例

从 AndroidX Test 1.4.0 开始,Espresso 通过 CoroutinesIdlingResource 支持协程。测试会自动等待所有启动的协程完成后再执行 UI 检查。对于更复杂的场景,使用 CountingIdlingResource — 一个计数器,在任务开始时增加并在完成时减少。

kotlin
// 为 OkHttp 注册 IdlingResource
class OkHttpIdlingResource(
    private val client: OkHttpClient
) : IdlingResource {

    private var isIdle = true
    private var watcher: IdlingResource.ResourceCallback? = null

    override fun getName() = "OkHttp"

    override fun isIdleNow() = isIdle

    override fun registerIdleTransitionCallback(
        callback: IdlingResource.ResourceCallback
    ) {
        watcher = callback
    }
}

在 Android 项目中配置 Espresso

连接 在 Android 项目中连接 Espresso 是通过在模块级别的 build.gradle 中添加依赖来完成的。Espresso 是 AndroidX Test 的一部分,因此只需要指定 Espresso 核心、扩展和 JUnit 集成的依赖。测试放置在 src/androidTest 目录中,并通过 AndroidJUnitRunner 在物理设备或模拟器上运行。

Gradle 配置

最小依赖集包括 espresso-core(核心)、espresso-contrib(针对 RecyclerView、Drawer、Picker 的额外 matcher)和 runner(AndroidX 测试运行器)。所有测试通过 Android Test Orchestrator 在模拟器或物理设备上运行。

kotlin
// build.gradle.kts (androidTest dependencies)
android {
    defaultConfig {
        testInstrumentationRunner =
            "androidx.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
    androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
    androidTestImplementation("androidx.test.espresso:espresso-contrib:3.6.1")
    androidTestImplementation("androidx.test:runner:1.6.1")
    androidTestImplementation("androidx.test:rules:1.6.1")
}

在 CI 上运行测试

Espresso 测试可以通过 Google Android Test Orchestrator 运行,它将每个测试隔离在单独的进程中并在运行之间清除状态。这消除了与前一次测试的剩余数据相关的不稳定测试,并提高了 CI 服务器上的稳定性。对于并行运行,使用 sharding — 将测试分配到多个模拟器上。

常见问题

Espresso 与 UI Automator 有什么区别?

Espresso 在应用程序进程内工作,使用与 UI 线程的自动同步。UI Automator 在系统层面工作,可以与其他应用程序交互,但需要手动管理等待。

为什么 Espresso 被称为“三脚狗”框架?

这是来自 Google 演示的比喻:Espresso 测试依赖三个支柱 — ViewMatcher(搜索)、ViewAction(操作)和 ViewAssertion(检查)。如果移除其中任何一个,测试就会失去稳定性,就像一只三脚狗。

如何通过 Espresso 测试 RecyclerView?

对于 RecyclerView,使用 espresso-contrib 库和 onView(withId(R.id.recycler)).perform(actionOnItemAtPosition(0, click())) 方法。替代方案是使用 onData() 处理 AdapterView,或自定义 ViewAction 来根据文本在 RecyclerView 内查找元素。此外,可以使用 espresso-contrib 中的 RecyclerViewActions 滚动到元素并对其执行操作。

什么是不稳定测试,Espresso 如何应对?

不稳定测试 (flaky test) 是指由于竞争条件或异步性而在代码未变的情况下偶尔失败的测试。Espresso 通过 Idling Resource 解决这个问题 — 在执行检查之前等待所有后台任务完成。

可以使用 Espresso 进行截图测试吗?

Espresso 本身不是为截图测试设计的,但可以与像 ShotPaparazzi 这样的库组合使用。Espresso 将 UI 准备到所需状态,比较库拍摄截图并与参考图进行比较。这种方法称为视觉回归测试,有助于发现界面中的意外变化。

总结

  • Espresso — Google 提供的具有自动同步功能的 Android UI 测试框架。
  • ViewMatchers — 用于根据 ID、文本、层级和组合方式搜索元素的 API。
  • ViewActions — 用于与 UI 交互的 click、typeText、scrollTo、swipe。
  • ViewAssertions — 用于检查元素状态的 matches、doesNotExist。
  • Idling Resource — 将测试与异步操作和协程同步。
  • 三个步骤 — onView().perform().check() = 查找、执行、检查。
  • AndroidX Test — 用于在模拟器或设备上运行工具测试的库。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读