Build 具有gradle的多项目测试依赖关系

Build 具有gradle的多项目测试依赖关系,build,dependencies,gradle,multi-project,Build,Dependencies,Gradle,Multi Project,我有一个多项目配置,我想使用gradle 我的项目如下: apply plugin: 'java' dependencies { compile project(':ProjectA') } dependencies { compile("com.example:projecta:1.0.0") testCompile("com.example:projecta:1.0.0:tests") } task testsJar(type: Jar, dependsOn: test

我有一个多项目配置,我想使用gradle

我的项目如下:

apply plugin: 'java'
dependencies {
  compile project(':ProjectA')
}
dependencies {

  compile("com.example:projecta:1.0.0")

  testCompile("com.example:projecta:1.0.0:tests")

}
task testsJar(type: Jar, dependsOn: testClasses) {
    classifier = 'tests'
    from sourceSets.test.output
}

configurations {
    tests
}

artifacts {
    tests testsJar
    archives testsJar
}

jar.finalizedBy(testsJar)
dependencies {

  compile project(':projecta')

  testCompile project(path: ':projecta', configuration: 'tests')

}
task jarTests(type: Jar, dependsOn: "assembleDebugUnitTest") {
    getArchiveClassifier().set('tests')
    from "$buildDir/tmp/kotlin-classes/debugUnitTest"
}

configurations {
    unitTestArtifact
}

artifacts {
    unitTestArtifact jarTests
}
  • 项目A

    • ->
      src/main/java
    • ->
      src/test/java
  • 项目B

    • ->
      src/main/java
      (取决于
      src/main/java
      项目A)
    • ->
      src/test/java
      (取决于项目A上的
      src/test/java
我的项目B
build.gradle
文件如下:

apply plugin: 'java'
dependencies {
  compile project(':ProjectA')
}
dependencies {

  compile("com.example:projecta:1.0.0")

  testCompile("com.example:projecta:1.0.0:tests")

}
task testsJar(type: Jar, dependsOn: testClasses) {
    classifier = 'tests'
    from sourceSets.test.output
}

configurations {
    tests
}

artifacts {
    tests testsJar
    archives testsJar
}

jar.finalizedBy(testsJar)
dependencies {

  compile project(':projecta')

  testCompile project(path: ':projecta', configuration: 'tests')

}
task jarTests(type: Jar, dependsOn: "assembleDebugUnitTest") {
    getArchiveClassifier().set('tests')
    from "$buildDir/tmp/kotlin-classes/debugUnitTest"
}

configurations {
    unitTestArtifact
}

artifacts {
    unitTestArtifact jarTests
}

任务
compileJava
工作得很好,但是
compileTestJava
不会从项目A编译测试文件

简单的方法是在项目B中添加显式的任务依赖项:

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
testCompile files(project(':ProjectA').sourceSets.test.output.classesDir)
compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
困难(但更清楚)的方法是为ProjectA创建额外的工件配置:

task myTestsJar(type: Jar) { 
  // pack whatever you need...
}

configurations {
  testArtifacts
}

artifacts {
   testArtifacts myTestsJar
}
evaluationDependsOn(':ProjectA')
并为ProjectB添加
testCompile
依赖项

apply plugin: 'java'
dependencies {
  compile project(':ProjectA')
  testCompile project(path: ':ProjectA', configuration: 'testArtifacts')
}
不推荐使用-用于Gradle 5.6及以上版本。 在项目B中,您只需要添加一个
testCompile
依赖项:

dependencies {
  ...
  testCompile project(':A').sourceSets.test.output
}
在项目B中使用Gradle 1.7进行测试。

dependencies {
  testCompile project(':projectA').sourceSets.test.output
}

似乎在1.7-rc-2中工作

最近我自己也遇到了这个问题,这是一个很难找到答案的问题

您犯的错误是认为项目应该以导出其主要工件和依赖项的相同方式导出其测试元素

我个人更成功的是在格拉德尔做了一个新项目。在你的例子中,我将命名它

计划A_测试 ->src/main/java

我将把您当前在项目A/src/test/java中的文件放入src/main/java。将项目的任何testCompile依赖项设置为Project A_测试的编译依赖项

然后使项目A_Test成为项目B的testCompile依赖项

从这两个项目的作者的角度来看,这是不符合逻辑的,但我认为,当你考虑像junit和scalatest(以及其他项目)这样的项目时,这是很有意义的。即使这些框架与测试相关,它们也不被认为是“测试”的一部分在他们自己的框架中的目标-他们产生其他项目恰好在他们的测试配置中使用的主要工件


尝试做这里列出的其他答案对我个人来说不起作用(使用Gradle 1.9),但我发现我在这里描述的模式无论如何都是一个更干净的解决方案。

我知道这是一个老问题,但我也遇到了同样的问题,并花了一些时间弄清楚发生了什么。我使用的是Gradle 1.9。所有更改都应该在ProjectB的
build.Gradle

要在ProjectB的测试中使用ProjectA中的测试类,请执行以下操作:

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
testCompile files(project(':ProjectA').sourceSets.test.output.classesDir)
compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
要确保
sourceset
属性可用于ProjectA,请执行以下操作:

task myTestsJar(type: Jar) { 
  // pack whatever you need...
}

configurations {
  testArtifacts
}

artifacts {
   testArtifacts myTestsJar
}
evaluationDependsOn(':ProjectA')
要确保ProjectA中的测试类确实存在,在编译ProjectB时:

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
testCompile files(project(':ProjectA').sourceSets.test.output.classesDir)
compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
新的基于testJar的(支持敏感依赖性)解决方案,可作为gradle插件提供:

从文件

如果您有一个多项目渐变构建,您可能需要进行测试 子项目之间的依赖关系(这可能暗示 项目结构不完善)

例如,假设子项目B所依赖的项目 在项目A和B上,不仅对A有编译依赖关系,而且 为了编译和运行B的测试,我们需要一些 从A测试助手类

默认情况下,gradle不会从测试构建中创建jar工件 项目的产出

此插件添加了testArchives配置(基于testCompile) 以及一个jarTest任务,用于从测试源集创建一个jar(使用 分类器测试添加到jar的名称中)。然后我们可以依赖于 的testArchives配置(还将包括 A)的可传递依赖项

在A中,我们会将插件添加到build.gradle:

应用插件:“com.github.hauner.jarTest”

在B中,我们引用 testArchives配置如下:

apply plugin: 'java'
dependencies {
  compile project(':ProjectA')
}
dependencies {

  compile("com.example:projecta:1.0.0")

  testCompile("com.example:projecta:1.0.0:tests")

}
task testsJar(type: Jar, dependsOn: testClasses) {
    classifier = 'tests'
    from sourceSets.test.output
}

configurations {
    tests
}

artifacts {
    tests testsJar
    archives testsJar
}

jar.finalizedBy(testsJar)
dependencies {

  compile project(':projecta')

  testCompile project(path: ':projecta', configuration: 'tests')

}
task jarTests(type: Jar, dependsOn: "assembleDebugUnitTest") {
    getArchiveClassifier().set('tests')
    from "$buildDir/tmp/kotlin-classes/debugUnitTest"
}

configurations {
    unitTestArtifact
}

artifacts {
    unitTestArtifact jarTests
}

其他一些答案以某种方式导致了错误-Gradle没有检测到来自其他项目的测试类,或者Eclipse项目在导入时具有无效的依赖项。如果有人有相同的问题,我建议使用:

testCompile project(':core')
testCompile files(project(':core').sourceSets.test.output.classesDir)

第一行强制Eclipse将另一个项目链接为依赖项,因此所有源代码都包含在内并且是最新的。第二行允许Gradle实际查看源代码,同时不会导致任何无效的依赖项错误,如
testCompile project(':core')。sourceset.test.output

请阅读下面的更新

JustACluelessNewbie描述的类似问题也出现在IntelliJ IDEA中。问题是依赖性
testCompile项目(':core').sourceset.test.output实际上意味着:“依赖于gradle构建任务生成的类”。所以,如果您打开的是尚未生成类的clean project,IDEA将无法识别它们并报告错误

要解决此问题,您必须在对已编译类的依赖项旁边添加对测试源文件的依赖项

// First dependency is for IDEA
testCompileOnly files { project(':core').sourceSets.test.java.srcDirs }
// Second is for Gradle
testCompile project(':core').sourceSets.test.output
您可以在模块设置->依赖项(测试范围)中观察IDEA识别的依赖项

顺便说一句,这不是一个好的解决方案,所以重构是值得考虑的。Gradle本身确实有一个特殊的子项目,只包含测试支持类。请参阅

更新2016-06-05 我对提议的解决方案考虑得越多,我就越不喜欢它。它几乎没有什么问题:

  • 它在IDEA中创建了两个依赖项。一个指向测试源,另一个指向已编译类。IDEA识别这些依赖项的顺序至关重要。您可以通过在模块设置->依赖项选项卡中更改依赖项顺序来使用它
  • 通过声明这些依赖项,您是不必要的