Warum E2E-Tests Ihr bester Freund sind (und wie Sie sich in Kotlin mit ihnen anfreunden)
\n\nStellen Sie sich vor: Sie haben einen tollen Dienst in Kotlin geschrieben, alles kompiliert, Modultests sind grün, das Code-Review ist bestanden. Sie bringen es in die Produktion, und... die Benutzer beschweren sich, dass der Button „Kaufen“ nicht funktioniert, obwohl die Unit-Tests ihn geprüft haben. Kommt Ihnen bekannt vor? Willkommen in der Welt, in der E2E-Tests von Kotlin-Anwendungen kein Luxus, sondern eine Notwendigkeit sind.
\n\nEnd-to-End-Tests (E2E) überprüfen den gesamten Benutzerpfad: vom Klick auf einen Button bis zum Schreiben in die Datenbank und zurück. In diesem Artikel werden wir nicht nur über Theorie sprechen. Wir schreiben echte Tests für eine Kotlin-Anwendung, analysieren die Werkzeuge und zeigen, wie man bei der Einrichtung der Infrastruktur nicht verrückt wird. Schnallen Sie sich an, es gibt Code und Kaffee.
\n\nWas sind E2E-Tests und wie unterscheiden sie sich von anderen Testarten
\n\nLassen Sie uns gleich klarstellen. E2E-Tests (oder End-to-End-Tests) überprüfen das gesamte System so, wie der Benutzer es sieht. Im Gegensatz zu:
\n\n- \n
- Unit-Tests – überprüfen eine einzelne Methode/Klasse isoliert. \n
- Integrationstests – überprüfen die Interaktion von zwei oder drei Komponenten (z. B. Controller + Service). \n
- UI-Tests – werden oft mit E2E verwechselt, aber ein UI-Test kann das Backend ignorieren und nur die Darstellung der Oberfläche prüfen. \n
E2E-Tests von Kotlin-Anwendungen sind der vollständige Zyklus: Benutzeroberfläche (falls vorhanden), API, Geschäftslogik, Datenbank, externe Dienste. Alles muss wie ein Uhrwerk zusammenarbeiten.
\n\nWerkzeuge für E2E-Tests in Kotlin
\n\nDie Wahl des Werkzeugs hängt davon ab, was Sie testen: eine Android-App, einen Webdienst auf Ktor oder eine Desktop-Anwendung. Hier sind die Top-Werkzeuge für Kotlin-Entwickler:
\n\n- \n
- Selenide + Kotlin – für Weboberflächen. Ein Wrapper um Selenium, aber mit prägnanter Syntax, ideal für Kotlin. \n
- Ktor Client + TestContainers – für das Backend. Sie starten die Testinfrastruktur (DB, Cache) in Docker und senden HTTP-Anfragen. \n
- Espresso + Compose Test – für Android. Native Werkzeuge, die mit dem Android SDK geliefert werden. \n
- Cucumber + Kotlin – wenn BDD-Szenarien in einer für den Kunden verständlichen Sprache benötigt werden. \n
Wir konzentrieren uns auf die ersten beiden Szenarien, da sie am vielseitigsten sind.
\n\nEinen E2E-Test für eine Webanwendung in Kotlin schreiben (Selenide)
\n\nAngenommen, wir haben einen einfachen Online-Shop auf Spring Boot + Kotlin. Wir müssen das Szenario überprüfen: Der Benutzer besucht die Website, fügt ein Produkt zum Warenkorb hinzu und gibt die Bestellung auf.
\n\nZuerst fügen wir die Abhängigkeiten in build.gradle.kts hinzu:
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\nJetzt schreiben wir den eigentlichen Test. Beachten Sie: Wir verwenden Kotlin-Extension-Funktionen, um den Code lesbar zu machen:
\n\nimport 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 // Browser vor jedem Test öffnen\n open("https://test-shop.example.com")\n }\n\n @Test\n fun `user can add product to cart and checkout`() {\n // Schritt 1: Produkt finden und in den Warenkorb legen\n `$`("[data-testid='product-1']").shouldBe(visible).click()\n `$`("[data-testid='add-to-cart']").click()\n\n // Schritt 2: Prüfen, dass der Warenkorb nicht leer ist\n `$`("[data-testid='cart-badge']").shouldHave(text("1"))\n\n // Schritt 3: Zur Kasse gehen\n `$`("[data-testid='checkout-btn']").click()\n\n // Schritt 4: Formular ausfüllen\n `$`("[