使用测试套件进行屏幕截图测试

从 Android Gradle 插件 (AGP) 9.5.0-alpha03 和 Compose 预览版屏幕截图测试引擎 0.0.1-alpha16 开始,屏幕截图测试已与 AGP 的原生测试套件框架集成。

此方法取代了独立的屏幕截图插件 (com.android.compose.screenshot)。我们建议采用 AGP 测试套件,原因如下:

  • 原生 Gradle 任务生命周期:屏幕截图测试直接集成到标准 Gradle 和 AGP 测试生命周期中,从而提高任务隔离性和测试作业可靠性。
  • 支持多变体和自定义测试套件:您可以在单个模块中创建多个不同的屏幕截图测试套件(例如 screenshotTestuiTestssmokeTests),并以特定 build 变体(例如 demoDebugrelease)为目标,而不是仅限于单个预配置的源代码集。
  • 提升了构建性能和隔离性:AGP 测试套件使用内置制品转换(例如 Layoutlib 运行时提取)和隔离的类加载,并完全支持 Gradle 配置缓存和项目隔离。

要求

如需将 Compose 屏幕截图测试与测试套件搭配使用,请确保您的环境满足以下要求:

  • Android Studio Rabbit 1 Canary 4 或更高版本。
  • Android Gradle 插件 (AGP) 版本 9.5.0-alpha03 或更高版本。
  • Compose 屏幕截图引擎版本 0.0.1-alpha16 或更高版本。
  • JDK 版本 17 或更高版本。
  • 已为您的项目启用 Compose。我们建议使用 Compose 编译器 Gradle 插件启用 Compose。

设置和配置

如需使用测试套件配置 Compose 屏幕截图测试,请完成以下步骤:

1. 启用实验性标志

在项目的根 gradle.properties 文件中,启用屏幕截图测试和测试套件支持:

android.experimental.enableScreenshotTest=true
android.experimental.testSuiteSupport=true

2. 在 build.gradle.kts 文件中配置测试套件

在模块的 build.gradle.kts 文件中,于 testOptions 代码块内定义屏幕截图测试套件:

android {
    testOptions {
        screenshotTests.create("screenshotTest") { // suiteName can be customized (for example, "uiTests")
            engineVersion = "0.0.1-alpha16"
            targetVariants.add("demoDebug") // Add specific variants to test

            dependencies {
                implementation(libs.androidx.compose.ui.tooling)
                implementation("com.android.tools.screenshot:screenshot-validation-api:0.0.1-alpha16")
            }
        }
    }
}

3. 创建测试源代码集

创建一个与您的套装名称匹配的专用源代码集目录:

{module}/src/{suiteName}/kotlin/

例如,对于名为 screenshotTest 的测试套件:

feature/foryou/impl/src/screenshotTest/kotlin/com/example/app/ForYouScreenTest.kt

4. 定义可组合项预览测试

使用 @PreviewTest 和标准 @Preview 或多预览注解来注解可组合项:

package com.example.app

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.android.tools.screenshot.PreviewTest
import com.example.app.ui.theme.AppTheme

@PreviewTest
@Preview(showBackground = true)
@Composable
fun ForYouScreenPreview() {
    AppTheme {
        ForYouScreen(isSyncing = false)
    }
}

运行屏幕截图测试

AGP 测试套件会根据您的套件名称、目标和变体生成专用 Gradle 任务。

1. 生成或更新参考图片

渲染可组合项预览并存储黄金基准参考图片:

  • Linux 和 macOS./gradlew update{SuiteName}{Target}{Variant}TestSuite (例如,./gradlew updateScreenshotTestDefaultDemoDebugTestSuite
  • Windowsgradlew updateScreenshotTestDefaultDemoDebugTestSuite

参考图片已生成并保存到以下位置:

{module}/src/{suiteName}{Target}{Variant}/reference/

2. 验证和运行测试

渲染新的屏幕截图,并将其与参考图片进行比较:

  • Linux 和 macOS./gradlew test{SuiteName}{Target}{Variant}TestSuite (例如,./gradlew testScreenshotTestDefaultDemoDebugTestSuite
  • Windowsgradlew testScreenshotTestDefaultDemoDebugTestSuite

检查测试报告

如果检测到差异或测试失败,AGP 会生成 HTML 测试报告。

  • 报告位置{module}/build/reports/tests/{taskName}/index.html(例如,app/build/reports/tests/testScreenshotTestDefaultDemoDebugTestSuite/index.html

更新后的报告包含以下内容:

  • 标题元数据卡片:显示测试名称、预览方法、变体、套件和状态徽章。
  • 错误分类:明确标记 Reference Image MissingImage Size MismatchPixel Mismatch,并提供可复制的堆栈轨迹。
  • 动态视觉差异:以较低强度突出显示细微修改,以高对比度强调重大更改,以防止嵌套元素吞噬。

从旧版独立插件迁移

如需从旧版独立屏幕截图插件迁移到 AGP 测试套件,请更新 Gradle 配置和任务命令。

构建配置 DSL 比较

旧版独立插件(已弃用)

// In build.gradle.kts
plugins {
    alias(libs.plugins.screenshot)
}

dependencies {
    screenshotTestImplementation(libs.androidx.compose.ui.tooling)
    screenshotTestImplementation("com.android.tools.screenshot:screenshot-validation-api:0.0.1-alpha16")
}
// In build.gradle.kts
android {
    testOptions {
        screenshotTests.create("screenshotTest") {
            engineVersion = "0.0.1-alpha16"
            targetVariants.add("demoDebug")

            dependencies {
                implementation(libs.androidx.compose.ui.tooling)
                implementation("com.android.tools.screenshot:screenshot-validation-api:0.0.1-alpha16")
            }
        }
    }
}

任务和路径映射

概念 旧版设置(已弃用) AGP 测试套件(推荐)
更新任务 ./gradlew updateDebugScreenshotTest ./gradlew update{SuiteName}{Target}{Variant}TestSuite
测试任务 ./gradlew validateDebugScreenshotTest ./gradlew test{SuiteName}{Target}{Variant}TestSuite
参考路径 src/screenshotTestDebug/reference src/{suiteName}{Target}{Variant}/reference
报告路径 build/reports/screenshotTest/debug/ build/reports/tests/{taskName}/