配置错误:未正确配置 compose-snapshot 插件
快照回归测试跑不起来了?构建日志里飘着一堆 ClassNotFoundException?
别急。我敢打赌,八成是 compose-snapshot 插件压根没配对。这个坑,我自己就踩过两回,每次都能浪费一个下午。
插件的“正确姿势”
先看一个最常见的错误配置:
// ❌ 错误写法
plugins {
id 'org.jetbrains.compose' version '1.5.0'
}
// 或者更离谱的:
plugins {
id 'compose-snapshot' version '1.0.0'
}
嗯,上面两个都不对。第一个只配了 Compose 编译器插件,少了快照相关的任务;第二个直接把 artifact ID 写错了。
正确的做法,是同时声明 两个 插件:
// ✅ 正确配置
plugins {
id 'org.jetbrains.compose' version '1.5.0'
id 'org.jetbrains.kotlin.plugin.compose' version '1.9.0' // Compose 编译器
}
gradle.properties 里统一管理版本号,避免多个地方写死。
插件声明了,但快照任务还是找不到?
你需要检查两件事:
- 插件是否应用到了正确的模块——快照回归一般只在
app或ui-tests模块里用,别一股脑加到所有子项目 - 是否配置了快照的 source set
看一个真实案例。我去年接手的一个项目,build.gradle.kts 里只配了 id("org.jetbrains.compose"),但没配 kotlin.plugin.compose。结果 composeScreenshotTest 任务压根不出现。当时我查了半小时,最后还是 gradle 的 task list 提醒了我——竟然没有 screenshot 相关的 task。
compose-compiler 的独立 Gradle 插件(比如 org.jetbrains.kotlin.plugin.compose),必须在 plugins 块中显式声明;光靠 org.jetbrains.compose 传递依赖是不行的。
常见配置遗漏与修复对照表
| 现象 | 原因 | 修复方法 |
|---|---|---|
| Task 'composeScreenshotTest' not found | 缺少 kotlin.plugin.compose | 在 plugins 块添加 id("org.jetbrains.kotlin.plugin.compose") version "1.9.0" |
| 生成截图都是空白/错误颜色 | Compose compiler 版本与 Kotlin 版本不兼容 | 检查 Kotlin 版本与 Compose compiler 插件的版本对应表 |
构建失败:无法解析符号 ScreenshotTest | 没开启 compose.experimental.screenshot.enabled | 在 gradle.properties 中添加 compose.experimental.screenshot.enabled=true |
composeScreenshotTest 运行了,但不生成 PNG | 缺少 composeScreenshots 目录或测试类没有 @ScreenshotTest 注解 | 确保测试类上有注解,且测试方法调用了 captureScreenshot() |
gradle.properties 里的开关
还有一个容易被忽略的地方——实验开关。Compose 快照功能在 1.5.x 时代还是实验性的。你需要手动开启:
# gradle.properties
org.jetbrains.compose.experimental.screenshot.enabled=true
不写这行,插件再对也没用。说白了,编译器根本不会去生成截图相关代码。
gradle.properties 中集中管理所有实验特性开关,并在 README 里列出来。新成员入职时,第一件事就是让他们对照这份清单检查配置。
模块级 build.gradle 的完整配置样板
给你一个我在生产项目中用的模板(Kotlin DSL):
// app/build.gradle.kts
plugins {
id("com.android.application")
kotlin("android")
id("org.jetbrains.compose") version "1.5.10"
id("org.jetbrains.kotlin.plugin.compose") version "1.9.21"
}
android {
namespace = "com.example.snapshotdemo"
compileSdk = 34
defaultConfig {
applicationId = "com.example.snapshotdemo"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
}
buildFeatures {
compose = true
}
}
dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.uiTest)
implementation(compose.materialIconsExtended)
// 快照测试依赖
testImplementation("org.jetbrains.compose:compose-screenshot-test:1.5.10")
}
// 可选:配置截图输出目录
composeScreenshots {
outputDirectory.set(project.layout.buildDirectory.dir("screenshots"))
}
compose.uiTest 是用于 JVM 平台测试的工件。如果你跑 Android 测试,需要换成 androidx.compose.ui:ui-test-junit4。
配置检查清单(快速诊断)
- 确认
plugins块包含 两个 插件:org.jetbrains.compose和org.jetbrains.kotlin.plugin.compose - 确认
gradle.properties中有org.jetbrains.compose.experimental.screenshot.enabled=true - 确认测试模块的
dependencies里引入了compose-screenshot-test - 确认测试类上加了
@ScreenshotTest注解(非@Test) - 确认 Gradle 版本 >= 7.5(我遇到过因为 Gradle 太旧导致插件不加载的案例)
compose-screenshot-test 加到了 androidTestImplementation 而不是 testImplementation,结果在 JVM 单元测试里死活找不到 captureScreenshot() 方法。记住:快照测试是 JVM 单元测试,不是 instrumentation 测试。
一个我踩过的坑:插件版本不匹配
有一次,我升级 Kotlin 到 1.9.22,但 Compose 编译器插件版本还停留在 1.9.20。结果编译通过了,但是快照截图全是白色。查了半天,发现是 Compose 内部的 ScreenshotUtil 类使用了新 API,旧插件不认识。
解决方案:到 JetBrains Compose Multiplatform 版本兼容矩阵 里查一下,确保三个版本都对齐:
- Kotlin 版本
- Compose 多平台插件版本(org.jetbrains.compose)
- Compose 编译器插件版本(kotlin.plugin.compose)
说白了,这三者必须像齿轮一样咬合。差一个次版本都可能出怪问题。
终极检查:一行命令搞定
我建议你保存这个 Gradle 任务,每次怀疑配置有误时跑一下:
./gradlew :app:dependencies --configuration implementation | grep compose
看看输出里有没有 compose-screenshot-test。如果没出现,说明依赖压根没加上。如果出现了但版本不对,那就是另一个故事了。
app/Tasks/verification,确认能看到 composeScreenshotTest 这个 task。如果看不到,100% 是插件没配好。
小结
配置错误是最容易修复、但也最容易忽略的问题。记住三句话:
- 两个插件一个不能少(compose + compiler)
- 实验开关必须开(gradle.properties)
- 测试依赖加对 scope(testImplementation 不是 androidTestImplementation)
做到这三点,恭喜你,90% 的配置问题已经解决了。剩下的 10% 可能出在版本兼容上——对照兼容表就完事了。