我正在尝试迁移到Gradle 7.3中引入的测试套件。我想做的是将testImplementation
依赖项添加到集成测试中。
testing {
suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter()
}
val integrationTest by registering(JvmTestSuite::class) {
dependencies {
implementation(project) // This adds dependencies to the prod code
// What to add to automatically use testImplementation deps?
}
...
}
}
}
您可能希望使integrationTestImplementation
配置扩展testImplementation
配置,就像默认情况下testImplementation
已经扩展implementation
一样。另请参阅有关配置继承的文档。
这里有一个独立的例子(用Gradle 7.3.2测试(:
plugins {
`java-library`
}
repositories {
mavenCentral()
}
testing {
suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter()
dependencies {
implementation("org.assertj:assertj-core:3.21.0")
}
}
val integrationTest by registering(JvmTestSuite::class) {
dependencies {
// TODO add any integration test only dependencies here
}
}
}
}
// Here’s the bit that you’re after:
val integrationTestImplementation by configurations.getting {
extendsFrom(configurations.testImplementation.get())
}
如果您在配置了配置继承的情况下运行./gradlew dependencies --configuration integrationTestRuntimeClasspath
,那么您将获得以下输出(缩写(:
integrationTestRuntimeClasspath - Runtime classpath of source set 'integration test'.
+--- org.junit.jupiter:junit-jupiter:5.7.2
| +--- org.junit:junit-bom:5.7.2
| | …
| +--- org.junit.jupiter:junit-jupiter-api:5.7.2
| | …
| +--- org.junit.jupiter:junit-jupiter-params:5.7.2
| | …
| --- org.junit.jupiter:junit-jupiter-engine:5.7.2
| …
--- org.assertj:assertj-core:3.21.0
但是,如果您在没有配置继承的情况下运行相同的命令,那么您将获得以下输出(缩写(-请注意缺少org.assertj:assertj-core:3.21.0
依赖项:
integrationTestRuntimeClasspath - Runtime classpath of source set 'integration test'.
--- org.junit.jupiter:junit-jupiter:5.7.2
+--- org.junit:junit-bom:5.7.2
| …
+--- org.junit.jupiter:junit-jupiter-api:5.7.2
| …
+--- org.junit.jupiter:junit-jupiter-params:5.7.2
| …
--- org.junit.jupiter:junit-jupiter-engine:5.7.2
正如回答评论中所要求的,这里还有一种方法可以使单元测试套件中的测试数据类可用于集成测试:
sourceSets.named("integrationTest") {
java {
val sharedTestData = project.objects.sourceDirectorySet("testData",
"Shared test data")
sharedTestData.srcDir("src/test/java")
sharedTestData.include("com/example/MyData.java")
source(sharedTestData)
}
}
我提出了以下解决方案
testing {
suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter()
}
val integrationTest by registering(JvmTestSuite::class) {
useJUnitJupiter()
dependencies {
implementation(project)
// add testImplementation dependencies
configurations.testImplementation {
dependencies.forEach(::implementation)
}
}
sources {
java {
//...
}
}
targets {
all {
testTask.configure {
shouldRunAfter(test)
}
}
}
}
}
}
我是一名Gradle开发人员,目前正在开发这个孵化功能。
需要记住的一点是,虽然目前为每个测试套件创建的配置的名称是基于相应的sourceSet
的名称,该名称与测试套件本身的名称相匹配,但这些名称应被视为实现细节。测试套件的主要目标之一是在这些细节上构建一个有用的抽象层,并允许您在不了解此类管道的情况下配置它们。
将配置与extendsFrom
连接在一起违背了这一意图,任何类型的名称检索也是如此,应该被视为反模式。
更好的选项包括使用suites.withType(JvmTestSuite).configureEach { suite -> ... }
或创建一个包含您想要的配置的Closure
,并使用它来配置感兴趣的测试套件,如下所示:
testing {
suites {
def applyMockitoAndJupiter = { suite ->
suite.useJUnitJupiter()
suite.dependencies {
implementation('org.mockito:mockito-junit-jupiter:4.6.1')
}
}
/* This is the equivalent of:
test {
applyMockitoAndJupiter(this)
}
*/
test(applyMockitoAndJupiter)
/* This is the equivalent of:
integrationTest(JvmTestSuite)
applyMockitoAndJupiter(integrationTest)
*/
integrationTest(JvmTestSuite, applyMockitoAndJupiter)
}
}
我们正在努力扩展测试套件和每个套件的dependencies
块提供的功能,并使文档对这一点更加明确。你可以在未来版本的Gradle文档中看到这个建议的预览(可能会有进一步的更改(——你必须以访客身份登录。
这就是我用来不为test
和customTest
任务重写两次相同依赖项的原因。也许根据@Tom Tresansky的说法,这是不推荐的,但我觉得它很方便:
configurations {
customTestImplementation {
extendsFrom testImplementation
}
customTestCompileOnly {
extendsFrom testCompileOnly
}
customTestAnnotationProcessor {
extendsFrom annotationProcessor
}
}