Testing in Kotlin (JUnit & kotlin.test)
Automated tests are small functions, marked with @Test , that call your code and assert the result — kotlin.test and JUnit let you verify behaviour and catch regressions before they ship.
Learn Testing in Kotlin (JUnit & kotlin.test) in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise…
Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
You'll write tests with assertEquals , assertTrue , and assertFailsWith , use readable backtick names, and follow Arrange-Act-Assert.
What You'll Learn in This Lesson
1️⃣ Your First Test: @Test and assertions
A test is a function marked @Test inside a class. Inside it you call your code and check the result with an assertion. assertEquals(expected, actual) fails if they differ; assertTrue(cond) fails if the condition is false. Backtick names make each test a readable sentence.
2️⃣ Arrange-Act-Assert and Testing Errors
Structure each test in three phases: Arrange the inputs, Act by calling the code once, and Assert the outcome. To test that bad input fails correctly, wrap the call in assertFailsWith<Exception> { ... } , which passes only when that exact exception is thrown.
3️⃣ A Runnable Demo You Can Try Now
Real test classes need a build tool to run, but the idea — call a function, compare to an expected value, report pass/fail — fits in a plain main() . This little harness lets you watch assertions succeed in the Playground.
Your turn. Fill in the ___ blank, then run and compare.
Mini-Challenge: Test isEven
Write a Boolean check harness and verify isEven .
Common Errors (and the fix)
- ❌ Test never runs — you forgot @Test or imported the wrong one. ✅ Use import kotlin.test.Test and annotate the function.
- ❌ Confusing failure message — arguments to assertEquals are reversed. ✅ Put expected first, actual second.
- ❌ Error test passes by accident — you used a try/catch that swallows everything. ✅ Use assertFailsWith<T> for the exact type.
- ❌ One test, many assertions on unrelated things — failures are hard to read. ✅ Test one behaviour per test.
Pro Tips
- 💡 Name behaviours, not methods: reads better than testAdd1 .
- 💡 Test the edges: empty, zero, negative, and boundary values catch the most bugs.
- 💡 Mock only real dependencies: use MockK for databases or networks, never for pure functions.
📋 Quick Reference — kotlin.test
Assertion
Passes when
assertEquals(e, a)
e == a
assertTrue(c)
c is true
assertFalse(c)
c is false
assertNull(x)
x is null
assertFailsWith<E> { }
block throws E
@Test
marks a test function
Frequently Asked Questions
🎉 Lesson Complete!
- ✅ Mark tests with @Test from kotlin.test
- ✅ assertEquals takes expected first, then actual
- ✅ assertFailsWith<T> verifies the right exception
- ✅ Backtick names turn tests into readable specs
- ✅ Structure tests as Arrange-Act-Assert; mock only real dependencies
- ✅ Next lesson: Java Interop
Practice quiz
Which annotation marks a function as a test the runner will execute?
- @Run
- @Check
- @Verify
- @Test
Answer: @Test. @Test from kotlin.test (or JUnit) marks a function as a test.
In assertEquals(expected, actual), which argument comes first?
- The expected value
- The actual value
- The error message
- The test name
Answer: The expected value. Convention is assertEquals(expected, actual); expected comes first.
What does assertTrue(condition) check?
- That two values are equal
- That the condition is true
- That a value is null
- That an exception is thrown
Answer: That the condition is true. assertTrue passes only when the given Boolean condition is true.
Which assertion verifies that a block throws a specific exception?
- assertEquals
- assertTrue
- assertFailsWith<T> { ... }
- assertNull
Answer: assertFailsWith<T> { ... }. assertFailsWith<T> { ... } passes only if the block throws type T.
How does kotlin.test relate to JUnit?
- It replaces JUnit entirely with no runner
- It is unrelated to test runners
- It only works on Android
- It provides assertions and on the JVM can delegate to a runner like JUnit 5
Answer: It provides assertions and on the JVM can delegate to a runner like JUnit 5. kotlin.test is a multiplatform assertion API that can delegate to JUnit on the JVM.
Why use backtick names like () for tests?
- They let the test name read as a sentence in reports
- They make tests run faster
- They are required by the compiler
- They hide the test from the runner
Answer: They let the test name read as a sentence in reports. Backtick names allow spaces, turning test names into readable specifications.
What are the three phases of the Arrange-Act-Assert pattern?
- Allocate, Apply, Audit
- Arrange, Act, Assert
- Assign, Await, Announce
- Ask, Answer, Archive
Answer: Arrange, Act, Assert. Arrange sets up inputs, Act runs the code once, Assert checks the outcome.
What does assertFalse(condition) pass for?
- When the condition is true
- When the condition is false
- When the value is null
- Always
Answer: When the condition is false. assertFalse passes only when the Boolean condition is false.
When do you typically need a mocking library like MockK?
- For every function including pure ones
- Never in Kotlin
- To replace real dependencies like databases or network clients
- To run main()
Answer: To replace real dependencies like databases or network clients. Mock real, slow, or non-deterministic collaborators; pure functions need no mocks.
Good practice for a single test is to verify how many behaviours?
- One behaviour per test
- As many as possible
- Exactly five
- None
Answer: One behaviour per test. Each test should exercise one behaviour so a failure has a clear cause.
Continue this course
- Previous: Advanced Collections
- Next: Java Interop