如何将新的源集添加到Gradle?


99

我想将集成测试添加到我的Gradle版本(1.0版)中。它们应与我的常规测试分开运行,因为它们需要将webapp部署到本地主机(它们测试该webapp)。这些测试应该能够使用在我的主要源代码集中定义的类。我如何做到这一点?

Answers:


114

这花了我一段时间才能弄清楚,在线资源也不是很好。所以我想记录我的解决方案。

这是一个简单的gradle构建脚本,除了主要和测试源集之外,还具有intTest源集:

apply plugin: "java"

sourceSets {
    // Note that just declaring this sourceset creates two configurations.
    intTest {
        java {
            compileClasspath += main.output
            runtimeClasspath += main.output
        }
    }
}

configurations {
    intTestCompile.extendsFrom testCompile
    intTestRuntime.extendsFrom testRuntime
}

task intTest(type:Test){
    description = "Run integration tests (located in src/intTest/...)."
    testClassesDir = project.sourceSets.intTest.output.classesDir
    classpath = project.sourceSets.intTest.runtimeClasspath
}

7
您仍然需要声明和配置集成测试任务。在文档方面,java/withIntegrationTests完整的Gradle发行版中有一个示例。
Peter Niederwieser

感谢@PeterNiederwieser,我已经更正了示例构建脚本。
斯宾娜2012年

2
我也在尝试执行此操作...非常感谢您发布解决方案:)
Igor Popov 2012年

@PeterNiederwieser谢谢-您能将其链接吗?我还发现文档中严重缺乏这种确切的情况:定义一个新的sourceSet很好,但是没有有关将其“挂钩”到实际的编译,jar,测试和诸如此类的目标的信息-如本例所示(除了添加放入jar,或从该sourceSet中制作一个新的jar)。
stolsvik 2014年

在第6行,使用IntelliJ时出现“无法解析符号'java'”。有什么想法吗?
Snekse 2014年

33

这是我无需使用即可实现的方法configurations{ }

apply plugin: 'java'

sourceCompatibility = JavaVersion.VERSION_1_6

sourceSets {
    integrationTest {
        java {
            srcDir 'src/integrationtest/java'
        }
        resources {
            srcDir 'src/integrationtest/resources'
        }
        compileClasspath += sourceSets.main.runtimeClasspath
    }
}

task integrationTest(type: Test) {
    description = "Runs Integration Tests"
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath += sourceSets.integrationTest.runtimeClasspath
}

测试使用: Gradle 1.4和Gradle 1.6


2
感谢分享!很高兴看到其他实现。
斯宾娜2013年

1
虽然java { srcDir 'src/integrationtest/java' } resources { srcDir 'src/integrationtest/resources' }是不相关的,因为它只是redeclares src/<sourceSetName>/...src/integrationtest/...:这里:改变大写字母T到一个低位的t
childno͡.de

当心这种方法。compileClasspath += sourceSets.main.runtimeClasspath正在合并两组文件。没有通常的依赖项冲突解决方案。您可以得到同一库的两个版本。扩展配置将对此有所帮助。
chalimartines

20

曾经是在2016年为Gradle 2.x / 3.x编写的,已经过时了!请查看Gradle 4及更高版本中记录的解决方案


总结两个旧答案(获得两个方面的最佳和最小可行性):

首先说一些温暖的话:

  1. 首先,我们需要定义sourceSet

    sourceSets {
        integrationTest
    }
  2. 接下来,我们扩展sourceSetfrom test,因此我们使用test.runtimeClasspath(包括testAND test本身的所有依赖项)作为派生类的类路径sourceSet

    sourceSets {
        integrationTest {
            compileClasspath += sourceSets.test.runtimeClasspath
            runtimeClasspath += sourceSets.test.runtimeClasspath // ***)
        }
    }
    • note)某种程度上需要此重新声明/扩展sourceSets.integrationTest.runtimeClasspath,但由于runtimeClasspath总是扩展output + runtimeSourceSet,因此不相关,请不要理解
  3. 我们为运行集成测试定义了一个专用任务:

    task integrationTest(type: Test) {
    }
  4. 配置integrationTest测试类和类路径的使用。java插件的默认设置使用test sourceSet

    task integrationTest(type: Test) {
        testClassesDir = sourceSets.integrationTest.output.classesDir
        classpath = sourceSets.integrationTest.runtimeClasspath
    }
  5. (可选)测试后自动运行

    integrationTest.dependsOn测试
    

  6. (可选)添加依赖项check(因此它总是在buildcheck执行时运行)

    tasks.check.dependsOn(tasks.integrationTest)
  7. (可选)将Java,资源添加到中sourceSet以支持自动检测,并在IDE中创建这些“部分”。即,sourceSet如果不存在,IntelliJ IDEA将自动为每个集合创建目录java和资源:

    sourceSets {
         integrationTest {
             java
             resources
         }
    }

