第3章 Gradle依赖声明:BOM版本选择与测试依赖配置
Compose测试夹具工程搭建的第一步就是正确配置Gradle依赖。本章聚焦三个关键决策:compose-bom版本锁定策略、testImplementation与androidTestImplementation的作用域差异以及JUnit与Compose测试库的声明方式。三者共同决定了测试代码能否正确编译、运行在正确的目标上。
本章核心结论
- 始终使用
compose-bom统一管理Compose测试库版本,避免手动硬编码。 - 单元测试(本地JVM)用
testImplementation;仪器化测试(真机/模拟器)用androidTestImplementation。 - Compose测试库
ui-test-junit4和ui-test-manifest需要正确匹配作用域。
3.1 选择compose-bom版本
Compose BOM(Bill of Materials)是一个版本控制模块,声明所有Compose相关库的统一版本。推荐在项目根 build.gradle 或模块级 build.gradle 中使用。
// 模块级 build.gradle
dependencies {
// 引入Compose BOM,版本号根据官方最新稳定版填写
implementation platform("androidx.compose:compose-bom:2024.12.01")
// Compose UI 核心
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-graphics"
implementation "androidx.compose.ui:ui-tooling-preview"
// 测试依赖(见3.2)
testImplementation "junit:junit:4.13.2"
androidTestImplementation platform("androidx.compose:compose-bom:2024.12.01")
androidTestImplementation "androidx.compose.ui:ui-test-junit4"
debugImplementation "androidx.compose.ui:ui-tooling"
debugImplementation "androidx.compose.ui:ui-test-manifest"
}
版本选择原则:
- 检查 官方BOM映射表,选取对应你目标Compose稳定版本的BOM号(如
2024.12.01对应 Compose 1.7.x)。 - 项目中的
composeOptions { kotlinCompilerExtensionVersion }必须与BOM指定的Compose编译器版本匹配。 - 测试依赖也要引用相同BOM,避免版本漂移。
常见陷阱:在 androidTestImplementation 中重复声明不带BOM的 androidx.compose.ui:ui-test-junit4:1.x.x 的固定版本,会覆盖BOM版本,导致测试运行时二进制不兼容。始终优先使用BOM。
3.2 testImplementation vs androidTestImplementation
Gradle的三种依赖作用域直接影响测试代码的运行位置和编译范围:
| 作用域 | 目标测试类型 | 运行环境 | 典型用途 |
|---|---|---|---|
testImplementation |
单元测试(Unit Test) | 本地JVM | 普通JUnit + Mockito + Robolectric |
androidTestImplementation |
仪器化测试(Instrumented Test) | 真机/模拟器 Android 环境 | Compose UI测试、Espresso、UI Automator |
debugImplementation |
仅debug构建 | 本地JVM/设备 | ui-tooling、ui-test-manifest |
选择决策流程:
- 如果测试代码完全不依赖Android系统API(如只测试ViewModel逻辑),用
testImplementation+junit。 - 如果测试需要
ActivityScenario、ComposeTestRule等Android运行时特性,必须用androidTestImplementation。 ui-test-manifest只需要在 debug 构建时提供测试专用AndroidManifest权限,因此放到debugImplementation。
性能建议:尽量将不需要设备环境的测试写成纯JVM单元测试(test 源集),它们执行速度快且无需部署APK。将Compose UI交互测试保留在 androidTest 源集中。
3.3 JUnit与Compose测试库的声明方式
Compose测试框架基于JUnit4。以下是最小化依赖声明:
dependencies {
// JUnit4(用于test源集)
testImplementation "junit:junit:4.13.2"
// Compose BOM(androidTest源集也必须用BOM)
androidTestImplementation platform("androidx.compose:compose-bom:2024.12.01")
// Compose UI测试规则和断言
androidTestImplementation "androidx.compose.ui:ui-test-junit4"
// 仅debug构建需要,提供测试Activity注入
debugImplementation "androidx.compose.ui:ui-test-manifest"
}
各库职责:
ui-test-junit4:提供createComposeRule()、ComposeTestRule、semantics断言等核心测试API。ui-test-manifest:使测试APK能正确注册Compose测试Activity(避免NoActivityResolvedException)。junit:junit:基础测试运行框架,与Compose测试完全兼容。
混淆点澄清:不要将 junit:junit 放入 androidTestImplementation,因为Android默认使用 androidx.test.ext:junit;但为了兼容性,Compose测试库内部已包含JUnit4依赖,通常无需额外声明。然而显式声明 testImplementation "junit:junit:4.13.2" 能确保本地单元测试正常运行。
3.4 依赖关系全貌
下图展示了Compose测试工程中不同Gradle作用域、BOM和测试库之间的调用关系:
3.5 常见错误与调试
| 错误现象 | 根本原因 | 解决方案 |
|---|---|---|
编译错误:Cannot resolve symbol 'createComposeRule' |
ui-test-junit4 放入了 testImplementation |
改为 androidTestImplementation |
运行时错误:No tests found |
测试类放在了 src/test 但依赖是 androidTestImplementation |
将测试移到 src/androidTest 或改用 testImplementation |
崩溃:No ActivityResolvedException |
缺少 ui-test-manifest |
添加 debugImplementation "androidx.compose.ui:ui-test-manifest" |
版本不匹配:KotlinCompilerVersion 警告 |
composeOptions 的编译器版本与BOM隐含版本不一致 |
更新 kotlinCompilerExtensionVersion 匹配BOM对应版本 |
一键验证配置正确性的方法:在Terminal执行 ./gradlew :app:dependencies --configuration androidTestImplementation,查看是否包含正确的 compose-bom 解析树,并确认 ui-test-junit4 版本与BOM一致。