创建第一个 Compose 单元测试项目:项目结构、依赖添加、Gradle 同步
在本章中,你将亲手搭建一个专用于 Compose 单元测试的 Android 项目。我们将从标准项目结构出发,精确配置 build.gradle 依赖,并完成 Gradle 同步,使测试环境可编译、可运行。整个过程遵循“稳定依赖版本 + 最小必要配置”原则,避免引入不兼容的库或冗余插件。
3.1 项目结构总览
一个标准的 Compose 单元测试项目通常包含以下模块与目录(以 Android 单模块应用为例):
| 目录 / 文件 | 用途 |
|---|---|
app/src/main/java/… | 生产代码(包含 Compose 界面) |
app/src/test/java/… | 本地 JVM 单元测试(不依赖设备,可测试 Compose 状态逻辑) |
app/src/androidTest/java/… | 仪器化测试(需设备/模拟器,用于 Compose UI 渲染与交互验证) |
app/build.gradle.kts 或 .gradle | 模块级构建脚本,核心依赖入口 |
settings.gradle.kts | 项目模块声明 |
gradle/libs.versions.toml(可选) | 版本目录,统一管理依赖版本号 |
关键原则:测试代码与生产代码保持相同包名(package),并分置于
test 与 androidTest 源集,Gradle 会自动识别编译。
3.2 依赖添加:精确到 API 与配置
以下是模块级 build.gradle.kts 中必须包含的 Compose 测试依赖。注意 debugImplementation 与 androidTestImplementation 的作用域差异:
android {
// 确保与 Compose 编译器兼容的 compileSdk 与 kotlinCompilerExtensionVersion
compileSdk = 34
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.8"
}
// 测试配置
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
// Compose BOM —— 统一管理 Compose 库版本
val composeBom = platform("androidx.compose:compose-bom:2024.01.00")
implementation(composeBom)
// 基础 Compose UI
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui-tooling-preview")
debugImplementation("androidx.compose.ui:ui-tooling")
// Compose 测试核心
debugImplementation("androidx.compose.ui:ui-test-manifest") // 仅 debug 模式,提供测试 Activity
// 本地单元测试(JVM)
testImplementation("junit:junit:4.13.2")
testImplementation("androidx.compose.ui:ui-test-junit4") // 提供 ComposeTestRule 等
// 仪器化测试(设备)
androidTestImplementation(composeBom)
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation("androidx.test:runner:1.5.2")
androidTestImplementation("androidx.test:rules:1.5.0")
}
常见错误:若
debugImplementation("androidx.compose.ui:ui-test-manifest") 遗漏,运行 createComposeRule() 时将抛出 No activity found 异常。
3.3 Gradle 同步与首次验证
完成依赖声明后,执行 Gradle 同步(Android Studio 工具栏中点击 “Sync Now” 或命令行 ./gradlew build)。同步成功后,项目应能解析所有依赖并生成可执行的测试类。验证步骤:
- 在
app/src/test/java/…下创建一个空测试类,如ExampleUnitTest.kt,并右键运行。 - 在
app/src/androidTest/java/…下创建一个使用createComposeRule()的基本 UI 测试。 - 观察 Gradle Console 输出,确认无依赖冲突或 API 版本不匹配。
3.4 项目依赖关系与测试执行流程
下图展示了 Compose 测试项目的依赖层次及从构建到执行的简化流程:
3.5 调试常见错误
| 错误现象 | 根因 | 解决方案 |
|---|---|---|
No matching variant of … was found | 测试依赖作用域错误(如用 implementation 代替 androidTestImplementation) | 检查依赖配置,将仪器测试依赖改为 androidTestImplementation |
composeTestRule.activity == null | 缺少 ui-test-manifest 或测试类未使用 @RunWith(AndroidJUnit4::class) | 添加 debugImplementation("androidx.compose.ui:ui-test-manifest") 并正确标注 Runner |
Kotlin compiler extension version mismatch | Kotlin 版本与 kotlinCompilerExtensionVersion 不兼容 | 对照官方兼容性表调整 Kotlin 版本或 BOM 版本 |
Could not resolve … compose-bom:2024.01.00 | 网络或仓库缺失 | 检查 settings.gradle.kts 中是否包含 google() 和 mavenCentral() |
性能优化习惯:在本地测试中避免创建完整 Compose 树,优先使用
createComposeRule();在 CI 环境中建议缓存 Gradle dependencies 以缩短同步时间。
3.6 项目结构完整示例
最终的项目骨架应类似如下(以包名 com.example.composetest 为例):
app/
├── build.gradle.kts
├── src/
│ ├── main/
│ │ ├── java/com/example/composetest/
│ │ │ └── MainActivity.kt
│ │ └── AndroidManifest.xml
│ ├── test/java/com/example/composetest/
│ │ └── ExampleUnitTest.kt // 纯逻辑测试
│ └── androidTest/java/com/example/composetest/
│ └── ComposeUITest.kt // UI 测试,使用 composeTestRule
settings.gradle.kts
gradle/wrapper/gradle-wrapper.properties
确保 AndroidManifest.xml 中声明了启动 Activity,否则 createComposeRule() 无法自动注入。至此,你的第一个 Compose 单元测试项目已搭建完成,Gradle 同步无误后即可进入第 4 章编写首个测试用例。