第2章 环境搭建:在Gradle中配置Robolectric依赖
说实话,环境搭建这事儿,看着简单,但坑是真的多。
我见过不少团队,代码写得挺好,一跑测试就崩。最后发现,全是配置问题。嗯,咱们这章就把Robolectric的Gradle配置理顺。把基础打好,后面才不会莫名其妙地翻车。
完成Robolectric环境的Gradle依赖配置、SDK版本选择、测试运行器设置。
一个萝卜一个坑,配置对了,测试跑起来才顺。
2.1 Gradle依赖配置
第一步,打开你的 build.gradle(模块级别)
我个人习惯把测试相关的依赖单独放在 dependencies 块里。这样清晰,也好维护。
android {
// 其他配置...
testOptions {
unitTests {
includeAndroidResources = true
}
}
}
dependencies {
// 核心依赖
testImplementation "org.robolectric:robolectric:4.12.1"
// 如果你用AndroidX测试库
testImplementation "androidx.test:core:1.5.0"
testImplementation "androidx.test:runner:1.5.2"
// 可选:加个JUnit4扩展
testImplementation "junit:junit:4.13.2"
}
我建议把Robolectric版本号提取到项目根级别的
ext 块里。这样多模块项目统一升级,省得每个模块改一遍。
关于版本兼容性
你问Robolectric 4.12能搭配Android Gradle Plugin 8.x吗?答案是早期版本有些问题。
我曾在项目中遇到过:升级AGP到8.2后,Robolectric 4.10.1直接报 ClassNotFoundException。最后查了一圈,是SDK版本映射出了问题。升级到4.12.1就解决了。
| Robolectric版本 | 最低AGP版本 | 建议Gradle版本 | 备注 |
|---|---|---|---|
| 4.9.x | 7.0 | 7.0+ | 老项目推荐 |
| 4.10.x | 7.3 | 7.5+ | 稳定 |
| 4.11.x | 8.0 | 8.0+ | 支持AGP 8.x |
| 4.12.x | 8.2 | 8.2+ | 当前推荐 |
2.2 SDK版本选择
Robolectric会加载对应SDK的framework资源。说白了,你设置的SDK版本决定了测试环境的Android系统版本。
怎么配?
在 build.gradle 的 android 块里,设置默认的compileSdk、targetSdk。Robolectric会从这些值推断测试SDK版本。
android {
compileSdk 34
defaultConfig {
applicationId "com.example.app"
minSdk 21
targetSdk 34
}
}
但有个坑: 你设置的 compileSdk 版本,必须对应Robolectric支持的SDK镜像版本。比如Robolectric 4.12.1内置了SDK 21到SDK 34的镜像。如果compileSdk设为35,测试时会去下载镜像——下载失败就直接挂。
我曾经在项目里把 compileSdk 改成35,结果Robolectric跑不起来。后来发现官方还没发布35的镜像。所以,我建议保持
compileSdk 不超过Robolectric包内置的最高版本。
2.3 测试运行器配置
默认情况下,Robolectric会使用内置的 androidx.test.runner.AndroidJUnitRunner。但你要告诉Gradle,单元测试走Robolectric,而不是真机或模拟器。
配置方式有两种:
- 在 build.gradle 中设置
在每个模块的android.defaultConfig或android.testOptions里指定:
实际上,Robolectric不需要显式替换运行器。它的原理是通过android { defaultConfig { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } }includeAndroidResources = true和依赖库自动注入Shadow类。你只要确保testOptions开启了Android资源支持。 - 自定义TestRunner
如果你需要定制Robolectric的行为,可以建一个自定义Runner:
然后在测试类上用import org.junit.runners.model.InitializationError import org.robolectric.RobolectricTestRunner class CustomRobolectricRunner : RobolectricTestRunner { constructor(klass: Class<*>) : super(klass) { // 可以在这里配置SDK版本、应用包名等 } }@RunWith(CustomRobolectricRunner::class)。
大部分项目不需要自定义Runner。直接用默认的即可。除非你遇到特殊的SDK版本冲突或需要全局覆盖某些配置。
2.4 验证:第一个能跑的测试
配置完成后,写一个最简单的测试来验证环境是否正常:
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.junit.Assert.*
@RunWith(RobolectricTestRunner::class)
class EnvironmentCheckTest {
@Test
fun testSdkVersion() {
val sdk = RuntimeEnvironment.getApiLevel()
println("当前测试SDK版本: $sdk")
assertNotNull(sdk)
}
}
右键运行这个测试。如果绿色通过,说明环境搭建成功。
常见失败原因:
- ClassNotFoundException: Robolectric依赖没加上或版本冲突。
- NoSuchMethodError: Robolectric版本和Android Gradle Plugin不匹配。
- SDK镜像下载失败: 检查网络,或在
settings.gradle中添加阿里云镜像。
如果你们团队在离线内网开发,需要提前下载好Robolectric的SDK镜像文件,放到
~/.m2/repository 目录下。否则第一次运行会卡在下载镜像上。