DEV Community

Ryszard Grodzicki
Ryszard Grodzicki

Posted on

Upgrading Kotest (Kotlintest) to version 4.2+

Kotest is one of the most popular testing frameworks for Kotlin (known as Kotlintest before version 4.0).
In recent versions there were some changes in class names and general behaviour which makes the transition to newer version not so obvious.

As of writing this post, the recent version of Kotest is 4.2.5 and the examples will be based on it.

Kotlintest to Kotest

If you already have Kotest in your project in version 4.0 or higher then you may skip this section.

So upgrading from old Koltintest you have to remember to change both all of the kotlintest dependencies in pom.xml/build.gradle and change all imports in code files.

Remember that the groupId was changed to io.kotest and some artifact ids have also changed.
Ie. 'kotlintest-runner-junit5' was changed to 'kotest-runner-junit5-jvm'
and
'kotlintest-assertions' as changed to 'kotest-assertions-core-jvm'

General Configuration

Okay, so earlier you could use an interface to make the configuration easier, like setting an isolation mode or adding listeners. (We'll talk about Spring listener later)

So instead of overriding a method, which is more cumbersome:

class ApplicationTest : StringSpec() {
    override fun isolationMode() = IsolationMode.InstancePerTest
    init {
        "sample test" {}
    }
}
Enter fullscreen mode Exit fullscreen mode

You could make such interface:

interface IsolationPerTest : SpecConfigurationMethods {
    override fun isolationMode(): IsolationMode = IsolationMode.InstancePerTest
}
Enter fullscreen mode Exit fullscreen mode

And then use it in a test just by implementing this interface to set an isolation mode:

class ApplicationTest : StringSpec(), IsolationPerTest {
    init {
        "sample test" {}
    }
}
Enter fullscreen mode Exit fullscreen mode

In Kotest 4.2.5 though, the interface has changed its name from SpecConfigurationMethods to SpecFunctionConfiguration.

Spring integration and other listeners

Same as with isolation mode: You can either do this by overriding a method in each test:
override fun listeners(): List<TestListener> = listOf(SpringListener)
or use an interface

interface SpringListenerSpec: SpecConfigurationMethods {
    override fun listeners(): List<TestListener> = listOf(SpringListener)
}
Enter fullscreen mode Exit fullscreen mode

and implement it in the test class (here together with the isolation interface):

@SpringBootTest
class ApplicationTest : StringSpec(), SpringListenerSpec, IsolationPerTest {
    init {
        "sample test" {}
    }
}
Enter fullscreen mode Exit fullscreen mode

What has recently changed is the type of SpringListener - now it's just an alias to a new SpringTestListener class, but it shouldn't be a problem if you've omitted the type declaration of listeners() function.

Just remember to include a @SpringBootTest or @ContextConfiguration annotation when you need any of the spring autowiring.

For more information about Kotest - Spring integration here are the docs.

Extra - global configuration

There is another way of configuring Kotest, this time - globally.
You can create an object extending the AbstractProjectConfig just like that:

object KotestConfiguration : AbstractProjectConfig() {
    override val isolationMode = IsolationMode.InstancePerTest
    override val parallelism = 3
    override val testCaseOrder = TestCaseOrder.Random
}
Enter fullscreen mode Exit fullscreen mode

In this example we've set all tests to have an isolation mode InstancePerTest (more about isolation in Kotest docs), to run in parallel (it should work, but may be problematic in some cases).
We've also made the order of test cases random. It's useful for being sure, that our tests are not depending on the order of execution, as it's a very bad practice.

Thanks for reading and let me know if you've had any more problems with Kotest versions so I can update the article.

Top comments (0)