第4章 环境搭建:Gradle插件配置、Kotlin版本要求、依赖管理、本地调试配置

说实话,环境搭建这一步看起来简单,但我见过不少团队在这上面翻车。不是说配不对,而是版本之间互相打架——Compose编译器版本、Kotlin版本、Gradle插件版本,随便一个没对齐,要么编译报错,要么快照死活生成不了。我记得有一次帮同事排查,折腾了两个小时,最后发现只是他的Kotlin版本比Compose编译器要求的低了一个小版本号。所以这一章,我们把每个细节都掰开讲清楚。

Gradle插件配置,这是入口

Compose快照测试依赖两个Gradle插件:一个是Compose编译器插件本身,另一个是快照测试框架的插件。我个人习惯用Roborazzi,它的插件叫io.github.takahirom.roborazzi。在项目级别的build.gradle.kts里加上:

plugins {
    id("com.android.application") version "8.2.0" apply false
    id("org.jetbrains.kotlin.android") version "1.9.22" apply false
    id("io.github.takahirom.roborazzi") version "1.6.0" apply false
}

然后在模块级别的build.gradle.kts里应用:

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("io.github.takahirom.roborazzi")
}

注意顺序——Kotlin插件必须在Roborazzi之前。为什么?因为Roborazzi的Gradle扩展需要用到Kotlin编译器的一些配置。我在项目中遇到过把插件顺序放反的情况,然后报错说“找不到compose编译器配置”,其实根本不是Compose的问题,就是顺序错了。

关键点: Roborazzi插件会自动适配Compose编译器版本,但前提是Kotlin版本在支持的范围内。后面会细说。

Kotlin版本要求,不能放飞自我

Compose快照测试对Kotlin版本有严格的兼容性要求。以Compose BOM 2024.02.00为例,它要求Kotlin 1.9.22。如果你用Kotlin 1.9.21或1.9.23,表面上可能编译通过,但运行测试时可能遇到“IllegalAccessError: class org.jetbrains.kotlin.compose...”之类的错误。

我个人建议直接使用Compose官方推荐的Kotlin版本。你可以在这里查到最新对应关系:https://developer.android.com/jetpack/androidx/releases/compose-kotlin。但更方便的做法是在build.gradle.kts里声明版本变量,统一管理:

ext {
    kotlinVersion = "1.9.22"
    composeCompilerVersion = "1.5.10"
    roborazziVersion = "1.6.0"
}

避坑提醒: 我曾经遇到过一个项目,用了Kotlin 2.0.0-alpha版本尝试Compose快照,结果Roborazzi里调用的Compose编译器API全变了。嗯,这种情况别想了,老老实实等稳定版。生产环境一定要用稳定版Kotlin。

依赖管理,加对库才能跑

快照测试需要两个核心依赖:一个是运行测试的库(Roborazzi本身),另一个是快照对比的库(通常是AndroidX Test)。在模块的build.gradle.kts的dependencies块里加上:

dependencies {
    // 核心测试依赖
    testImplementation("io.github.takahirom.roborazzi:roborazzi:1.6.0")
    testImplementation("io.github.takahirom.roborazzi:roborazzi-compose:1.6.0")
    
    // 原生UI测试的支持(如果要做instrumentation测试)
    androidTestImplementation("io.github.takahirom.roborazzi:roborazzi:1.6.0")
    androidTestImplementation("io.github.takahirom.roborazzi:roborazzi-compose:1.6.0")
    
    // AndroidX Test 核心库
    testImplementation("androidx.test:core:1.5.0")
    testImplementation("androidx.test.ext:junit:1.1.5")
    testImplementation("androidx.test.espresso:espresso-core:3.5.1")
    
    // Compose UI测试工具
    testImplementation("androidx.compose.ui:ui-test-junit4:1.6.0")
    androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.6.0")
}

这里说明一下:roborazzi-compose提供了Compose专用的快照API,比如captureRoboImage。如果你只写原生View的快照,可以不加这个,但既然我们讲的是Compose快照,那就必须加。

小提示: 如果项目使用多模块,记得在每个需要做快照测试的模块里都重复加一遍依赖。别想在公共模块里加然后子模块继承——因为Roborazzi的plugin会按模块独立注册任务,依赖不写全的话,运行verifyRoborazzi时会找不到类。

本地调试配置,让快照跑起来

配置完Gradle和依赖,我们还要做一件事:让快照测试能在本地调试环境里正常运行。Roborazzi默认支持两种模式:记录模式(生成快照图片)和验证模式(对比图片差异)。本地调试时一般先跑记录模式,确认图片正确后再切回验证模式。

在模块的build.gradle.kts里,可以配置Roborazzi的全局参数:

roborazzi {
    outputDir = "screenshots" // 快照图片输出目录
    compareMode = "similar"   // 默认对比模式:similar(相似度)、exact(精确)
    similarityThreshold = 0.95 // 相似度阈值,低于此值视为不通过
}

你想想看,如果团队里有几个人都在本地调试,最好把outputDir设置成独立目录,避免互相覆盖。我的做法是在local.properties里指定个人目录,然后在build.gradle.kts里读取:

val localProperties = File(rootProject.projectDir, "local.properties")
if (localProperties.exists()) {
    val props = Properties().apply { load(localProperties.inputStream()) }
    val userOutput = props.getProperty("roborazzi.outputDir")
    if (userOutput != null) {
        roborazzi { outputDir = userOutput }
    }
}

这样每个人都能用自己的截图目录,互不干扰。

核心流程总结: 环境搭建的正确步骤是——先配Gradle插件,再锁Kotlin版本,接着加依赖,最后设置本地调试参数。缺一步都有可能跑不起来。

下面这张图把整个流程串起来了,你可以对照着检查自己的配置:

Compose快照回归测试 —— 环境搭建流程 ① 添加Gradle插件 先应用Roborazzi ② 锁定Kotlin版本 ③ 添加测试依赖 ④ 本地调试配置 ⑤ 运行快照测试 ⚠️ 常见陷阱 - 插件顺序错 - Kotlin版本不匹配 - 忘了加Compose依赖 - 输出目录冲突 ✅ 推荐做法 - 版本统一变量管理 - 使用BOM管理Compose版本 - 本地配置文件独立 - CI/CD中强制verify模式

图里标出的五个步骤,每个都有坑。我曾经在图里第①步顺序上栽过跟头,也见过同事在第②步Kotlin版本上纠结半天。所以我的建议是:把这张图打印出来贴在工位旁,配的时候逐项勾选。

最后的检查清单

配置完以后,运行下面这条命令,如果没报错,说明环境搭好了一半:

./gradlew :module:testDebugUnitTest --tests "*.ScreenshotTest"

这时候如果提示No tests found,别慌——说明你的测试类还没写。但Gradle插件和依赖至少加载成功了。如果报类找不到、方法签名不对,那就要回头看看Kotlin版本和Compose编译器版本是不是匹配。可以用下面这个表快速对照:

Compose BOM版本 推荐Kotlin版本 Roborazzi兼容版本
2024.02.001.9.221.6.0+
2024.01.001.9.211.5.0+
2023.10.001.9.101.4.0+
2023.08.001.9.01.3.0+

个人经验: 我一般会在项目的根build.gradle.kts里定义好版本变量,然后在提交CI之前,本地先跑一次./gradlew verifyRoborazzi,确保没有任何环境差异导致的误判。环境搭建这件事,说白了就是一次配置,多次受益。你值得花半小时把它搞稳。