Integration tests with Gradle Kotlin DSL

gradle kotlin extra properties
gradle kotlin dsl properties
gradle integration test
gradle skip integration tests
kotlin integration test
gradle test filter
gradle kotlin dependson
gradle testng

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.

Integration test samples · Issue #345 · gradle/kotlin-dsl-samples , The check- task rule of the gradle-script-kotlin build runs the tasks task on samples. This is not enough, we need to actually run tasks defined in  JUnit 5 and Gradle. Gradle 5+ has been out for a while now and with that we finally got the ability to write our Gradle scripts in Kotlin. Almost every example out there about JUnit and Gradle is still using the old dependencies or Groovy Gradle syntax, so let’s try to migrate a Groovy build using JUnit Platform to Kotlin DSL, specifically, based on examples about how to extend Gradle’s

As of Gradle 5.2.1 see https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests

sourceSets {
    create("intTest") {
        compileClasspath += sourceSets.main.get().output
        runtimeClasspath += sourceSets.main.get().output
    }
}

val intTestImplementation by configurations.getting {
    extendsFrom(configurations.testImplementation.get())
}

configurations["intTestRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())

dependencies {
    intTestImplementation("junit:junit:4.12")
}

val integrationTest = task<Test>("integrationTest") {
    description = "Runs integration tests."
    group = "verification"

    testClassesDirs = sourceSets["intTest"].output.classesDirs
    classpath = sourceSets["intTest"].runtimeClasspath
    shouldRunAfter("test")
}

tasks.check { dependsOn(integrationTest) }

Running Kotlin Tests With Gradle, Can create a Gradle project that can compile unit and integration tests which use Kotlin. Know how we can add custom test sets to our Gradle  The Kotlin programming language is used to write a Gradle Plugin focused on orchestrating ElasticMQ instances, with Unit, Functional and even Integration Tests!

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.

Gradle Kotlin DSL Primer, The Kotlin DSL is fully supported by IntelliJ IDEA and Android Studio. same problem from the command line, then the issue is with the build rather than the IDE integration. tasks.test { // lazy configuration } // Lazy reference val testProvider:  Each Gradle release is meant to be used with a specific version of the kotlin-dsl plugin and compatibility between arbitrary Gradle releases and kotlin-dsl plugin versions is not guaranteed. Using an unexpected version of the kotlin-dsl plugin in a build will emit a warning and can cause hard to diagnose problems.

Testing in Java & JVM projects, Kotlin DSL is fully supported in Intellij IDEA and Android Studio. For example, when compiling code, Gradle does not need to configure tasks that run tests. We provide all-open plugin support both for Gradle and Maven with the complete IDE integration. Note: For Spring you can use the kotlin-spring compiler plugin . Using in Gradle. Add the plugin artifact to the buildscript dependencies and apply the plugin:

Migrating build logic from Groovy to Kotlin, Gradle 5 has been out for a while now and with that we finally got the ability to write How can I migrate my JUnit-enabled Gradle scripts to Kotlin Gradle DSL? And also will apply to any Test task defined on our build. accessor and comes with full IDE integration like code completion and inspections. Currently tested against Kotlin plugin versions 1.2.20-1.2.71 and 1.3.0-1.3.11 using Gradle 5.1; Kotlin plugin versions prior to 1.2.30 do not support Java 10+ Version of the Kotlin plugin prior to 1.2.20 are unlikely to work; Support for Gradle Kotlin DSL; Usage. Add the following to your build.gradle file.

Using Gradle Kotlin DSL with junit 5, gradle . Inside integration-test.gradle , I set up the following: sourceSets { integrationTest { compileClasspath += sourceSets.main.output +  Write a simple library in Kotlin, test it with JUnit, generate API docs with Dokka, and publish it using Gradle's Kotlin DSL of course. Use the Build Init plugin to create a Scala project, build it, run tests and view the test report, and generate the API docs.

Comments
  • Glad you figured it out, since it helped me with my problem. I find it difficult to understand when to use "withConvention"...it seems always when another language as Java is used (in my case Groovy for Spock tests). It makes sense when you think of the typesystem, but I would find it more consistent if the the withConvention(JavaXX) would be required instead of inferred.
  • what you only did was to copy the piece of code from Gradle's documentation: docs.gradle.org/current/userguide/…