113

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

4

8 回答 8

134

2021 年更新:

8年来发生了很多变化。Gradle 仍然是一个很棒的工具。现在,文档中有一个完整的部分专门用于配置集成测试。我建议您现在阅读文档

原答案:

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

这是一个简单的 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
}
于 2012-07-20T14:30:47.770 回答
35

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

于 2013-05-29T16:34:43.993 回答
24

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


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

先说几句暖心的话:

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

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

    sourceSets {
        integrationTest {
            compileClasspath += sourceSets.test.runtimeClasspath
            runtimeClasspath += sourceSets.test.runtimeClasspath // ***)
        }
    }
    
    • 注意)以某种方式需要重新声明/扩展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(因此它总是在执行时build运行check

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

    sourceSets {
         integrationTest {
             java
             resources
         }
    }
    

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

于 2016-06-17T12:49:53.720 回答
10

nebula-facet插件消除了样板:

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

特别是对于集成测试,即使这是为您完成的,只需申请:

apply plugin: 'nebula.integtest'

每个 Gradle 插件门户链接是:

  1. 星云面
  2. nebula.integtest
于 2016-08-09T18:03:46.200 回答
7

如果你正在使用

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

plugin {
    idea
}

idea {
    module {
        testSourceDirs = testSourceDirs + sourceSets["intTest"].allJava.srcDirs
        testResourceDirs = testResourceDirs + sourceSets["intTest"].resources.srcDirs
    }
}
于 2019-02-14T17:02:19.540 回答
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 发行说明

于 2017-08-02T15:31:34.113 回答
1

我收集的文档在 2012 年被问到这个问题时并不是很好,但是对于在 2020 年以上阅读此内容的任何人:文档中现在有一整节内容是关于如何为集成测试添加源集。您真的应该阅读它,而不是在此处复制/粘贴代码片段并将头撞到墙上,试图弄清楚为什么 2012-2016 年的答案不太有效。

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

于 2020-12-28T11:19:31.003 回答
-1

我是 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,那么您还可以implementationdependencies.

我必须指定repositories部分才能使其正常工作,我怀疑这是最好/唯一的方法。

于 2019-12-23T16:46:21.717 回答