测试环境搭建:安装依赖、配置Gradle、创建测试目录与运行配置

说实话,搞 Compose 重组测试,最怕的不是写测试代码,而是环境搭半天跑不起来。我以前有个项目,团队里三个人搭出来三种不同的报错,折腾了两天才发现是依赖版本没对齐。所以这一章,咱们把地基打牢。

安装依赖

核心依赖其实就三样:JUnit、Compose UI Test、MockK(或者 Mockito,但 MockK 对 Kotlin 协程支持更好)。我个人习惯用 MockK,因为它的 `coEvery`、`coVerify` 处理挂起函数实在太顺手了。

在 `build.gradle.kts` 的 `dependencies` 块里加上这几行:

// 测试框架
androidTestImplementation("junit:junit:4.13.2")
// Compose UI 测试
androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.6.0")
// MockK
androidTestImplementation("io.mockk:mockk:1.13.8")
// 如果需要协程测试
androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
⚠️ 版本对齐陷阱
Compose 1.6.0 要求 Kotlin 1.9.0+,低于这个版本会直接编译不过。我当初在项目里从 1.5.x 升级时,死活报错找不到 Compose 类,最后发现是 Kotlin 版本没跟着升。建议你直接看 Compose BOM(虽然不能放链接,但记住这个关键词)来统一管理版本。

另外,别忘了在模块的 `build.gradle.kts` 里开启 Compose 实验性 API:

android {
    ...
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.6"
    }
}

配置 Gradle

这一步很容易被忽略——测试用的 `buildType` 需要单独处理。默认 `androidTest` 跑在 debug 下,但如果你有 release 的混淆规则,Mock 会被打成渣。我建议在 `buildTypes` 里加一个专门的 test 构建类型:

buildTypes {
    debug {
        isMinifyEnabled = false
    }
    release {
        isMinifyEnabled = true
        proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
    }
    // 专门跑 mock 测试用的
    create("mocktest") {
        initWith(getByName("debug"))
        matchingFallbacks += listOf("debug")
    }
}

然后在 `src/mocktest/` 目录下放你需要的 Mock 配置。这样做的好处是:测试代码和 release 代码完全隔离,不会因为 ProGuard 误删 mock 类而炸掉。

💡 一个小技巧
在 `gradle.properties` 里加上 `android.useAndroidX=true` 和 `kotlin.code.style=official`,能避免很多奇怪的编译警告。我以前被这些黄线折磨过,后来统一加上了就清静了。

创建测试目录

目录结构直接决定了你的测试能不能被 Gradle 自动识别。标准 Android 项目里,测试分两类:

  • 单元测试:放在 `src/test/java/` 下
  • 仪器化测试(需要真机或模拟器):放在 `src/androidTest/java/` 下

Compose 重组测试属于仪器化测试,因为它需要用 `ComposeTestRule` 在真实 UI 线程上跑。所以你的文件应该长这样:

app/
├── src/
│   ├── main/
│   │   ├── java/com/example/app/
│   │   │   ├── MainActivity.kt
│   │   │   └── ui/
│   │   │       └── components/
│   │   │           └── MyButton.kt
│   │   └── AndroidManifest.xml
│   └── androidTest/
│       └── java/com/example/app/
│           ├── ui/
│           │   └── MyButtonTest.kt
│           └── MainActivityTest.kt

注意,`androidTest` 目录下的 package 路径必须和 `main` 下一致,否则 Gradle 找不到你的测试类。我有一次把 `com.example.app.ui` 写成了 `com.example.app.test`,结果跑测试时一直报「未找到测试」,浪费了半小时。

运行配置

配置好之后,怎么跑?我推荐两种方式:

  1. 直接点绿色三角:在 Android Studio 里,打开测试文件,点击方法左侧的 Run 图标。
  2. 配置 Gradle Task:在 Gradle 面板里找到 `app` → `Tasks` → `verification` → `connectedCheck`,双击就能跑所有仪器化测试。

如果你只想跑某个特定的测试类,可以在 Run Configuration 里新建一个 Android Instrumented Tests,指定模块和类名。我个人习惯这样,因为项目大了之后跑全量测试太慢。

重要参数检查清单:
配置项建议值说明
kotlinCompilerExtensionVersion与 Compose 版本匹配1.6.0 -> 1.5.6(官方对应表为准)
androidTestImplementationui-test-junit4必须有,否则 ComposeTestRule 用不了
mockk 版本1.13.x1.12.x 对 K2 编译器有兼容问题
isMinifyEnabledfalse(debug/mocktest)混淆后 mock 对象会丢失属性

最后再唠叨一句:如果你跑测试时遇到「ClassNotFoundException: kotlinx.coroutines.test.TestCoroutineDispatcher」,那是因为这个类在 1.7.0 之后被移到了内部包,你需要用 `UnconfinedTestDispatcher` 代替。这个坑我踩了三天才爬出来。

测试环境搭建核心流程 安装依赖 配置Gradle 创建测试目录 运行配置 执行测试 关键依赖列表 · JUnit 4.13.2 · ui-test-junit4 · MockK 1.13.8 · coroutines-test 避坑指南 · 版本必须对齐 · 建议使用BOM管理 · 测试buildType隔离release

以上就是测试环境搭建的全部内容。你按照这个流程走一遍,十分钟内应该能跑起来第一个 Compose 测试。如果遇到卡壳,多半是版本没对齐,回去检查一下 `kotlinCompilerExtensionVersion` 和 Compose 的对应关系——这是最常见的坑,没有之一。