我想将集成测试添加到我的 Gradle 构建(版本 1.0)中。它们应该与我的正常测试分开运行,因为它们需要将 web 应用程序部署到 localhost(它们测试该 web 应用程序)。测试应该能够使用我的主要源集中定义的类。我该如何做到这一点?
8 回答
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
}
这是我在不使用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
这曾经是 2016 年为 Gradle 2.x / 3.x 编写的,并且已经过时了!!请查看Gradle 4 及更高版本中记录的解决方案
总结两个旧答案(获得两个世界的最佳和最小可行):
先说几句暖心的话:
首先,我们需要定义
sourceSet
:sourceSets { integrationTest }
接下来我们扩展
sourceSet
fromtest
,因此我们使用test.runtimeClasspath
(包括test
ANDtest
本身的所有依赖项)作为派生的类路径sourceSet
:sourceSets { integrationTest { compileClasspath += sourceSets.test.runtimeClasspath runtimeClasspath += sourceSets.test.runtimeClasspath // ***) } }
- 注意)以某种方式需要重新声明/扩展
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 测试
(可选)添加依赖项
check
(因此它总是在执行时build
运行check
)tasks.check.dependsOn(tasks.integrationTest)
(可选)添加 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上的示例代码似乎没有处理这个问题或有不同的/更复杂/对我来说没有更清晰的解决方案!
nebula-facet插件消除了样板:
apply plugin: 'nebula.facet'
facets {
integrationTest {
parentSourceSet = 'test'
}
}
特别是对于集成测试,即使这是为您完成的,只需申请:
apply plugin: 'nebula.integtest'
每个 Gradle 插件门户链接是:
如果你正在使用
- Gradle 5.x,请查看文档部分“测试 Java > 配置集成测试
示例 14 和 15 以了解详细信息(适用于 Groovy 和 Kotlin DSL,您更喜欢哪一个)
- alt:“当前”Gradle 文档链接位于2,但将来可能会延迟,如果示例更改,您应该查看)
- 对于 Gradle 4,看看古老的版本3 ,它与@Spina 在 2012 年发布的内容很接近
要让 IntelliJ 将自定义源集识别为测试源根:
plugin {
idea
}
idea {
module {
testSourceDirs = testSourceDirs + sourceSets["intTest"].allJava.srcDirs
testResourceDirs = testResourceDirs + sourceSets["intTest"].resources.srcDirs
}
}
从 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 发行说明。
我收集的文档在 2012 年被问到这个问题时并不是很好,但是对于在 2020 年以上阅读此内容的任何人:文档中现在有一整节内容是关于如何为集成测试添加源集。您真的应该阅读它,而不是在此处复制/粘贴代码片段并将头撞到墙上,试图弄清楚为什么 2012-2016 年的答案不太有效。
答案很可能很简单,但比您想象的更微妙,您需要的确切代码可能与我需要的代码不同。例如,您是否希望您的集成测试使用与单元测试相同的依赖项?
我是 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
部分才能使其正常工作,我怀疑这是最好/唯一的方法。