Kotlin Academy · Lesson

Writing Tests with JUnit5

Structure tests.

Lesson 1 of 413 steps

Writing Tests with JUnit5 is a free Kotlin Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, and your progress syncs across the web and the CoddyKit app. The Kotlin Academy course includes 4 lessons in total.

What is JUnit5?

JUnit5 (JUnit Jupiter) is the standard testing framework for the JVM and Kotlin. It provides annotations to mark and structure test code.

  • Tests live in src/test/kotlin
  • Each test is a function
  • The runner executes them and reports results

Adding the Dependency

Add JUnit Jupiter to your test configuration and enable the JUnit platform.

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
}

tasks.test {
    useJUnitPlatform()
}

Your First Test

Annotate a function with @Test. A test asserts something about your code.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.assertEquals

class MathTest {
    @Test
    fun addsTwoNumbers() {
        assertEquals(4, 2 + 2)
    }
}

Descriptive Test Names

Use @DisplayName for readable test reports without long function names.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.DisplayName

class OrderTest {
    @Test
    @DisplayName("total includes tax")
    fun totalWithTax() {
        // ...
    }
}

Setup with @BeforeEach

@BeforeEach runs before every test, ideal for fresh fixtures. @AfterEach runs after each test for cleanup.

import org.junit.jupiter.api.BeforeEach

class CartTest {
    private lateinit var cart: MutableList<String>
    @BeforeEach
    fun setUp() {
        cart = mutableListOf()
    }
}

Class-Level Setup

@BeforeAll and @AfterAll run once for the whole class. In Kotlin they need a companion object with @JvmStatic (or a per-class lifecycle).

import org.junit.jupiter.api.BeforeAll

class DbTest {
    companion object {
        @BeforeAll
        @JvmStatic
        fun connect() {
            // open shared connection
        }
    }
}

Arrange-Act-Assert

Structure each test in three clear phases:

  • Arrange — set up inputs and state
  • Act — invoke the code under test
  • Assert — verify the outcome

This keeps tests readable and focused.

Nested Tests

@Nested groups related tests, producing a tree-shaped report that documents behavior.

import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test

class StackTest {
    @Nested
    inner class WhenEmpty {
        @Test fun isEmpty() { /* ... */ }
    }
}

Parameterized Tests

Run the same test with multiple inputs using @ParameterizedTest and a value source.

import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import org.junit.jupiter.api.Assertions.assertTrue

class NumberTest {
    @ParameterizedTest
    @ValueSource(ints = [2, 4, 6])
    fun isEven(n: Int) {
        assertTrue(n % 2 == 0)
    }
}

Disabling and Tagging

Skip a test temporarily with @Disabled, and group tests with @Tag so you can include or exclude them in CI runs.

import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test

class FlakyTest {
    @Test
    @Disabled("fix later")
    @Tag("slow")
    fun pending() { }
}

A Self-Contained Example

Here is a simple pure-Kotlin function and the idea behind testing it (the test itself runs under JUnit).

fun add(a: Int, b: Int): Int = a + b

fun main() {
    val result = add(2, 3)
    println(if (result == 5) "PASS" else "FAIL")
}

Quick Check

You need a fresh, empty list before every single test method. Which annotation fits?

Recap

You can structure JUnit5 tests:

  • @Test marks tests, @DisplayName names them
  • @BeforeEach / @BeforeAll handle setup
  • Arrange-Act-Assert keeps tests clear
  • @Nested and @ParameterizedTest organize and scale tests

Next: assertions.

Free to start

Learn Kotlin with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
51
Lessons
203

Frequently Asked Questions

Is the “Writing Tests with JUnit5” lesson free?

Yes — any 3 lessons of the Kotlin Academy learning path, including “Writing Tests with JUnit5”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Kotlin Academy course includes 4 lessons in total.

What will I learn in “Writing Tests with JUnit5”?

Structure tests. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Kotlin Academy?

No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.

How long does the “Writing Tests with JUnit5” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Kotlin Academy lesson?

Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Writing Tests with JUnit5
  2. Assertions
  3. Mocking with MockK
  4. Coroutine Testing
← Back to Kotlin Academy