icehawk
icehawk

Reputation: 1235

Gradle does not find my tests with Kotlin and JUnit 5

I have written some basic unit tests with Kotlin and Junit 5. Unfortunately, when I run them from Intellij IDEA, the tests are not found by Gradle. I am getting the message "No tests found for given includes: [de.mhaug.phd.btcwallet.BasicTests]" from Gradle and the message "Test event not received" from Intellij.

Interestingly, running it from the commandline with "./gradlew :clean :test" reports a successful build. However, my first test is obviously red, so this shows that Gradle did not execute it.

I already tried running it with more verbose output but nothing helpful showed up. Here is a minimal (not) working example:

package de.mhaug.phd.btcwallet

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Test

class BasicTests {
  @Test
  fun hey() {
    assertEquals(3,1+1)
  }

  @Test
  fun hey2() {
    assertFalse(3==1+1)
  }
}

This is my build.gradle:

buildscript {
    ext.kotlin_version = '1.2.10'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

group 'de.mhaug.phd'
version '1.0-SNAPSHOT'

apply plugin: 'kotlin'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile group: 'org.bouncycastle', name: 'bcprov-jdk16', version: '1.46'
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.0.2'
    testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.0.2'
//    testCompile group: 'org.junit.platform', name: 'junit-platform-runner', version: ''
//    testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.0.2'
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

How can I make Intellij/Gradle execute my tests?

Upvotes: 40

Views: 26053

Answers (7)

Pierre Vieira
Pierre Vieira

Reputation: 3300

In my case I fixed by the following way (in the root of your build.gradle module):

tasks.test {
    useJUnitPlatform()
}

Upvotes: 0

PSanetra
PSanetra

Reputation: 524

I accidentially imported org.junit.Test instead of org.junit.jupiter.api.Test

Upvotes: 0

Bass
Bass

Reputation: 5296

Be careful when writing your tests as expression-body functions: their return type should still remain Unit. Example:

import org.assertj.core.api.Assertions.assertThat
import kotlinx.coroutines.runBlocking

// ...

    @Test
    fun t() = runBlocking {
        assertThat(42).isEqualTo(42)
    }

The return type of such test method will be AbstractIntegerAssert<*> and not Unit, so it will be still recognized as a test by IDEA but not by the JUnit engine (when invoked via gradle test).

Correct example:

    @Test
    fun t() = runBlocking<Unit> {
        assertThat(42).isEqualTo(42)
    }

Upvotes: 2

Stephan Pr&#228;tsch
Stephan Pr&#228;tsch

Reputation: 119

I needed to add

        testImplementation(platform("org.junit:junit-bom:5.7.0"))

as well. In sum

        // junit 5
        testImplementation(platform("org.junit:junit-bom:5.7.0"))
        testImplementation('org.junit.jupiter:junit-jupiter-api')
        testCompile('org.junit.jupiter:junit-jupiter-params')
        testRuntime('org.junit.jupiter:junit-jupiter-engine')
        testCompile group: 'org.mockito', name: 'mockito-inline', version: '3.2.0'
        test.useJUnitPlatform() // fix "test events not received" bug in IDEA
        testCompile 'com.willowtreeapps.assertk:assertk-jvm:0.23'

Upvotes: 0

WesternGun
WesternGun

Reputation: 12728

No, the first comment of @JB Nizet has pointed it out: add test.useJUnitPlatform() alongside your JUnit 5 dependencies. It is the way.

http://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle

test {
    useJUnitPlatform()
}

or:

dependency {
    ...
    // junit 5
    testImplementation ('org.junit.jupiter:junit-jupiter-api')
    testCompile ('org.junit.jupiter:junit-jupiter-params')
    testRuntime ('org.junit.jupiter:junit-jupiter-engine')
    testCompile ('org.mockito:mockito-junit-jupiter')
    test.useJUnitPlatform() // fix "test events not received" bug in IDEA
}

Upvote his comment, not this answer!

Upvotes: 42

Abhinav Manchanda
Abhinav Manchanda

Reputation: 6631

I faced the same issue with Java 11 and JUnit 5. It started working for me as soon as I made the class public.

Upvotes: 0

PHPirate
PHPirate

Reputation: 7572

I think your particular issue of tests not being run was or would be solved by updated everything to the latest version (Gradle, Kotlin, IntelliJ, etc.). Everything is moving really fast at the moment so keeping up to date is a must.

About the 'test events were not received'

As far as I know this is sort of expected. The point is, when using Gradle tasks, either trust your tests were run or figure out a way to display per-test logging.

You need to make a distinction when 'executing the gradle task' or 'running tests using IntelliJ' (e.g. by clicking the gutter icon next to a test).

Running from IntelliJ.

IntelliJ integrates wonderfully with Gradle, in the sense that if you run from IntelliJ, then it will not only run the tests (via Gradle?) but also show some nice test results. All works well with JUnit 5, Kotlintest, Spek, using normal Gradle or Gradle Kotlin DSL or whatever you use.

Shameless self-advert: JUnit 5 and Gradle (also shows Gradle test logging): How to use JUnit 5 with Gradle? and JUnit 5, Kotlintest and Gradle Kotlin DSL: How to run kotlintest tests using the Gradle Kotlin DSL?

Running the Gradle task.

However, when you run a Gradle task using the Gradle tool window, you will see as you mentioned 'test events were not received'. I think this is because you just run a Gradle task which ran the test, and that does not have anything to do with IntelliJ per se, it doesn't integrate in that it reports back results - it just prints to the command line.

Compare for example with running the Kotlin. When you use the Gradle task, it will output in build/. But when you run the main method using the gutter icon, so using IntelliJ, it will output in out/. These are two different things running.

Upvotes: 2

Related Questions