Why use the kotlin.test assertion family instead of a framework's native asserts, and what do assertEquals vs assertNotEquals cover?
answer
- kotlin.test = multiplatform (JVM/JS/Native/Wasm)
- import kotlin.test.*
- JVM delegates to JUnit by default
- assertNotEquals = != (passes when different)
- most specific assertion = best message
basics
~20 skotlin.test gives one set of assertions that work the same on every Kotlin platform and produce clear messages. assertEquals checks values match; assertNotEquals checks they differ. On the JVM, failures still flow through your test framework.
solid answer
~40 s`kotlin.test` is the multiplatform assertion API: the same `import kotlin.test.*` calls (`assertEquals`, `assertNotEquals`, `assertTrue/assertFalse`, `assertNull/assertNotNull`, `assertSame/assertNotSame`, `fail`) compile on JVM, JS, Native, and Wasm. On the JVM, kotlin.test plugs into the configured framework (JUnit by default) so failures appear in normal reports, but your test code stays framework-agnostic and portable. `assertEquals(expected, actual)` passes on structural equality (`==`); `assertNotEquals(illegal, actual)` passes when they are *not* equal (`!=`) — useful for asserting a value changed or differs from a forbidden sentinel. All share an optional trailing `message`. The guiding rule: pick the most specific assertion for the most useful failure message, and prefer kotlin.test for portability over framework-native asserts.
code
kotlin · 11 linesimport kotlin.test.*
import kotlin.test.Test
class OrderTest {
@Test fun summary() {
val o = buildOrder()
assertNotNull(o.id)
assertEquals(2, o.items.size)
assertNotEquals(Status.DRAFT, o.status)
}
}go deeper
Knows assertEquals/assertNotEquals check equality/inequality of values.
Knows kotlin.test is a single import covering the core asserts with optional messages.
Explains multiplatform portability and that JVM delegates to JUnit, choosing specific asserts for good messages.
Weighs kotlin.test portability vs richer framework/assertion libraries and sets a team convention for assertion choice across KMP targets.
## The `kotlin.test` core assertion family `kotlin.test` is Kotlin's **multiplatform** assertion library: the same `import kotlin.test.*` functions compile on JVM, JS, Native, and Wasm. On the JVM the failures are reported through the configured framework (JUnit by default), but the API you call is framework-independent. ### Core functions (all take an optional trailing `message: String?`) | Function | Passes when | Equality kind | |---|---|---| | `assertEquals(expected, actual)` | `expected == actual` | structural (`==`) | | `assertNotEquals(illegal, actual)` | `illegal != actual` | structural (`!=`) | | `assertTrue(cond)` / `assertFalse(cond)` | cond is `true` / `false` | boolean | | `assertNull(actual)` | actual `=== null` | null check | | `assertNotNull(actual)` | actual is non-null; **returns** it | null check (narrows type) | | `assertSame(expected, actual)` | `expected === actual` | referential (`===`) | | `assertNotSame(illegal, actual)` | `illegal !== actual` | referential (`!==`) | | `fail(message)` | never (always fails) | — | ### Why these over raw framework asserts - **Multiplatform**: one API across all targets. - **Better messages**: `assertEquals` prints `expected:<..> but was:<..>`; `assertNotNull` narrows the type. - **Idiomatic Kotlin**: named `message` arg, lambda message overloads, `Nothing` return on `fail`. ```kotlin import kotlin.test.* import kotlin.test.Test class OrderTest { @Test fun summary() { val order = buildOrder() assertNotNull(order.id) assertEquals(2, order.items.size, "expected two line items") assertTrue(order.total > 0) assertNotEquals(Status.DRAFT, order.status) } } ``` Choosing the *most specific* assertion gives the *most useful* failure message — that is the guiding principle.
- On the JVM, does kotlin.test replace JUnit?No — it delegates to the configured framework (JUnit by default), so failures show in normal reports; you just call a portable API.
- When is assertNotEquals the right tool?When the contract is that a value must differ — e.g. an id was regenerated, or status moved away from a sentinel like DRAFT.
saying these in an interview costs you the question
- Thinks kotlin.test is JVM-only
- Believes kotlin.test replaces/conflicts with JUnit on JVM
- Says assertNotEquals uses ===
- Cannot name a use for assertNotEquals
- Defaults to assertTrue for everything instead of specific asserts