运行 Gradle 使用多个 Java 工具链进行测试
Run Gradle tests with multiple Java toolchains
我有一个 Gradle 项目,它使用由工具链指定的 Java 版本 API:
val minimumJava = JavaLanguageVersion.of(8)
val maximumJava = JavaLanguageVersion.of(16)
java {
toolchain {
languageVersion.set(minimumJava)
vendor.set(JvmVendorSpec.ADOPTOPENJDK)
}
}
我希望能够使用支持的最低 Java 版本进行编译,然后 运行 使用项目支持的所有 JDK 进行测试。
我尝试了以下方法,但显然只执行了原始测试,所有其他测试都没有执行,即使所需的 JDK 已正确下载和设置:
for (javaVersion in JavaLanguageVersion.of(minimumJava.asInt() + 1)..maximumJava) {
val base = tasks.test.get()
val testTask = tasks.register<Test>("testUnderJava${javaVersion.asInt()}") {
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion.set(javaVersion)
}
)
classpath = base.classpath
testClassesDirs = base.testClassesDirs
isScanForTestClasses = true
}
tasks.test.configure { finalizedBy(testTask) }
}
这是哑终端中的 运行:
❯ TERM=dumb ./gradlew test testUnderJava10 --rerun-tasks --scan
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on
<<<SNIP>>>
> Task :testClasses
> Task :test
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on
Gradle Test Executor 4 STANDARD_OUT
~~~ Kotest Configuration ~~~
-> Parallelization factor: 1
-> Concurrent specs: null
-> Global concurrent tests: 1
-> Dispatcher affinity: true
-> Default test timeout: 600000ms
-> Default test order: Sequential
-> Default isolation mode: SingleInstance
-> Global soft assertions: false
-> Write spec failure file: false
-> Fail on ignored tests: false
-> Spec execution order: SpecExecutionOrder
-> Remove test name whitespace: false
-> Append tags to test names: false
-> Extensions
- io.kotest.engine.extensions.SystemPropertyTagExtension
- io.kotest.core.extensions.RuntimeTagExtension
- io.kotest.engine.extensions.RuntimeTagExpressionExtension
org.danilopianini.template.test.Tests > A greeting should get printed STARTED
org.danilopianini.template.test.Tests > A greeting should get printed STANDARD_OUT
[:hello=SUCCESS]
> Task :hello
Hello from Danilo Pianini
BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed
org.danilopianini.template.test.Tests > A greeting should get printed PASSED
<<<Other tests have no output!>>>
> Task :testUnderJava9
> Task :testUnderJava8
> Task :testUnderJava16
> Task :testUnderJava15
> Task :testUnderJava14
> Task :testUnderJava13
> Task :testUnderJava12
> Task :testUnderJava11
> Task :testUnderJava10
BUILD SUCCESSFUL in 23s
36 actionable tasks: 36 executed
<<<SNIP>>>
从build scan, it appears that tests are not executed but those with JDK8. I'm puzzled, the docs说起,这应该是直截了当的:
tasks.register<Test>("testsOn14") {
javaLauncher.set(javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(14))
})
}
我想我找出了我遇到的问题的根本原因,我发布了解决方案以防其他人遇到类似问题。
我有以下测试配置:
tasks.test {
useJUnitPlatform()
testLogging {
showStandardStreams = true
showCauses = true
showStackTraces = true
events(*org.gradle.api.tasks.testing.logging.TestLogEvent.values())
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}
正在将名为 test
的任务指示给 useJunitPlatform()
。此设置不会自动传播到所有后续 Test
任务(当然)。所以,在这种情况下,解决方案就是简单地使用:
tasks.withType<Test> {
// Same configuration as above
}
更新 2022-03-16
我决定创建一个 multi-JVM testing plugin for Gradle,以便创建所有测试任务,并且跨项目需要更少的样板文件。
我有一个 Gradle 项目,它使用由工具链指定的 Java 版本 API:
val minimumJava = JavaLanguageVersion.of(8)
val maximumJava = JavaLanguageVersion.of(16)
java {
toolchain {
languageVersion.set(minimumJava)
vendor.set(JvmVendorSpec.ADOPTOPENJDK)
}
}
我希望能够使用支持的最低 Java 版本进行编译,然后 运行 使用项目支持的所有 JDK 进行测试。 我尝试了以下方法,但显然只执行了原始测试,所有其他测试都没有执行,即使所需的 JDK 已正确下载和设置:
for (javaVersion in JavaLanguageVersion.of(minimumJava.asInt() + 1)..maximumJava) {
val base = tasks.test.get()
val testTask = tasks.register<Test>("testUnderJava${javaVersion.asInt()}") {
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion.set(javaVersion)
}
)
classpath = base.classpath
testClassesDirs = base.testClassesDirs
isScanForTestClasses = true
}
tasks.test.configure { finalizedBy(testTask) }
}
这是哑终端中的 运行:
❯ TERM=dumb ./gradlew test testUnderJava10 --rerun-tasks --scan
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on
<<<SNIP>>>
> Task :testClasses
> Task :test
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on
Gradle Test Executor 4 STANDARD_OUT
~~~ Kotest Configuration ~~~
-> Parallelization factor: 1
-> Concurrent specs: null
-> Global concurrent tests: 1
-> Dispatcher affinity: true
-> Default test timeout: 600000ms
-> Default test order: Sequential
-> Default isolation mode: SingleInstance
-> Global soft assertions: false
-> Write spec failure file: false
-> Fail on ignored tests: false
-> Spec execution order: SpecExecutionOrder
-> Remove test name whitespace: false
-> Append tags to test names: false
-> Extensions
- io.kotest.engine.extensions.SystemPropertyTagExtension
- io.kotest.core.extensions.RuntimeTagExtension
- io.kotest.engine.extensions.RuntimeTagExpressionExtension
org.danilopianini.template.test.Tests > A greeting should get printed STARTED
org.danilopianini.template.test.Tests > A greeting should get printed STANDARD_OUT
[:hello=SUCCESS]
> Task :hello
Hello from Danilo Pianini
BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed
org.danilopianini.template.test.Tests > A greeting should get printed PASSED
<<<Other tests have no output!>>>
> Task :testUnderJava9
> Task :testUnderJava8
> Task :testUnderJava16
> Task :testUnderJava15
> Task :testUnderJava14
> Task :testUnderJava13
> Task :testUnderJava12
> Task :testUnderJava11
> Task :testUnderJava10
BUILD SUCCESSFUL in 23s
36 actionable tasks: 36 executed
<<<SNIP>>>
从build scan, it appears that tests are not executed but those with JDK8. I'm puzzled, the docs说起,这应该是直截了当的:
tasks.register<Test>("testsOn14") {
javaLauncher.set(javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(14))
})
}
我想我找出了我遇到的问题的根本原因,我发布了解决方案以防其他人遇到类似问题。 我有以下测试配置:
tasks.test {
useJUnitPlatform()
testLogging {
showStandardStreams = true
showCauses = true
showStackTraces = true
events(*org.gradle.api.tasks.testing.logging.TestLogEvent.values())
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}
正在将名为 test
的任务指示给 useJunitPlatform()
。此设置不会自动传播到所有后续 Test
任务(当然)。所以,在这种情况下,解决方案就是简单地使用:
tasks.withType<Test> {
// Same configuration as above
}
更新 2022-03-16
我决定创建一个 multi-JVM testing plugin for Gradle,以便创建所有测试任务,并且跨项目需要更少的样板文件。