如何在另一个模块的androidTest目录中使用代码

44

我在我的AndroidStudio项目中添加了两个模块:

app-base
|
|----src
      |____androidTest
                |________MyTestBase.java          

app
|
|----src
      |____androidTest
                |________MyTest.java

在app-base的androidTest中定义了一些常见的测试类,并且在app的androidTest中使用。

我尝试在app的build.gradle中添加以下代码:

    evaluationDependsOn(':app-base')

    compile project(':app-base')

    androidTestCompile project(':app-base')

我已在settings.gradle中同时包含了app-base和app,使用gradlew projects命令的输出结果如下:

Root project 'MyProject'
+--- Project ':app-base' 
+--- Project ':app'

这种方法没有编译错误,但是当我在IDE中运行MyTest时,它会提示找不到MyTestBase类。你知道问题出在哪里吗?欢迎任何想法。谢谢。

你是否定义了适当的settings.gradle文件? gradlew projects的输出是什么?请查看Gradle文档以获取有关如何设置多项目构建的更多信息。 - Mark Vieira
依赖于另一个项目的测试代码确实是不寻常的。您必须明确依赖于该项目的testCompile配置。尝试使用androidTestCompile project(path: ':app-base', configuration: 'androidTestCompile') - Mark Vieira
请参见 https://dev59.com/E1UM5IYBdhLWcg3wCcqz。 - huskygrad
3个回答

29

我已经寻找解决方案有一段时间了,最终找到适合我的东西。

这将允许您将常见的测试类放在另一个模块中。

android {
    ...

    sourceSets {
        androidTest.java.srcDirs += ["${project('match the module name that is currently in the dependencies').projectDir}/src/androidTest/java"]
    }
}

所以对于上面的例子,它可能看起来像这样

androidTest.java.srcDirs += ["${project(':appbase').projectDir}/src/androidTest/java"]

3
顺便说一句,这个功能可以运行,但是Android Studio无法识别来自另一个模块的文件。这种情况只会导致导入该文件时出现红色下划线,有些让人烦恼。 - sudocoder
@sudocoder,红色的波浪线听起来像是该模块在正常构建下没有正确编译。出现了什么错误?你是否在该模块中缺少某个依赖项? - Stimsoni
如果在运行测试时可以正常工作,则说明在进行 Android 测试编译时可以正确编译,并且与此无关。该代码将在原始模块依赖项下编译代码,而不是代码所在模块的依赖项。 - Stimsoni
如果您只有几个需要共享的类,最好的解决方案是不要创建单独的模块。谢谢 :) - MatPag
解决方案对我有效。 我看到@sudocoder报告的红色波浪线,我的项目有两个模块依赖于第三个包含共享测试代码的模块。 其中一个依赖模块没有红色波浪线,而另一个依赖模块则有。 没问题的那个被称为:app,而具有波浪线的是:appgrab。 我不知道还有什么其他的区别。 尽管:appgrab和:app应该是独立的,但通过在:appgrab的build.gradle中添加androidTestImplementation project(":app")可以消除红色波浪线。 - Michael Osofsky
3
我决定使用 @ben75 提出的另一种解决方案,因为我担心红色波浪线会使维护此方案长期的其他人感到困惑。 - Michael Osofsky

15
我建议您采用以下策略:创建一个名为test-utils的新模块,并将MyTestBase.java放置在该模块的主要源代码中。
test-utils
|
|----src
      |____main
             |________MyTestBase.java

然后您将 test-utils 添加为所有需要它的模块的测试依赖项

androidTestCompile project(':test-utils')

1
在我看来,新模块并不是什么大事。其他的解决方案包括:在每个模块中复制代码或者为androidTest定义多个源目录,并使用一些相对路径,例如:../app-base/src/androidTest/java/(在我看来,这两种方法都更糟糕)。 - ben75
2
我认为这个答案只有在共享的代码确实是多个其他模块所需的 Utils 时才有帮助。如果基础模块包含一些特定于基础模块中的“实际”代码的测试结构/助手,则从组织上讲,将这些测试结构保留在基础模块中是有意义的。 - tir38
1
这似乎应该可以工作,但是我得到了一个“未解决的引用:BaseTest”的错误。 - AutonomousApps
如上所述,只有在您想使用某种“utils”时才有用,但是如果您拥有需要在其自己的模块中生成的模型的模拟工厂,您将遇到OP所提出的问题。 - htafoya
1
建议:在 :test-utils 模块的 build.gradle 中将所有的 androidTestImplementation 等转换为 implementation。当我将测试代码从应用程序模块移动到 :test-utils 模块时,最初我忘记了这样做。 - Michael Osofsky
显示剩余7条评论

3

在 Stimsoni 的答案上做了少许更改后,这最终对我起作用了。我将以下代码添加到我的应用 gradle 中:

sourceSets {
    test.java.srcDirs += ["${project(':app-base').projectDir}/src/test/java"]
}

第一个版本 androidTest.java + /src/androidTest 用于仪器测试(androidTest),第二个版本 test.java + /src/test 用于纯单元测试(test)。 - ehartwell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接