搭建测试环境:Gradle依赖配置与AndroidX Test归纳总结
好了,到了真正动手的环节。这一章我们聊的是测试环境怎么搭。说实话,很多项目卡在这一步就放弃了——依赖冲突、版本不匹配、运行报错,各种幺蛾子。我个人习惯先把所有依赖写成一份“清单”,再挨个核对,这样心里才踏实。
核心依赖一览
Mock回放测试,说白了就是给网络请求装个“录像机 + 播放器”。我们需要三样东西:
- Retrofit + OkHttp —— 网络框架本体
- MockWebServer / MockRetrofit —— 模拟服务器
- AndroidX Test 全家桶 —— 测试运行器和断言
下面这张图能帮你快速摸清各组件之间的关系:
一句话总结:你的测试代码通过 AndroidX Test 运行器启动,调用我们封装好的 Mock 回放库,拦截器在 OkHttp 链条里“偷换”请求和响应,最终让 Retrofit 不需要真正的服务器也能工作。
Gradle 依赖配置:建议用 BOM 统一版本
我在项目中遇到过最头疼的事,就是 OkHttp 3.x 和 Retrofit 2.x 的小版本不兼容,导致运行时抛 NoSuchMethodError。所以我的建议是——用 BOM(Bill of Materials) 统一管理版本号。
打开你的 build.gradle(app 模块),在最外层加上这些:
dependencies {
// —— 测试核心依赖 ——
testImplementation "androidx.test:core:1.5.0"
testImplementation "androidx.test:runner:1.5.2"
testImplementation "androidx.test:rules:1.5.0"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.9.3"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.9.3"
// —— 网络测试依赖 ——
testImplementation "com.squareup.okhttp3:mockwebserver:4.11.0"
testImplementation "com.squareup.retrofit2:retrofit:2.9.0"
testImplementation "com.squareup.retrofit2:converter-gson:2.9.0"
// (重点)本课程编写的 Mock 回放库
testImplementation project(':mockreplay-lib') // 或者发布到本地 maven
}
⚠ 我曾经踩过的坑:如果你同时用了 androidx.test:core-ktx 和 androidx.core:core-ktx,务必核对版本号。曾经因为一个 1.8.0 一个 1.9.0,导致测试一直报 ClassNotFoundException,花了我一下午才追到。解决办法:统一用 androidx.test.ext:junit-ktx:1.1.5 代替散落的扩展包。
AndroidX Test 运行器配置
跑单元测试(非仪器化),关键是在 defaultConfig 里指定测试运行器:
android {
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// 如果是纯 JUnit 本地测试,保留这一行即可
}
testOptions {
unitTests {
includeAndroidResources = true // 需要 Android 资源模拟时打开
}
}
}
为什么强调这个?因为 MockWebServer 虽然是纯 Java 库,但如果你在测试里用到了 Context 或者 Resources(比如从 assets 加载回放文件),就必须设置 includeAndroidResources = true,否则会直接挂。
一个真实项目的依赖清单(推荐直接复制)
| 组件 | 推荐版本 | 作用 | 备注 |
|---|---|---|---|
| androidx.test:core | 1.5.0 | 测试基础类(ApplicationProvider 等) | 必选 |
| androidx.test:runner | 1.5.2 | 测试运行器 | 必选 |
| androidx.test:rules | 1.5.0 | 测试规则(如 InstantTaskExecutorRule) | 推荐 |
| junit-jupiter-api | 5.9.3 | JUnit 5 注解和 API | JUnit 4 用户可换 junit:junit:4.13.2 |
| com.squareup.okhttp3:mockwebserver | 4.11.0 | Mock 服务器(模拟 HTTP 响应) | 必选 |
| com.squareup.retrofit2:retrofit | 2.9.0 | Retrofit 核心 | 与生产版本一致 |
| com.squareup.retrofit2:converter-gson | 2.9.0 | JSON 自动解析 | 根据你的序列化方案替换 |
| mockreplay-lib | 0.1.0 | 本课程自研录制/回放拦截器库 | 后续章节详细讲解 |
💡 小技巧:把 OkHttp 和 Retrofit 的版本号提取成 ext.okhttp_version = '4.11.0' 放在项目根 build.gradle 里,所有模块统一引用。这样以后升级版本只需要改一个地方,不会出现“新版 OkHttp 搭配旧版 Retrofit”的悲剧。
常见冲突与解决方案
我整理了一个 checklist,每次加依赖的时候扫一眼:
- JUnit 4 vs JUnit 5 混用——如果你用
@Test注解,需要明确导入org.junit.Test(JUnit4)还是org.junit.jupiter.api.Test(JUnit5)。混用会导致测试方法不被发现。 - kotlin-stdlib 版本不一致——AndroidX Test 某些组件依赖特定 Kotlin 版本。要么统一用 BOM 管理,要么在
configurations.all里强制指定一个版本。 - mockwebserver 的 OkHttp 版本冲突——MockWebServer 本身就是 OkHttp 的测试模块,如果生产代码也引用了不同版本的 OkHttp,会报
Duplicate class。我的做法是:把所有 OkHttp 相关依赖(包括 retrofit)都指向同一个版本。
// 强制统一 OkHttp 版本示例(在 app/build.gradle 中)
configurations.all {
resolutionStrategy {
force "com.squareup.okhttp3:okhttp:4.11.0"
force "com.squareup.okhttp3:logging-interceptor:4.11.0"
}
}
确认环境是否搭建成功
写一个最简单的“冒烟测试”来验证:
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Test
class SmokeTest {
private lateinit var mockServer: MockWebServer
@Before
fun setUp() {
mockServer = MockWebServer()
mockServer.start(8080)
}
@Test
fun testMockServerIsRunning() {
val url = mockServer.url("/")
println("Mock server ready at: $url")
// 能打印出 URL 说明环境没问题
}
@After
fun tearDown() {
mockServer.shutdown()
}
}
运行它。如果控制台能看到 Mock server ready at: http://127.0.0.1:8080/,恭喜你,环境已经搭好。剩下的就是往里面塞“录像”数据了。
这一步看似简单,但请务必验证通过——后面所有 Mock 录制和回放测试都依赖这个基础。我曾经在客户现场发现半天跑不通,最后是 Gradle 缓存没清干净导致的。所以建议每次改完依赖后,执行一次 ./gradlew cleanTest test 确保缓存被刷新。