创建第一个 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)。同步成功后,项目应能解析所有依赖并生成可执行的测试类。验证步骤:

  1. 在 app/src/test/java/… 下创建一个空测试类,如 ExampleUnitTest.kt,并右键运行。
  2. 在 app/src/androidTest/java/… 下创建一个使用 createComposeRule() 的基本 UI 测试。
  3. 观察 Gradle Console 输出,确认无依赖冲突或 API 版本不匹配。

3.4 项目依赖关系与测试执行流程

下图展示了 Compose 测试项目的依赖层次及从构建到执行的简化流程:

Compose Unit Test 项目依赖与执行流程 Gradle Build System Compose BOM (2024.01.00) app/build.gradle.kts 依赖解析与冲突检测 test / androidTest 源集 编译 & APK / Jar 生成 ComposeTestRule 注入 Activity 测试报告 / 日志输出 关键点 ui-test-manifest 仅 debug BOM 保证版本一致性

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 mismatchKotlin 版本与 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 章编写首个测试用例。