如何向Gradle添加新的源集?

时间:2012-07-20 14:30:48

标签: java gradle build integration-testing source-sets

我想在我的Gradle构建(版本1.0)中添加集成测试。它们应该与我的正常测试分开运行,因为它们需要将webapp部署到localhost(它们测试该webapp)。测试应该能够使用我的主要源集中定义的类。我该如何实现这一目标?

8 个答案:

答案 0 :(得分:98)

我花了一段时间才弄明白,在线资源并不是很好。所以我想记录我的解决方案。

这是一个简单的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
}

答案 1 :(得分:29)

以下是我在不使用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 :(得分:16)

  

这是曾在2016年为Gradle 2.x / 3.x编写,并且已经过时了 !!   请看一下at the documented solutions in Gradle 4 and up

总结两个旧答案(获得两个世界的最佳和最低可行性):

首先是一些温暖的话:

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

    sourceSets {
        integrationTest
    }
    
  2. 接下来我们从sourceSet展开test,因此我们使用test.runtimeClasspath(其中包括来自test AND test本身的所有相关内容)作为派生sourceSet的类路径:

    sourceSets {
        integrationTest {
            compileClasspath += sourceSets.test.runtimeClasspath
            runtimeClasspath += sourceSets.test.runtimeClasspath // ***)
        }
    }
    
    • 注意)某种方式需要sourceSets.integrationTest.runtimeClasspath的重新声明/扩展,但应该无关紧要,因为runtimeClasspath始终展开output + runtimeSourceSet,不要得到它< / LI>
  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 test
    

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

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

    sourceSets {
         integrationTest {
             java
             resources
         }
    }
    
  8. <强> TL;博士

    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上的示例代码似乎没有处理这个或者有一个不同/更复杂/对我来说无论如何都没有更清晰的解决方案!

答案 3 :(得分:7)

nebula-facet插件消除了样板:

apply plugin: 'nebula.facet'
facets {
    integrationTest {
        parentSourceSet = 'test'
    }
}

具体来说,对于集成测试,即使是this is done for you,也只需应用:

apply plugin: 'nebula.integtest'

每个Gradle插件门户链接都是:

  1. nebula.facet
  2. nebula.integtest

答案 4 :(得分:1)

这对于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 release notes

答案 5 :(得分:1)

如果您使用

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

plugin {
    idea
}

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

答案 6 :(得分:1)

我认为在 2012 年提出这个问题时文档并不是很好,但对于 2020 年以后阅读本文的任何人来说:现在文档中有一个完整的部分是关于 how to add a source set for integration tests。你真的应该阅读它,而不是在这里复制/粘贴代码片段,然后用头撞墙试图找出为什么 2012-2016 年的答案不太奏效。

答案很可能很简单,但比您想象的更微妙,您需要的确切代码可能与我需要的代码不同。例如,您是否希望集成测试使用与单元测试相同的依赖项?

答案 7 :(得分:0)

我是Gradle的新手,使用Gradle 6.0.1 JUnit 4.12。这就是我想出的解决这个问题的方法。

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部分才能使其正常工作,我怀疑这是最好/唯一的方法。