I'm using this blog post to configure integration tests for a Spring Boot project, but I'm pretty stuck on declaring the source sets. I also found this post on StackOverflow, but I think I'm a bit further already.
My project structure is
project
|_ src
|_ main
| |_ kotlin
| |_ resources
|_ testIntegration
| |_ kotlin
| |_ resources
|_ test
| |_ kotlin
| |_ resources
|_ build.gradle.kts
|_ ... other files
And build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
idea
kotlin("jvm")
id("org.springframework.boot") version "2.0.5.RELEASE"
id("org.jetbrains.kotlin.plugin.spring") version "1.2.71"
}
fun DependencyHandlerScope.springBoot(module: String) = this.compile("org.springframework.boot:spring-boot-$module:2.0.5.RELEASE")
fun DependencyHandlerScope.springBootStarter(module: String) = this.springBoot("starter-$module")
dependencies {
springBoot("devtools")
springBootStarter("batch")
springBootStarter("... spring boot dependencies")
compile("... more dependencies")
testCompile("... more test dependencies")
}
val test by tasks.getting(Test::class) {
useJUnitPlatform { }
}
kotlin {
sourceSets {
val integrationTest by creating {
kotlin.srcDir("src/testIntegration/kotlin")
resources.srcDir("src/testIntegration/resources")
}
}
}
val integrationTestCompile by configurations.creating {
extendsFrom(configurations["testCompile"])
}
val integrationTestRuntime by configurations.creating {
extendsFrom(configurations["testRuntime"])
}
val testIntegration by tasks.creating(Test::class) {
group = "verification"
testClassesDirs = kotlin.sourceSets["integrationTest"].kotlin
}
idea {
module {
testSourceDirs.addAll(kotlin.sourceSets["integrationTest"].kotlin.srcDirs)
testSourceDirs.addAll(kotlin.sourceSets["integrationTest"].resources.srcDirs)
}
}
I think I'm pretty much in the right direction. At least it doesn't throw an exception any more :)
When I run the testIntegration task, I get the following output:
Testing started at 12:08 ...
12:08:49: Executing task 'testIntegration'...
> Task :project:compileKotlin UP-TO-DATE
> Task :project:compileJava NO-SOURCE
> Task :project:processResources UP-TO-DATE
> Task :project:classes UP-TO-DATE
> Task :project:compileTestKotlin UP-TO-DATE
> Task :project:compileTestJava NO-SOURCE
> Task :project:processTestResources UP-TO-DATE
> Task :project:testClasses UP-TO-DATE
> Task :project:testIntegration
BUILD SUCCESSFUL in 2s
5 actionable tasks: 1 executed, 4 up-to-date
12:08:51: Task execution finished 'testIntegration'.
Also, IntelliJ doesn't recognise the testIntegration directories as Kotlin packages.
gradle file which helps Gradle build tool to specify this build is a debug build with certain keyAlias etc. So these building blocks, API, etc are formats to use Gradle in android, hence called Gradle DSL (domain-specific language).
Gradle's Kotlin DSL provides an alternative syntax to the traditional Groovy DSL with an enhanced editing experience in supported IDEs, with superior content assist, refactoring, documentation, and more.
To run integration tests from intelliJ, locate the /src/integration-test package as shown below. Right-click on the entire integration test suite, or choose a targeted integration test, then choose the Run '{chosen test}' option. After running an integration test, the intelliJ event log will display test result data.
I was finally able to figure it out thanks to some help on the Kotlin Slack channel. First of all I had to upgrade to Gradle version 4.10.2.
For more info have a look at these two pages from Gradle:
Then I just had to create the sourceSets for the integrationTests
sourceSets {
create("integrationTest") {
kotlin.srcDir("src/integrationTest/kotlin")
resources.srcDir("src/integrationTest/resources")
compileClasspath += sourceSets["main"].output + configurations["testRuntimeClasspath"]
runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath
}
}
This would work just fine for Java, but since I'm working with Kotlin I had to add an extra withConvention
wrapper
sourceSets {
create("integrationTest") {
withConvention(KotlinSourceSet::class) {
kotlin.srcDir("src/integrationTest/kotlin")
resources.srcDir("src/integrationTest/resources")
compileClasspath += sourceSets["main"].output + configurations["testRuntimeClasspath"]
runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath
}
}
}
In the docs they only put runtimeClasspath += output + compileClasspath
, but I added sourceSets["test"].runtimeClasspath
so I can directly use the test dependencies instead of declaring new dependencies for the integrationTest
task.
Once the sourceSets were created it was a matter of declaring a new task
task<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath
mustRunAfter(tasks["test"])
}
After this the tests still didn't run, but that was because I'm using JUnit4. So I just had to add useJUnitPlatform()
which makes this the final code
task<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath
mustRunAfter(tasks["test"])
useJUnitPlatform()
}
I didnt like the use of withConvention and how the kotlin src dir was set. So after check out both gradle docs here and here, I came up with this:
sourceSets {
create("integrationTest") {
kotlin {
compileClasspath += main.get().output + configurations.testRuntimeClasspath
runtimeClasspath += output + compileClasspath
}
}
}
val integrationTest = task<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath
mustRunAfter(tasks["test"])
}
tasks.check {
dependsOn(integrationTest)
}
I preferr the less verbose style when using kotlin {
and the use of variable for the new integrationTestTask.
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