首页 文章

如何向Gradle添加新的源集?

提问于
浏览
78

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

6 回答

  • 1

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

    这是一个简单的gradle构建脚本,除了main和test源集外,还有一个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
    }
    
  • 96

    这是我如何在不使用 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
    }
    

    Tested using: Gradle 1.4和Gradle 1.6

  • 28

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


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

    先说一些温暖的话:

    • 首先,我们需要定义 sourceSet
    sourceSets {
        integrationTest
    }
    
    • 接下来我们从 test 展开 sourceSet ,因此我们使用 test.runtimeClasspath (其中包括来自 test AND test 本身的所有依赖项)作为派生 sourceSet 的类路径:
    sourceSets {
        integrationTest {
            compileClasspath += sourceSets.test.runtimeClasspath
            runtimeClasspath += sourceSets.test.runtimeClasspath // ***)
        }
    }
    
    • note )不知何故需要重新声明/扩展 sourceSets.integrationTest.runtimeClasspath ,但应该是无关紧要的,因为 runtimeClasspath 总是扩展 output + runtimeSourceSet ,不要得到它

    • 我们定义了一个专门用于运行集成测试的任务:

    task integrationTest(type: Test) {
    }
    
    • 配置 integrationTest 测试类和类路径使用 . java 插件的默认值使用 test sourceSet
    task integrationTest(type: Test) {
        testClassesDir = sourceSets.integrationTest.output.classesDir
        classpath = sourceSets.integrationTest.runtimeClasspath
    }
    
    • (可选)测试后自动运行
    integrationTest.dependsOn test
    
    • (可选)从 check 添加依赖项(因此它始终在执行 buildcheck 时运行)
    tasks.check.dependsOn(tasks.integrationTest)
    
    • (可选)将java,资源添加到 sourceSet 以支持自动检测并在IDE中创建这些"partials" . 即IntelliJ IDEA将自动为每个集创建 sourceSet 目录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上的示例代码似乎没有处理这个或者有一个不同/更复杂/对我来说无论如何都没有更清晰的解决方案!

  • 6

    nebula-facet插件消除了样板:

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

    对于集成测试,甚至this is done for you,只需应用:

    apply plugin: 'nebula.integtest'
    

    每个Gradle插件门户链接是:

  • 15

    这对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 .

  • 1

    如果你正在使用

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

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

相关问题