1

I have a simple JUnit "smoke" test which check if Spring context is loaded correctly:

@SpringBootTest
class ContextLoadJUnit {

    @Test
    fun contextLoads() {
        //empty by design
    }
}

I'm trying to rewrite it into kotest. I've tested two versions:

@SpringBootTest
@ApplyExtension(SpringTestExtension::class)
class ContextLoadKotestWordSpec : WordSpec({
  "context" should { "load with WordSpec" {} }
})

@SpringBootTest
class ContextLoadKotestFunSpec : FunSpec() {

    override fun extensions(): List<Extension> {
        return listOf(SpringExtension)
    }
    init {
        test("context should load with FunSpec") {}
    }
}

I have all three tests in one file:

import io.kotest.core.extensions.ApplyExtension
import io.kotest.core.extensions.Extension
import io.kotest.core.spec.style.FunSpec
import io.kotest.core.spec.style.WordSpec
import io.kotest.extensions.spring.SpringExtension
import io.kotest.extensions.spring.SpringTestExtension
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
class ContextLoadJUnit {

    @Test
    fun contextLoads() {
        //empty by design
    }
}

@SpringBootTest
@ApplyExtension(SpringTestExtension::class)
class ContextLoadKotestWordSpec : WordSpec({
  "context" should { "load with WordSpec" {} }
})

@SpringBootTest
class ContextLoadKotestFunSpec : FunSpec() {

    override fun extensions(): List<Extension> {
        return listOf(SpringExtension)
    }
    init {
        test("context should load with FunSpec") {}
    }
}

When they are running and passing, they are handled correctly:

3 tests are passing

But when they are failing, kotest are "wrapped" into initializationError and it looks like I have only two tests:

looks like 2 tests are failing (but I have 3)

Is there a way to prepare kotest somehow differently, avoid the initializationError and see that I have three separate failing tests?

Piotr Pradzynski
  • 4,190
  • 5
  • 23
  • 43
  • 2
    Okay I'm going to be That Guy, sorry! Do you really need to find a way to run 3 tests in one file? It seems like you wanted to migrate from JUnit to Kotest, and you can do that with one test - just pick one style and move on. – aSemy Aug 23 '22 at 16:25
  • Can you try splitting them into separate files, as @asemy says. I guess the junit one is breaking the other two. – sksamuel Aug 24 '22 at 03:29
  • If you run the tests through the CLI does everything works correctly? Or if you check any generated XML or HTML reports? My guess is that IntelliJ is getting confused by the tests & suites being named identically - it's only a UI problem. – aSemy Aug 24 '22 at 04:54
  • Guys, the 3 tests in one file is just an example. It behaves exactly the same way in a three different files. The same result is also via CLI. – Piotr Pradzynski Aug 24 '22 at 05:41

1 Answers1

2

Kotest's SpringExtension is an instance of SpringTestExtension which is a SpecExtension and a TestCaseExtension.

The initialization of the application context happens in the intercept function of the SpecExtension part of the extension. When the initialization of the application context fails, the spec has never been executed, and thus, the single tests of the spec have never been initialized. This has the effect that IntelliJ does not show any failed tests -- there simply are no failed tests, only a failed spec.

We can by-pass that behavior by taking only parts of the SpringExtension's initialization logic and put it in a test like this:

import io.kotest.core.spec.style.FunSpec
import org.springframework.test.context.TestContextManager

class KotestWithSpring : FunSpec() {
    init {
        val testContextManager = TestContextManager(this::class.java)
        test("context should load") {
            testContextManager.beforeTestClass()
            testContextManager.prepareTestInstance(this)
        }
    }
}

When the application context for this test class fails, it looks like this:

Screenshot of test execution result in IntelliJ

Karsten Gabriel
  • 3,115
  • 6
  • 19