kotlin.test provides @Test and assertion functions (assertEquals, assertTrue, assertFailsWith) with Kotlin-friendly naming, delegating to JUnit as its actual test runner on the JVM — the same underlying JUnit annotations and lifecycle still apply, just accessed through Kotlin-idiomatic wrappers, and the same API surface is source-compatible on Kotlin/Native and Kotlin/JS too. Kotest is a separate, more expansive third-party framework offering several distinct testing styles (a Given-When-Then BDD style, a simple function-based style, and others) plus a fluent assertion DSL (result shouldBe 5) that many find more readable than JUnit's assertEquals(5, result) argument order.
A basic test with kotlin.test
assertFailsWith checks that calling the lambda throws the given exception type — a cleaner, more Kotlin-idiomatic way to express "this should throw" than JUnit's assertThrows on its own.
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class CalculatorTest {
@Test
fun addsTwoNumbers() {
val calc = Calculator()
assertEquals(5, calc.add(2, 3))
}
@Test
fun throwsOnDivideByZero() {
val calc = Calculator()
assertFailsWith<ArithmeticException> {
calc.divide(1, 0)
}
}
}The same test with Kotest's fluent style
shouldBe reads closer to natural language than assertEquals's argument-order convention, and Kotest's StringSpec style lets each test's description double as its actual name in test output.
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
class CalculatorTest : StringSpec({
"adding two numbers" {
Calculator().add(2, 3) shouldBe 5
}
})Testing coroutines: runTest
runTest (from kotlinx-coroutines-test) runs a suspending test body while automatically fast-forwarding through any delay() calls, so a test involving real coroutine timing doesn't actually have to wait in real time.
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
class DataLoaderTest {
@Test
fun loadsData() = runTest { // suspending test body, delay() calls fast-forwarded
val result = loadDataAsync()
assertEquals("data", result)
}
}