BDD in Kotlin: How to Write Tests Even Managers Can Understand

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

BDD in Kotlin: Writing Tests That Both Managers and Developers Can Read

\n\n

Have you ever shown a unit test to your product manager? Probably not. Because it's like showing jet engine blueprints to a pilot — useful, but incomprehensible. Behaviour-Driven Development (BDD) in Kotlin solves exactly this problem: it turns dry asserts into living scenarios that describe system behavior in human language.

\n\n

In this article, we'll explore how to implement BDD in Kotlin using modern frameworks — Kotest and Spek. You'll see how to write tests in the Given-When-Then style, which serve as both documentation and automated verification. And yes, even your team lead without special training will be able to read them.

\n\n

What is BDD and how is it different from TDD?

\n\n

Many people confuse TDD (Test-Driven Development) and BDD (Behaviour-Driven Development). The difference is simple:

\n\n
    \n
  • TDD is about "how do I verify this method?"
  • \n
  • BDD is about "how does the user get value from this feature?"
  • \n
\n\n

Behaviour-driven development focuses on system behavior, not implementation details. You describe a scenario: given certain conditions (Given), when an action occurs (When), the system produces the expected result (Then).

\n\n

For example, instead of writing:
assertEquals(42, calculator.add(20, 22)),
you would write:

\n\n
Given("I have a calculator") {\n    val calc = Calculator()\n    When("I add 20 and 22") {\n        val result = calc.add(20, 22)\n        Then("the result should be 42") {\n            result shouldBe 42\n        }\n    }\n}\n
\n\n

You'll agree, the second option reads like a story, not a technical instruction.

\n\n

Why Kotlin is ideal for BDD

\n\n

Kotlin is a language that naturally lends itself to writing readable code. Extension functions, infix notation, lambdas with receivers — all of this makes BDD tests in Kotlin as natural as possible. You can write shouldBe, shouldThrow, and other matchers that look like English.

\n\n

Moreover, Kotlin supports multiple paradigms, allowing you to use different frameworks for BDD. Let's look at the two most popular ones.

\n\n

Kotest Framework: BDD out of the box

\n\n

Kotest (formerly KotlinTest) is a powerful multiplatform testing framework. It supports several styles, including BehaviorSpec, which is perfect for BDD.

\n\n

Here's what a full BDD scenario in Kotlin looks like using Kotest:

\n\n
import io.kotest.core.spec.style.BehaviorSpec\nimport io.kotest.matchers.shouldBe\n\nclass CartSpec : BehaviorSpec({\n    given("an empty cart") {\n        val cart = ShoppingCart()\n        `when`("adding an item with a price of 100") {\n            cart.addItem(Item("Book", 100.0))\n            then("the cart should have 1 item") {\n                cart.itemCount shouldBe 1\n            }\n            then("the total should be 100") {\n                cart.total shouldBe 100.0\n            }\n        }\n        `when`("adding an item and applying a 10% discount") {\n            cart.addItem(Item("Book", 100.0))\n            cart.applyDiscount(10.0)\n            then("the final total should be 90") {\n                cart.total shouldBe 90.0\n            }\n        }\n    }\n})\n
\n\n

Notice the backticks around when. This is a Kotlin feature: when is a reserved word, but in backticks it works as an identifier. Some developers prefer to use When with a capital letter.

\n\n

Spek: structured BDD for Kotlin

\n\n

Spek

Blogs

Book Recommendations