What is the kotlin.test library, and how do you write a basic assertion-based unit test with it?
answer
- kotlin.test = annotations + assertions, not a runner
- @Test, @BeforeTest, @AfterTest, @Ignore
- assertEquals(expected, actual) — expected first
- assertFailsWith<T> returns the exception
- Multiplatform: compiles in commonTest, JUnit runs it on JVM
basics
~10 skotlin.test is Kotlin's small built-in testing toolkit. You mark a function with @Test, then call assertions like assertEquals or assertTrue to check that your code produced the right result.
solid answer
~30 skotlin.test is a thin, multiplatform assertion and annotation library. It provides annotations (@Test, @BeforeTest, @AfterTest, @Ignore) and assertion functions (assertEquals, assertTrue, assertFalse, assertNull, assertNotNull, assertSame, assertFailsWith, fail). On JVM these annotations are mapped onto an underlying engine (usually JUnit) via kotlin-test-junit5, so JUnit actually runs them; on JS/Native they map to platform runners. Crucially, assertEquals(expected, actual) takes expected FIRST. assertFailsWith<T> verifies an exception type is thrown and returns it for further assertions. Because the API is common across platforms, the same test source compiles in a Kotlin Multiplatform commonTest source set. You typically run tests via Gradle's `test` task.
go deeper
Can write an @Test method and use assertEquals/assertTrue correctly with proper argument order.
Knows assertFailsWith, assertNotNull smart-cast, and that kotlin.test delegates to JUnit on the JVM.
Explains the multiplatform delegation model and when to layer MockK/Kotest on top of the thin API.
Reasons about commonTest source-set strategy and choosing kotlin.test vs Kotest assertions as a team-wide standard.
## What kotlin.test Is `kotlin.test` is Kotlin's own lightweight testing API. It is **not** a test runner by itself — it is a set of **annotations** and **assertion functions** with a common API that works across Kotlin Multiplatform targets (JVM, JS, Native, Wasm). On each platform it delegates to a real engine; on the JVM you add `kotlin-test-junit5` so JUnit 5 actually discovers and runs the tests. ## Core Annotations - `@Test` — marks a test function. - `@BeforeTest` / `@AfterTest` — run before/after each test (setup/teardown). - `@Ignore` — skip a test. ## Core Assertions - `assertEquals(expected, actual, message?)` — **expected comes first**. - `assertTrue(condition)`, `assertFalse(condition)`. - `assertNull(value)`, `assertNotNull(value)` — the latter smart-casts to non-null and returns it. - `assertSame` / `assertNotSame` — reference identity. - `assertFailsWith<T>(block)` — asserts the block throws `T`, returns the exception. - `fail(message)` — force a failure. ```kotlin import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith class CalculatorTest { @Test fun `adds two numbers`() { assertEquals(5, add(2, 3)) // expected, actual } @Test fun `divide by zero throws`() { val ex = assertFailsWith<ArithmeticException> { divide(1, 0) } assertEquals("/ by zero", ex.message) } } ``` ## Why Use It - **Multiplatform**: the same `commonTest` code compiles everywhere. - **Idiomatic Kotlin**: backtick test names, `assertNotNull` smart-cast. - **Thin**: for richer matchers/specs you bring MockK or Kotest on top.
- Why does kotlin.test need kotlin-test-junit5 on the JVM?kotlin.test only defines the API; it has no runner. kotlin-test-junit5 maps its annotations onto JUnit 5 so the JUnit Platform actually discovers and executes the tests.
- What is the argument order for assertEquals and why does it matter?assertEquals(expected, actual). Getting it backwards still passes/fails correctly but produces misleading 'expected X but was Y' messages, confusing whoever reads the failure.
saying these in an interview costs you the question
- Thinking kotlin.test is a standalone runner like JUnit
- Putting actual before expected in assertEquals
- Confusing assertEquals (value) with assertSame (identity)
- Using try/catch + fail() instead of assertFailsWith
- Believing kotlin.test only works on the JVM