I'm using JUnit 5 platform via Gradle.
My current build file has configuration clause
junitPlatform {
platformVersion '1.0.0-M5'
logManager 'java.util.logging.LogManager'
enableStandardTestTask true
filters {
tags {
exclude 'integration-test'
}
packages {
include 'com.scherule.calendaring'
}
}
}
That works fine. But I also need to run integration tests which require the application to be built, dockerized and run in background. So I should have second configuration like this which would be launched only then... how to achieve this? Normally I would extend Test task creating IntegrationTest task but it doesn't fit JUnit Platform where there is no simple task running tests...
I know I could do sth like this
task integrationTests(dependsOn: "startMyAppContainer") {
doLast {
def request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectPackage("com.scherule.calendaring"))
.filters(includeClassNamePatterns(".*IntegrationTest"))
.build()
def launcher = LauncherFactory.create()
def listener = new SummaryGeneratingListener()
launcher.registerTestExecutionListeners(listener)
launcher.execute(request)
}
finalizedBy(stopMyAppContainer)
}
but is there a simpler way? More consistent.
This is not fully supported in Gradle with the JUnit5 plugin yet (though it's getting closer all the time). There are several workarounds. This is the one I use: it's a bit verbose, but it does the same thing as maven's test vs. verify.
Gradle's main and test sourceSets are good as they are. Add a new integrationTest sourceSet that describes only your integration tests. You can use file names but that might mean you have to tweak the test sourceSet to skip files that it currently includes (in your example, you'd want to remove ".*IntegrationTest" from the test sourceSet and leave it only in the integrationTest sourceSet). So I prefer to use a root directory name that is different from the test sourceSet's one.
sourceSets {
integrationTest {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integrationTest/java')
}
resources.srcDir file('src/integrationTest/resources')
}
}
Since we have the java plugin, this very nicely creates the integrationTestCompile
and integrationTestRuntime
functions for using with the dependencies
block:
dependencies {
// .. other stuff snipped out ..
testCompile "org.assertj:assertj-core:${assertjVersion}"
integrationTestCompile("org.springframework.boot:spring-boot-starter-test") {
exclude module: 'junit:junit'
}
}
Nice!
As you pointed out, you do need to have a task for running integration tests. You could use the launcher as in your example; I just delegate to the existing console runner in order to take advantage of the simple command line options.
def integrationTest = task('integrationTest',
type: JavaExec,
group: 'Verification') {
description = 'Runs integration tests.'
dependsOn testClasses
shouldRunAfter test
classpath = sourceSets.integrationTest.runtimeClasspath
main = 'org.junit.platform.console.ConsoleLauncher'
args = ['--scan-class-path',
sourceSets.integrationTest.output.classesDir.absolutePath,
'--reports-dir', "${buildDir}/test-results/junit-integrationTest"]
}
That task definition includes a dependsOn and shouldRunAfter, to make sure that when you run your integration tests, the unit tests are run first. To ensure that your integration tests are run when you ./gradlew check
, you need to update the check task:
check {
dependsOn integrationTest
}
Now you use ./gradlew test
like ./mvnw test
, and ./gradlew check
like ./mvnw verify
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With