tl; dr

apply plugin: 'java'

// apply the runtimeClasspath from "test" sourceSet to the new one
// to include any needed assets: test, main, test-dependencies and main-dependencies
sourceSets {
    integrationTest {
        // not necessary but nice for IDEa's
        java
        resources

        compileClasspath += sourceSets.test.runtimeClasspath
        // somehow this redeclaration is needed, but should be irrelevant
        // since runtimeClasspath always expands compileClasspath
        runtimeClasspath += sourceSets.test.runtimeClasspath
    }
}

// define custom test task for running integration tests
task integrationTest(type: Test) {
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
}
tasks.integrationTest.dependsOn(tasks.test)

指:

不幸的是,github.com / gradle / gradle / subprojects / docs / src / samples / java / customizedLayout / build.gradle…/ gradle /…/ withIntegrationTests / build.gradle上的示例代码似乎无法处理此问题或具有不同的含义 /更复杂/对我而言,没有更清晰的解决方案!


1
(!)事实证明,单独使用sourceSet增强功能而不进行配置或输出会导致在最初打开项目后产生想法错误。新“模块”(此处integrationTest):构建依赖(测试这里)不可在第一compileTestJava
childno͡.de

2
classesDir被迁移到classesDirsgradle 5
deFreitas

谢谢你的提示@deFreitas,标志着我答案过时
childno͡.de


7

如果您正在使用

  • Gradle 5.x, 请参见文档部分“测试Java>配置集成测试示例14和15”(有关Groovy和Kotlin DSL的详细信息,请选择其中的一种)
    • alt:“当前” Gradle doc链接位于2,但将来可能会延迟,您应该看看示例是否发生变化)
  • Gradle 4的用户可以看看古代版本3,该版本与@Spina在2012年发布的版本非常接近

要使IntelliJ将自定义源集识别为测试源根:

plugin {
    idea
}

idea {
    module {
        testSourceDirs = testSourceDirs + sourceSets["intTest"].allJava.srcDirs
        testResourceDirs = testResourceDirs + sourceSets["intTest"].resources.srcDirs
    }
}

2

从Gradle 4.0开始,这对我有效。

sourceSets {
  integrationTest {
    compileClasspath += sourceSets.test.compileClasspath
    runtimeClasspath += sourceSets.test.runtimeClasspath
  }
}

task integrationTest(type: Test) {
  description = "Runs the integration tests."
  group = 'verification'
  testClassesDirs = sourceSets.integrationTest.output.classesDirs
  classpath = sourceSets.integrationTest.runtimeClasspath
}

从版本4.0开始,Gradle现在为源集中的每种语言使用单独的类目录。因此,如果您的构建脚本使用sourceSets.integrationTest.output.classesDir,您将看到以下弃用警告。

Gradle现在为每种JVM语言使用单独的输出目录,但是此构建为源集中的所有类假定一个目录。此行为已被弃用,并计划在Gradle 5.0中删除。

要消除此警告,只需切换到即可sourceSets.integrationTest.output.classesDirs。有关更多信息,请参见Gradle 4.0发行说明


切换到<hmm> ?? 您之前和之后都一样。
Merk

0

我是使用Gradle 6.0.1 JUnit 4.12刚接触Gradle的人。这是我想出的解决此问题的方法。

apply plugin: 'java'
repositories { jcenter() }

dependencies {
    testImplementation 'junit:junit:4.12'
}

sourceSets {
  main {
    java {
       srcDirs = ['src']
    }
  }
  test {
    java {
      srcDirs = ['tests']
    }
  }
}

注意,主要来源和测试来源是分别引用的,一个在之下main,一个在之下test

下的testImplementation项目dependencies仅用于编译中的源test。如果您的主代码实际上依赖于JUnit,那么您还可以implementation在下指定dependencies

我必须指定repositories部分来使它起作用,我怀疑这是最好/唯一的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.