测试环境搭建:安装依赖、配置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`,结果跑测试时一直报「未找到测试」,浪费了半小时。
运行配置
配置好之后,怎么跑?我推荐两种方式:
- 直接点绿色三角:在 Android Studio 里,打开测试文件,点击方法左侧的 Run 图标。
- 配置 Gradle Task:在 Gradle 面板里找到 `app` → `Tasks` → `verification` → `connectedCheck`,双击就能跑所有仪器化测试。
如果你只想跑某个特定的测试类,可以在 Run Configuration 里新建一个 Android Instrumented Tests,指定模块和类名。我个人习惯这样,因为项目大了之后跑全量测试太慢。
| 配置项 | 建议值 | 说明 |
|---|---|---|
| kotlinCompilerExtensionVersion | 与 Compose 版本匹配 | 1.6.0 -> 1.5.6(官方对应表为准) |
| androidTestImplementation | ui-test-junit4 | 必须有,否则 ComposeTestRule 用不了 |
| mockk 版本 | 1.13.x | 1.12.x 对 K2 编译器有兼容问题 |
| isMinifyEnabled | false(debug/mocktest) | 混淆后 mock 对象会丢失属性 |
最后再唠叨一句:如果你跑测试时遇到「ClassNotFoundException: kotlinx.coroutines.test.TestCoroutineDispatcher」,那是因为这个类在 1.7.0 之后被移到了内部包,你需要用 `UnconfinedTestDispatcher` 代替。这个坑我踩了三天才爬出来。
以上就是测试环境搭建的全部内容。你按照这个流程走一遍,十分钟内应该能跑起来第一个 Compose 测试。如果遇到卡壳,多半是版本没对齐,回去检查一下 `kotlinCompilerExtensionVersion` 和 Compose 的对应关系——这是最常见的坑,没有之一。