使用 gradle 进行多项目测试依赖关系
我有一个多项目配置,我想使用 gradle。
我的项目是这样的:
项目A
- ->
src/main/java
- ->
src/test/java
- ->
项目 B
- ->
src/main/java
(取决于项目 A 上的src/main/java
) - ->
src/test/java
(取决于项目 A 上的src/test/java
)
- ->
我的项目 B build.gradle
文件是这样的:
apply plugin: 'java'
dependencies {
compile project(':ProjectA')
}
任务 compileJava
工作得很好,但是 compileTestJava
没有编译来自 Project A 的测试文件>。
I have a multi-project configuration and I want to use gradle.
My projects are like this:
Project A
- ->
src/main/java
- ->
src/test/java
- ->
Project B
- ->
src/main/java
(depends onsrc/main/java
on Project A) - ->
src/test/java
(depends onsrc/test/java
on Project A)
- ->
My Project B build.gradle
file is like this:
apply plugin: 'java'
dependencies {
compile project(':ProjectA')
}
The task compileJava
work great but the compileTestJava
does not compile the test file from Project A.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
已弃用 - 对于 Gradle 5.6 及更高版本,请使用此答案。
在项目B中,您只需要添加一个
testCompile
依赖项:Tested with Gradle 1.7。
Deprecated - For Gradle 5.6 and above use this answer.
In Project B, you just need to add a
testCompile
dependency:Tested with Gradle 1.7.
现在,这是 Gradle 中的首要功能。带有
java
或java-library
插件的模块还可以包含java- test-fixtures
插件公开了要与testFixtures
帮助程序一起使用的帮助程序类和资源。这种方法针对工件和分类器的好处是:示例
维护的实用程序此处仅显示相关行,请参阅GitHub 查看完整的编译示例。
:modul:one
modul/one/build.gradle
modul/one/src/testFixtures/java/com/example/Helper.java
:modul:other
modul/other/ build.gradle
modul/other/src/test/java/com/example/other/SomeTest.java
进一步阅读
有关详细信息,请参阅文档:
https://docs.gradle.org/current/userguide/java_testing.html #sec:java_test_fixtures
在 Gradle 5.6 中添加:
https://docs.gradle.org/5.6 /release-notes.html#test-fixtures-for-java-projects
在 Android 上,Java 测试装置支持 在 AGP 7.1 中添加
在 JVM 项目的 test-fixtures 源集中使用 Kotlin 语言是可能的,不确定何时添加,假设是 2022 年:Kotlin 1.7.
在 Android 上的测试装置中使用 Kotlin 语言:
JetBrains 拒绝实现它 此处,Google 仅保留 将其从一个版本推到下一个版本,社区只是向往(看看投票数)。
This is now supported as a first class feature in Gradle. Modules with
java
orjava-library
plugins can also include ajava-test-fixtures
plugin which exposes helper classes and resources to be consumed withtestFixtures
helper. Benefit of this approach against artifacts and classifiers are:Example
Only relevant lines shown here, see GitHub for the full compiling example.
:modul:one
modul/one/build.gradle
modul/one/src/testFixtures/java/com/example/Helper.java
:modul:other
modul/other/build.gradle
modul/other/src/test/java/com/example/other/SomeTest.java
Further reading
For more info, see the documentation:
https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures
It was added in Gradle 5.6:
https://docs.gradle.org/5.6/release-notes.html#test-fixtures-for-java-projects
On Android Java test-fixtures support was added in AGP 7.1
Using Kotlin language in test-fixtures source set in JVM projects is possible, not sure when it was added exactly, let's say 2022: Kotlin 1.7.
Using Kotlin language in test-fixtures on Android:
JetBrains is refusing to implement it here and Google just keeps punting it from one release to the next and the community is just yearning (look at the number of votes).
简单的方法是在 ProjectB 中添加显式任务依赖项:
困难(但更清晰)的方法是为 ProjectA 创建额外的工件配置:
并为 ProjectB 添加
testCompile
依赖项Simple way is to add explicit task dependency in ProjectB:
Difficult (but more clear) way is to create additional artifact configuration for ProjectA:
and add the
testCompile
dependency for ProjectB我最近自己也遇到了这个问题,这是一个很难找到答案的问题。
您所犯的错误是认为项目应该以导出其主要工件和依赖项的方式导出其测试元素。
我个人取得的更大成功是在 Gradle 中创建了一个新项目。在您的示例中,我将其命名为
Project A_Test
-> src/main/java
我会将项目 A/src/test/java 中当前拥有的文件放入 src/main/java 中。使项目 A 的任何 testCompile 依赖项编译项目 A_Test 的依赖项。
然后使项目 A_Test 成为项目 B 的 testCompile 依赖项。
当您从两个项目的作者的角度来看它时,这是不合逻辑的,但是当您考虑像 junit 和 scalatest(以及其他项目)这样的项目时,我认为它很有意义尽管这些框架与测试相关,但它们并不被视为自己框架中“测试”目标的一部分 - 它们生成其他项目恰好在其测试配置中使用的主要工件,您只想遵循相同的模式。 。
尝试执行此处列出的其他答案对我个人来说不起作用(使用 Gradle 1.9),但我发现我在这里描述的模式无论如何都是一个更干净的解决方案
I've come across this problem myself recently, and man is this a tough issues to find answers for.
The mistake you are making is thinking that a project should export its test elements in the same way that it exports its primary artifacts and dependencies.
What I had a lot more success with personally was making a new project in Gradle. In your example, I would name it
Project A_Test
-> src/main/java
I would put into the src/main/java the files that you currently have in Project A/src/test/java. Make any testCompile dependencies of your Project A compile dependencies of Project A_Test.
Then make Project A_Test a testCompile dependency of Project B.
It's not logical when you come at it from the perspective of the author of both projects, but I think it makes a lot of sense when you think about projects like junit and scalatest (and others. Even though those frameworks are testing-related, they are not considered part of the "test" targets within their own frameworks - they produce primary artifacts that other projects just happen to use within their test configuration. You just want to follow that same pattern.
Trying to do the other answers listed here did not work for me personally (using Gradle 1.9), but I've found that the pattern I describe here is a cleaner solution anyway.
我知道这是一个老问题,但我也遇到了同样的问题,并花了一些时间弄清楚发生了什么。我正在使用 Gradle 1.9。所有更改都应在 ProjectB 的
build.gradle
中要在 ProjectB 的测试中使用 ProjectA 中的测试类:
确保
sourceSets
属性可用于 ProjectA:确保测试类当您编译 ProjectB 时,来自 ProjectA 的文件实际上就在那里:
I know it's an old question but I just had the same problem and spent some time figuring out what is going on. I'm using Gradle 1.9. All changes should be in ProjectB's
build.gradle
To use test classes from ProjectA in tests of ProjectB:
To make sure that
sourceSets
property is available for ProjectA:To make sure test classes from ProjectA are actually there, when you compile ProjectB:
在这里,如果您使用 Kotlin DSL,您应该根据 Gradle 文档。
就像之前的一些答案一样,您需要在项目内创建一个特殊的配置来共享其测试类,这样您就不会混合测试类和主类。
简单步骤
build.gradle.kts
:build.gradle.kts
中添加:Here if you are using Kotlin DSL, you should create your task like that according to Gradle documentation.
Like some previous answer, you need to create a special configuration inside the project that will share its tests class, so that you don't mix test and main classes.
Simple steps
build.gradle.kts
:build.gradle.kts
:请阅读下面的更新。
JustACluelessNewbie 描述的类似问题也出现在 IntelliJ IDEA 中。问题是依赖
testCompile project(':core').sourceSets.test.output
实际上意味着:“依赖于 gradle 构建任务生成的类”。因此,如果您打开未生成类的干净项目,IDEA 将无法识别它们并报告错误。要解决此问题,您必须在编译类的依赖项旁边添加对测试源文件的依赖项。
您可以在“模块设置”->“模块设置”中观察 IDEA 识别的依赖关系。依赖关系(测试范围)。
顺便提一句。这不是一个好的解决方案,因此值得考虑重构。 Gradle 本身确实有一个仅包含测试支持类的特殊子项目。请参阅https://docs.gradle.org/current/userguide/test_kit.html
更新2016-06-05
我更多的是考虑建议的解决方案,而不是我喜欢它。它有几个问题:
那么更好的解决方案是什么呢?在我看来,它正在创建新的自定义源集并将共享类放入其中。实际上 Gradle 项目的作者是通过创建 testFixtures 源集来做到这一点的。
为此,您只需:
创建源集并添加必要的配置。检查 Gradle 项目中使用的这个脚本插件: https://github .com/gradle/gradle/blob/v4.0.0/gradle/testFixtures.gradle(或更新的 8.2.1 版本)
在依赖项目中声明正确的依赖关系:< /p>
将 Gradle 项目导入 IDEA 并在导入时使用“为每个源集创建单独的模块”选项。
Please read the update bellow.
Similar problems described by JustACluelessNewbie occurs in IntelliJ IDEA. Problem is that dependency
testCompile project(':core').sourceSets.test.output
actually means: "depend on classes generated by gradle build task". So if you open clean project where classes are not generated yet IDEA won't recognise them and reports error.To fix this problem you have to add a dependency on test source files next to dependency on compiled classes.
You can observe dependencies recognised by IDEA in Module Settings -> Dependencies (test scope).
Btw. this is not nice solution so refactoring is worth considering. Gradle itself does have special subproject containing test-support classes only. See https://docs.gradle.org/current/userguide/test_kit.html
Update 2016-06-05
More I am thinking about proposed solution less I like it. There are few problems with it:
So what's the better solution? In my opinion it's creating new custom source set and putting shared classes into it. Actually authors of Gradle project did it by creating testFixtures source set.
To do it you just have to:
Create source set and add necessary configurations. Check this script plugin used in Gradle project: https://github.com/gradle/gradle/blob/v4.0.0/gradle/testFixtures.gradle (or more recent 8.2.1 version)
Declare proper dependency in dependent project:
Import Gradle project to IDEA and use the "create separate module per source set" option while importing.
新的基于 testJar(支持 trnsitive dependency)的解决方案可作为 gradle 插件使用:
https://github .com/hauner/gradle-plugins/tree/master/jartest
https://plugins.gradle.org/plugin/com.github.hauner.jarTest/1.0
来自文档
New testJar based (trnsitive dependancies supported) solution available as gradle plugin:
https://github.com/hauner/gradle-plugins/tree/master/jartest
https://plugins.gradle.org/plugin/com.github.hauner.jarTest/1.0
From documentation
我参加聚会太晚了(现在是 Gradle v4.4),但对于其他发现这一点的人来说:
假设:
转到项目 B 的
build.gradle
(需要一些测试的项目) A) 中的类并添加以下内容:或(假设您的项目名为
ProjectB
)瞧!
I'm so late to the party (it is now Gradle v4.4) but for anyone else who finds this:
Assuming:
Go to the
build.gradle
of project B (the one that needs some test classes from A) and add the following:or (assuming your project is named
ProjectB
)Voila!
当我尝试构建 Android 项目(gradle 2.2.0)时,Fesler 的解决方案对我不起作用。
所以我必须手动引用所需的类:
The Fesler's solution haven't worked for me, when i tried it to build an android project (gradle 2.2.0).
So i had to reference required classes manually :
为 Gradle 6.6.x 创建 test-jar
我知道有很多消息来源告诉你,这是不行的,fe:
但这太简单了,我只是不喜欢使用通用测试类的想法分别位于
testFixtures
文件夹中。所以在模块 A 中:
在模块 B 中:
它就可以工作了!
Creating test-jar For Gradle 6.6.x
I know that there are many sources telling you, that is not OK, fe:
But this is so damn simple and I just don't like the idea of having common test classes separately in
testFixtures
folder.So in module A:
And in module B:
And it just works!
如果您想使用artifact依赖项来实现:
然后 build.gradle 中 ProjectB 的依赖项部分应该看起来像这样:
为此,ProjectA 需要构建一个 -tests jar 并将其包含在它生成的工件中。
ProjectA 的 build.gradle 应包含如下配置:
当 ProjectA 的工件发布到您的工件时,它们将包含一个 -tests jar。
ProjectB 的依赖项部分中的 testCompile 将引入 -tests jar 中的类。
如果您想要在 ProjectB 中includeFlat ProjectA 的源代码和测试类用于开发目的,那么 ProjectB 的 build.gradle 中的依赖项部分将如下所示:
If you want to use artifact dependencies to have:
then ProjectB's dependencies section in build.gradle should look something like this:
For this to work ProjectA needs to build a -tests jar and include it in the artifacts it produces.
ProjectA's build.gradle should contain configuration like this:
When ProjectA's artifacts are published to your artifactory they will include a -tests jar.
The testCompile in ProjectB's dependencies section will bring in the classes in the -tests jar.
If you want to includeFlat ProjectA's source and test classes in ProjectB for development purposes then the dependencies section in ProjectB's build.gradle would look like this:
如果您正在努力使解决方案适应 Gradle Kotlin DSL,则这相当于:
If you are struggling to adapt the solution to the Gradle Kotlin DSL this is the equivalent:
如果您有需要在测试之间共享的模拟依赖项,您可以创建新项目
projectA-mock
,然后将其作为测试依赖项添加到ProjectA
和ProjectB< /code>:
这是共享模拟依赖项的明确解决方案,但如果您需要在
ProjectB
中运行ProjectA
的测试,请使用其他解决方案。If you have mock dependencies which you need to share between tests, you can create new project
projectA-mock
and then add it as test dependency toProjectA
andProjectB
:This is clear solution to share mock dependencies, but if you need to run tests from
ProjectA
inProjectB
use other solution.Nikita 针对 Android + Kotlin 提到的解决方案如下所示:
Gradle for project that isgoing使用依赖项:
The solution mentioned by Nikita for Android + Kotlin looks like this:
Gradle for project that is going to use dependencies:
其他一些答案以某种方式导致错误 - Gradle 没有检测到其他项目的测试类,或者 Eclipse 项目在导入时具有无效的依赖项。如果有人遇到同样的问题,我建议使用:
第一行强制 Eclipse 将其他项目链接为依赖项,因此所有源都包含在内并且是最新的。第二个允许 Gradle 实际查看源代码,同时不会像
testCompile project(':core').sourceSets.test.output
那样导致任何无效的依赖项错误。Some of the other answers caused errors one way or another - Gradle did not detect test classes from other projects or Eclipse project had invalid dependencies when imported. If anyone has the same problem, I suggest going with:
The first line forces the Eclipse to link the other project as dependency, so all sources are included and up to date. The second allows Gradle to actually see the sources, while not causing any invalid dependency errors like
testCompile project(':core').sourceSets.test.output
does.在项目 B 中:
似乎适用于 1.7-rc-2
in project B:
Seems to work in 1.7-rc-2