Android多模块测试问题:模块B测试无法引用模块A测试代码
嘿,我来帮你搞定这个头疼的问题!你遇到的核心痛点是:模块B的单元测试想继承模块A里的基础测试类,但构建时只能访问A的生产代码,尝试手动引用测试输出还报了属性找不到的错误。这其实是因为你用了过时的Gradle写法,而且没用到AGP(Android Gradle Plugin)提供的官方测试共享方案。
下面给你两种靠谱的解决方案,优先推荐第一种官方方案:
方案1:用AGP官方的Test Fixtures(AGP 7.0+ 推荐)
这是Google官方推荐的跨模块共享测试代码的方式,既能保证依赖隔离,又能自动处理测试依赖的传递性。
步骤1:在模块A中开启Test Fixtures支持
打开模块A的build.gradle(如果用Kotlin DSL就是build.gradle.kts),添加Test Fixtures的启用配置:
Groovy DSL 写法:
android { // 保留你原来的compileSdk、defaultConfig等配置 testFixtures { enable = true } }
Kotlin DSL 写法:
android { // 保留你原来的compileSdk、defaultConfig等配置 testFixtures { enable.set(true) } }
然后把模块A中要共享的基础测试类、测试工具类,从src/test/java/移动到src/testFixtures/java/目录下(如果没有这个目录,手动创建即可)。
步骤2:在模块B中依赖模块A的Test Fixtures
打开模块B的build.gradle,在dependencies块中添加测试专用依赖:
Groovy DSL 写法:
dependencies { // 原来的生产代码依赖不变 implementation project(':features:A') // 新增:依赖模块A的测试共享代码 testImplementation project(path: ':features:A', configuration: 'testFixtures') }
Kotlin DSL 写法:
dependencies { implementation(project(":features:A")) testImplementation(project(mapOf("path" to ":features:A", "configuration" to "testFixtures"))) }
配置完成后,同步Gradle,模块B的测试代码就能正常继承模块A的基础测试类了,IDE和构建都会正常工作。
方案2:手动导出测试输出(兼容旧版AGP)
如果你的项目还在使用AGP 7.0以下的版本,或者因为特殊场景不能用Test Fixtures,可以试试这种手动配置的方式:
步骤1:在模块A中配置测试输出导出
在模块A的build.gradle中添加自定义配置,导出测试代码的编译输出:
configurations { testOutput { extendsFrom testImplementation outgoing.artifact sourceSets.test.output } }
步骤2:在模块B中依赖这个自定义配置
在模块B的build.gradle中添加依赖:
dependencies { implementation project(':features:A') testImplementation project(path: ':features:A', configuration: 'testOutput') }
不过要注意,这种方式没有Test Fixtures那么智能,可能会出现依赖重复或者冲突的问题,所以优先推荐方案1。
为什么你之前的写法会报错?
你之前尝试的testCompile project(':features:A').sourceSets.test.output之所以报错,是因为Gradle的模块隔离机制:模块B的构建脚本不能直接访问模块A的内部sourceSets配置,这是Gradle为了保证模块独立性设计的,所以会提示“Could not get unknown property 'sourceSets'...”。
内容的提问来源于stack exchange,提问作者DmitryBorodin

