Skip to content

截图测试 (Screenshot Testing)

源:Paparazzi | Roborazzi

UI 测试通常验证“按钮是否可点”,而截图测试验证“像素是否偏移”。对于防止 UI 回归(Regression)至关重要。

1. 为什么需要截图测试?

  • 无需真机: 它们通常在 JVM 上运行,速度极快(几秒钟生成数百张图)。
  • 像素级精确: 哪怕是 1px 的 padding 变化都能被检测出来。
  • 版本控制: 截图作为 Git 的一部分,Code Review 时可以直接看到 UI 变化。

2. 工具选择

目前主流的两个库:

特性Paparazzi (Cash App)Roborazzi (Takahirom)
原理使用 Android Studio 的 LayoutLib (Preview 引擎)使用 Robolectric (无头 Android 模拟器)
速度极快较快
准确度接近 Preview,可能有细微差异接近真实设备行为
交互支持不支持 (静态渲染)支持点击、滚动后再截图

3. 使用 Paparazzi

配置

kotlin
// build.gradle
plugins {
    id("app.cash.paparazzi") version "1.3.1"
}

编写测试

kotlin
class ButtonSnapshotTest {
    @get:Rule
    val paparazzi = Paparazzi(
        deviceConfig = DeviceConfig.PIXEL_5,
        theme = "android:Theme.Material.Light.NoActionBar"
    )

    @Test
    fun snapButton() {
        paparazzi.snapshot {
            MyTheme {
                Button(onClick = {}) { Text("Snapshot Me") }
            }
        }
    }
}

运行

  • ./gradlew recordPaparazzi: 生成基准截图(Golden Images)。
  • ./gradlew verifyPaparazzi: 运行测试并对比当前截图与基准截图。

如果对比失败,它会生成一个带有差异高亮的 HTML 报告。

4. 最佳实践

  1. 为组件库编写截图测试: 确保原子组件(Button, Card, Input)的稳定性。
  2. 测试不同配置: 利用 Parameterized Test 自动测试 Light/Dark 模式、不同字体缩放、RTL 布局。
  3. 不要测试整个屏幕: 屏幕太复杂且易变,容易导致测试频繁失败(Flaky)。专注于组件级测试。