3. Gradle依赖声明

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

选择决策流程:

  1. 如果测试代码完全不依赖Android系统API(如只测试ViewModel逻辑),用 testImplementation + junit。
  2. 如果测试需要 ActivityScenario、ComposeTestRule 等Android运行时特性,必须用 androidTestImplementation。
  3. 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和测试库之间的调用关系:

Compose测试依赖作用域与流转图 模块build.gradle compose-bom:2024.12.01 版本锁定(implementation) testImplementation 本地JVM环境 junit:junit:4.13.2 Mockito / Robolectric androidTestImplementation 模拟器/真机 Android环境 androidx.compose.ui:ui-test-junit4 ComposeTestRule + Semantics debugImplementation 仅debug构建 ui-test-manifest 测试Activity注册 测试执行阶段 test 源集 → 本地JVM | androidTest 源集 → 设备APK部署 注意:BOM版本只对implementation和androidTestImplementation生效,但不能用于testImplementation

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一致。