Testcontainers

Integrationstesten mit Docker leicht gemacht

Stefan Hildebrandt / @hildebrandttk

Wer bin ich

Portrait von Stefan Hildebrandt
Und Ihr?

Testumgebungen ohne Docker

Testumgebungen ohne Docker

System under Test (SUT)

  • Zentrale Instanz
    • Updates?
    • Branch?
    • Testdatensetup
    • Störungen durch parallele Zugriffe
  • Setup in der CI-Pipeline
    • Proprietär
    • Laufzeit
    • Fehleranfälligkeit
Testumgebungen ohne Docker

Infrastruktur (z.B. RDBMS, App-Server)

  • Geteilte Instanz
    • Schema je Umgebung
  • Lokale Installationen
    • Pflege?
Testumgebungen ohne Docker

Entwicklerrechner?

  • ...

Docker, ohne Testcontainers

Docker, ohne Testcontainers

docker

  • Forward-Only Ansatz
    • Einfacher
    • Weniger Fehleranfällig
    • Schneller
  • Manueller Start
  • Verbindungen der Container nicht standartisiert abgelegt
Docker, ohne Testcontainers

docker-compose

  • Manueller Start
  • Automatisch ausführbare Beschreibung ganzer Umgebungen
  • Leicht durch CI im SCM aktualisierbar nach erfolgreichem Test einzelner Komponenten
Docker, ohne Testcontainers

kubernetes

  • Meist genutztes Betriebsmodel
  • Verlust der Unabhängigkeit von Infrastruktur in Testszenarien
  • Komplex, daher nur wenn ohnehin schon im Einsatz
Docker, ohne Testcontainers

Maven (fabric8 Plugin)

  • Maven startet Container
  • Sicherstellung laufender Container vor Integration-Test-Phase
  • Einbindung in die IDE zur Testausführung
  • Übergabe von Ports als System-Properties bei Failsave-/Surefire-Plugin
Docker, ohne Testcontainers

Gradle

  • Konzept Analog zu maven
  • Noch keine Konsolidierung bei den Plugins

Testcontainers

Testcontainers (java)

Überblick

  • Library zum Starten von Dockercontainern im Testkontext
  • Nutzt das Docker-Java-Binding
  • Erleichtert die Einbindung in gängige Testframeworks
  • Bietet Wrapper um typische Container
  • Arquillian Cube
    • Java EE only
    • Konzeptioneller Vorgänger
Testcontainers

Weitere unterstützte Sprachen

Code diving

Beispiele auf Github

Testcontainers

Grundlagen

  • GenericContainer
    • Start
    • Environment
    • Ports / Port-Mapping
    • Environment-Variablen
    • Output
    • Stop

Infrastruktur-Container

Infrastruktur-Container

JDBC Container

  • DB / Username / Password
    • Defaults
  • Ready-Check
  • getJdbcUrl
  • Setup-Scripts
Infrastruktur-Container

RDBMS

  • db2
  • dynalite
  • influxdb
  • mariadb
  • mssqlserver
  • mysql
  • oracle(-xe)
  • postgresql
Infrastruktur-Container

Andere Datenbanken

  • cassandra
  • clickhouse
  • couchbase
  • elasticsearch
  • neo4j
Infrastruktur-Container

Infrastruktur

  • kafka
  • localstack
  • mockserver
  • nginx
  • rabbitmq
  • toxiproxy
Testcontainers

Ryuk

  • Sidecar-Container
    • Läuft weiter falls Test nicht graceful beendet wird
  • Sicherstellung
    • Stoppen von Container
    • Löschen von Container
    • Löschen von temporären Images

Einbindung in Tests

Einbindung in Tests

Testframeworks

  • JUnit 4 ist die Basis
  • JUnit 5
  • Spock
Einbindung in Tests

Code diving

Beispiele auf Github

Einbindung in Tests

Laufzeit Container

  • Container per Test
  • Container per TestClass
  • Container per TestSuite

Images erstellen

Images erstellen

Motivation

  • Aktuelles Projekt (Project under Test)
    • Einfacheres Setup
      • z.B.: Linux Umgebung auf Windows Rechnern
    • Schnellerer Roundtrip
  • Vorbereitete Datenbank
    • Test-Laufzeit
    • Test-Stabilität
  • ...
Images erstellen

Code diving

Beispiele auf Github

Spring Boot

Spring Boot

Code diving

Beispiele auf Github

Spring Boot

Optionen

  • Zugriff in der SpringConfig auf den static Container im Test
  • Container wie gewohnt starten
    • Beachten, dass DB-Container länger als Spring-Container laufen sollte
  • embedded-Mode
  • ContainerDatabaseDriver
    • Starten des Containers über einen jdbc-String
    • Initscript-Support

Selenium

Selenium

Bereitstellung von Browsern

  • Auf Headless-CI-Servern nicht einfach
  • Ungeplante Updates erzeugen Testfehler
  • Lokal Störung des Tests bei Benutzung des Rechners möglich
Selenium

Code diving

Beispiele auf Github

Selenium

Video Support

Selenium

Testen von Services auf Localhost

exposeHostPorts

Cucumber

Cucumber
Cucumber

Code diving

Beispiele auf Github

Cucumber

Parallelität

  • Unterschiedliche DBMS
  • Isolierte Umgebungen
  • Browserbereitstellung für mehrere Tests
    • Auch gemeinsames SUT möglich
Cucumber

Generische Container-Stepdefinitions

  • Meist nicht sinnvoll
    • zu kleinteilig
    • fachlich nicht lesbar
Cucumber

Abdeckungstest mit Infrastruktur

  • Datenbanken
  • Application Server
  • JDKs
  • Betriebssysteme
Cucumber

Netzwerk

  • Mehrere Container in einem Netzwerk
    • Alias-Suppport
  • Mehrere Netzwerke
Netzwerk

Docker-Compose

  • Nutzung bestehender Setups
    • Insbesondere komplexe Netzwerk-Topologien
  • Zentrales Update von Images

Und sonst ...

Und sonst ...

Zugriff auf laufende Container

  • execInContainer(String command)
  • copyFileFromContainer(String command)
  • copyFileToContainer(String command)
  • ...
Und sonst ...

fehlt noch

  • Commit-On-Failure für Docker-Container
  • Bauen von Maven/Gradle-Projekte

Zusammenfassung

Zusammenfassung

Schnell auf Integrationstestebene

  • Overhead gering
  • Vorbereitete Testdaten
    • Setup im Test kann entfallen
    • Migration von Bestandsdaten wird getestet
Zusammenfassung

Unit-Tests

  • Bei der Entwicklung schnell zu langsam (> 2 Sekunde)
  • Im CI-Server als Suite OK
Zusammenfassung

Stabil

  • Verlässliche Laufzeitumgebung
    • Datenbanken
    • Browser
  • Isoliert
    • Keine Beeinflussung durch andere automatisierte oder manuelle Tests
Zusammenfassung

Einfach

  • Einbindung in Tests einfach

Checkout-And-Run

  • Nur Build-Tooling und Docker muss installiert sein
  • Läuft auf den meisten CI-Servern und Entwicklerrechnern
  • Wenig Aufwand für Installation und Pflege

Slides

https://h9t.eu/s/tc

Weitere Links

Stefan Hildebrandt - consulting.hildebrandt.tk

  • Beratung, Coaching und Projektunterstützung
  • Java EE
  • Buildsysteme gradle und maven/ant-Migration
  • Testautomatisierung
  • Coach in agilen Projekten
  • DevOps
Datenschutz Impressum