E2E Testing Kotlin Applications: From Zero to Production

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

Why E2E Testing Is Your Best Friend (and How to Befriend It in Kotlin)

\n\n

Imagine: you wrote a cool service in Kotlin, everything compiled, unit tests are green, code review passed. You deploy to production, and... users complain that the "Buy" button doesn't work, even though unit tests checked it. Sound familiar? Welcome to the world where E2E testing Kotlin applications is not a luxury, but a necessity.

\n\n

End-to-end testing is checking the entire user path: from a button click to a database write and back. In this article, we won't just talk about theory. We'll write real tests for a Kotlin application, break down the tools, and show you how not to go crazy setting up infrastructure. Buckle up, there will be code and coffee.

\n\n

What Is E2E Testing and How It Differs from Other Types

\n\n

Let's set the record straight. E2E (or end-to-end) testing checks the entire system as the user sees it. Unlike:

\n\n
    \n
  • Unit tests — check one method/class in isolation.
  • \n
  • Integration tests — check the interaction of two or three components (e.g., controller + service).
  • \n
  • UI tests — often confused with E2E, but a UI test may not check the backend, only the interface rendering.
  • \n
\n\n

E2E testing Kotlin applications is a full cycle: user interface (if any), API, business logic, database, external services. Everything must work together like clockwork.

\n\n

Tools for E2E Testing in Kotlin

\n\n

The choice of tool depends on what you are testing: an Android application, a Ktor web service, or a desktop application. Here are the top picks for a Kotlin developer:

\n\n
    \n
  • Selenide + Kotlin — for web interfaces. A wrapper over Selenium, but with concise syntax, perfect for Kotlin.
  • \n
  • Ktor Client + TestContainers — for the backend. Spin up test infrastructure (DB, cache) in Docker and fire HTTP requests.
  • \n
  • Espresso + Compose Test — for Android. Native tools that come with the Android SDK.
  • \n
  • Cucumber + Kotlin — if you need BDD scenarios in a language understandable to the client.
  • \n
\n\n

We'll focus on the first two scenarios, as they are the most universal.

\n\n

Writing an E2E Test for a Kotlin Web Application (Selenide)

\n\n

Suppose we have a simple online store on Spring Boot + Kotlin. We need to check the scenario: a user visits the site, adds a product to the cart, and places an order.

\n\n

First, add the dependencies to build.gradle.kts:

\n\n
dependencies {\n    testImplementation("com.codeborne:selenide:6.19.1")\n    testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")\n    testImplementation("io.github.bonigarcia:webdrivermanager:5.6.2")\n}
\n\n

Now let's write the test itself. Note: we use Kotlin extension functions to make the code readable:

\n\n
import com.codeborne.selenide.Condition.visible\nimport com.codeborne.selenide.Selenide.`$`\nimport com.codeborne.selenide.Selenide.open\nimport org.junit.jupiter.api.BeforeEach\nimport org.junit.jupiter.api.Test\n\nclass ShopE2ETest {\n\n    @BeforeEach\n    fun setUp() {\n        // Open the browser before each test\n        open("https://test-shop.example.com")\n    }\n\n    @Test\n    fun `user can add product to cart and checkout`() {\n        // Step 1: Find the product and add to cart\n        `$`("[data-testid='product-1']").shouldBe(visible).click()\n        `$`("[data-testid='add-to-cart']").click()\n\n        // Step 2: Verify the cart is not empty\n        `$`("[data-testid='cart-badge']").shouldHave(text("1"))\n\n        // Step 3: Proceed to checkout\n        `$`("[data-testid='checkout-btn']").click()\n\n        // Step 4: Fill out the form\n        `$`("[                

Blogs

Book Recommendations