7

What do I want?

I want to run my tests using kotlintest, and I succeeded in running them from IntelliJ by clicking the icon next to the test class. I also have JUnit 5 tests in my project. I am now starting to use the Gradle Kotlin DSL, and I managed to run the Gradle task check which executed the JUnit 5 tasks.

What is the problem?

The kotlintest test is not run! It is not discovered by Gradle it seems, as a failing test lets the Gradle task succeed. So,

How to run kotlintest tests using the Gradle Kotlin DSL while also using JUnit 5?

What did I try?

How can I run kotlintest tests with gradle? is essentially the old version of the question but already obsolete since using different technology: JUnit 4 and Gradle instead of the Gradle Kotlin DSL. All other question I could find are either for JUnit 4, or JUnit 5 without kotlintest.

Project setup

I am using Gradle 4.6. My test is

import io.kotlintest.matchers.exactly
import io.kotlintest.matchers.shouldBe
import io.kotlintest.specs.FunSpec

class KotlinTest: FunSpec() {

    init {
        testCalculate()
    }

    /** This failing test will not fail the Gradle check. */
    fun testCalculate() = test("one plus one is two") {
        (1+1).toDouble() shouldBe exactly(42.0)
    }

}

and my build.gradle.kts is

import org.gradle.api.plugins.ExtensionAware

import org.junit.platform.gradle.plugin.FiltersExtension
import org.junit.platform.gradle.plugin.EnginesExtension
import org.junit.platform.gradle.plugin.JUnitPlatformExtension

group = "mypackage"
version = "0.0"

// JUnit 5
buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath("org.junit.platform:junit-platform-gradle-plugin:1.1.0")
    }
}

apply {
    plugin("org.junit.platform.gradle.plugin")
}

// Kotlin configuration.
plugins {
    application
    kotlin("jvm") version "1.2.30"
    java // Required by at least JUnit.
}

application {
    mainClassName = "mypackage.HelloWorld"
}

dependencies {
    compile(kotlin("stdlib"))
    // To "prevent strange errors".
    compile(kotlin("reflect"))
    // Kotlin reflection.
    compile(kotlin("test"))
    compile(kotlin("test-junit"))

    // JUnit 5
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.1.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.1.0")
    testRuntime("org.junit.platform:junit-platform-console:1.1.0")

    // Kotlintests are not run anyway when using JUnit 5 as well.
    testCompile("io.kotlintest:kotlintest:2.0.7")

}

repositories {
    jcenter()
}

PS Complete project at GitHub.

PHPirate
  • 7,023
  • 7
  • 48
  • 84

3 Answers3

6

With more recent versions of the Kotlin Gradle plugin, adding this is sufficient:

dependencies {
    testImplementation(kotlin("test-junit5"))
    testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.5.2")
}

tasks {
    test {
        useJUnitPlatform()
    }
}

This is assuming that you want to stick to the interface of kotlin.test. For example, a small test could look like this:

import kotlin.test.Test
import kotlin.test.assertEquals

class SomeTest {
    @Test
    fun testBar() {
        assertEquals(5, 6)
    }
}

If you want to run your tests from IDEA, you need to add some additional dependencies:

dependencies {
    // ...
    testCompileOnly("org.junit.jupiter", "junit-jupiter-api", "5.5.2")
    testCompileOnly("org.junit.jupiter", "junit-jupiter-params", "5.5.2")
}
Raphael
  • 9,779
  • 5
  • 63
  • 94
  • Do you mean to replace the kotlintest dependencies with `testImplementation(kotlin("test-junit5"))`? That doesn't really work for me with the test code from the question, I get unresolved references. Can you maybe point to documentation about this, or give a complete `build.gradle.kts`? – PHPirate Jun 22 '19 at 13:05
  • 1
    @PHPirate My bad, I didn't realize you were _not_ going for `kotlin.test`. – Raphael Jun 22 '19 at 15:12
4

Since kotlintest version 3, JUnit 5 is supported! Just replace, in your build.gradle.kts,

testCompile("io.kotlintest:kotlintest:2.0.7")

by

testCompile("io.kotlintest:kotlintest-core:3.0.2")
testCompile("io.kotlintest:kotlintest-assertions:3.0.2")
testCompile("io.kotlintest:kotlintest-runner-junit5:3.0.2")

as clarified in the changelog.

Then either run the Gradle task check (in IntelliJ in the Gradle tool window on the right) or, in IntelliJ, click the gutter icon to run only a specific test or set of tests.

PHPirate
  • 7,023
  • 7
  • 48
  • 84
  • Does this set the tests to run, or do you need to change the test config to make them run? – jrtapsell Apr 03 '18 at 20:45
  • @jrtapsell What do you mean with the 'test config'? If you have the correct dependencies in your `build.gradle.kts` then executing the gradle task `check` should run your tests. – PHPirate Apr 03 '18 at 20:47
  • I think the only thing you're doing wrong in your initial post is you haven't changed your KotlinTest imports to be `io.kotlintest:kotlintest-runner-junit5` instead of `io.kotlintest:kotlintest` – sksamuel Apr 03 '18 at 22:39
  • @monkjack Sorry, which imports do you mean? I can't find where I should be importing `io.kotlintest:kotlintest`. Btw, thanks for you answer, it has a much more minimal example. I hope it makes it easier for more people to use the Gradle Kotlin DSL! (Personally I have found the docs a little lacking for beginners...) – PHPirate Apr 04 '18 at 06:09
3

Similar to @PhPirate's answer, to use KotlinTest 3.0.x with gradle, you need to.

  1. Add the gradle plugin for junit 5 (also called the junit platform)
  2. Add the gradle junit plugin to the classpath of your buildscript
  3. Add KotlinTest junit5 runner to your test dependencies.

The first two steps are common for any project that uses junit platform - which includes junit5 itself, KotlinTest, Spek, and so on.

A basic gradle config looks like this:

apply plugin: 'org.junit.platform.gradle.plugin'

buildscript {
    ext.kotlin_version = '1.2.31'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.junit.platform:junit-platform-gradle-plugin:1.1.0"
    }
}

dependencies {
    testCompile 'io.kotlintest:kotlintest-runner-junit5:3.0.2'
}

You could also clone the gradle sample repo here which has a simple gradle project configured with KotlinTest.

sksamuel
  • 16,154
  • 8
  • 60
  • 108