测试依赖必须严格区分:testimplementation用于本地jvm单元测试(如junit、mockito),不打入apk;androidtestimplementation用于设备/模拟器上的仪器化测试(如espresso),需单独声明且不继承主模块依赖,混用会导致运行时类找不到或安全风险。

测试依赖必须按运行环境严格分到 testImplementation 或 androidTestImplementation,混用或错放会导致编译通过但运行失败、类找不到、IDEA 无法识别测试类等问题。
本地 JVM 单元测试用 testImplementation
所有在开发机上跑的纯 Java/Kotlin 测试(不依赖 Android 框架),比如 JUnit、Mockito、Robolectric 的测试代码,必须声明在 testImplementation 块里。
-
testImplementation只参与test任务的编译与执行,不会打进 APK,也不会污染主模块的 classpath - 如果误放到
implementation,会增大 APK 体积,且可能因重复类引发duplicate class错误 - Robolectric 需要
testImplementation+testRuntimeOnly(如testRuntimeOnly("org.robolectric:robolectric:4.10.3"))才能加载 Android 环境资源
设备/模拟器上运行的仪器化测试用 androidTestImplementation
所有需要真正 Android Runtime(ART)、调用 Context、Activity、系统服务的测试,比如 Espresso、UIAutomator、AndroidJUnitRunner 相关代码,必须走 androidTestImplementation。
- 这个配置只对
androidTest源集生效,Gradle 会自动将其打包进androidTestAPK,并和主 APK 一起安装到设备 - 若错放成
testImplementation,编译能过,但运行时会报ClassNotFoundException(找不到androidx.test.espresso.Espresso等类) - 注意
androidTestImplementation默认不继承主模块的implementation依赖,需显式声明所需库(如androidx.test:core)
常见错误:把测试依赖写进 implementation 或 api
这是最常踩的坑——看着测试能跑通就以为没问题,但实际已埋下隐患:
- 测试代码被意外打包进正式 APK,违反安全规范,也可能触发 ProGuard 混淆异常
- 模块 A 用
api暴露了测试库,模块 B 依赖 A 后,B 的主代码也能访问到Mockito类,导致编译期“合法”但运行期崩溃 - CI 构建时启用
test以外的任务(如assembleDebug)会跳过test*配置,但误放的依赖仍参与构建,造成版本冲突或类路径污染
真正容易被忽略的是:Android 项目里 testImplementation 和 androidTestImplementation 是两个完全隔离的 classpath,它们之间默认不共享任何东西。哪怕你写了 testImplementation 'junit:junit:4.13.2',也不能指望它在 androidTest 里自动可用——该配还得配。











