Integrationstests in Go mit Docker: Schritt-für-Schritt-Anleitung

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Integrationstests von Go mit Docker: Vollständige Anleitung



Integrationstests sind ein entscheidender Schritt bei der Entwicklung zuverlässiger Go-Anwendungen. Im Gegensatz zu Unit-Tests prüfen Integrationstests die Interaktion von Komponenten: Datenbanken, Caches, externe APIs. Docker ermöglicht die Isolierung der Testumgebung und macht Tests reproduzierbar und unabhängig vom Host-Rechner. In diesem Artikel zeigen wir, wie man Integrationstests für Go-Anwendungen mit Docker einrichtet – von einfachen Containern bis hin zu fortgeschrittenen Szenarien mit Testcontainers und CI/CD.



1. Warum Docker für Integrationstests von Go?



Go-Anwendungen arbeiten oft mit PostgreSQL, Redis, MongoDB oder anderen Diensten. Die manuelle Einrichtung dieser Abhängigkeiten auf jedem Entwicklerrechner und CI-Server führt zu Fehlern. Docker löst dieses Problem:

  • Reproduzierbarkeit – gleiche Umgebung lokal und in CI.
  • Isolierung – Tests verschmutzen das Host-System nicht.
  • Geschwindigkeit – Container starten in Sekunden.
  • Parallelität – mehrere isolierte Tests können gleichzeitig ausgeführt werden.


Betrachten wir ein einfaches Beispiel: Wir testen eine Funktion, die Daten in PostgreSQL speichert.



2. Einrichtung der Testumgebung mit Docker Compose



Erstellen wir docker-compose.test.yml für die Testdatenbank:



version: '3.8'services:  postgres_test:    image: postgres:16-alpine    environment:      POSTGRES_USER: test      POSTGRES_PASSWORD: test      POSTGRES_DB: testdb    ports:      - "5433:5432"  # verwenden nicht standardmäßigen Port, um lokale DB nicht zu stören    tmpfs: /var/lib/postgresql/data  # Daten im Arbeitsspeicher für Geschwindigkeit


Im Go-Test starten wir den Container über os/exec oder verwenden die Bibliothek testcontainers-go. Wir zeigen beide Ansätze.



2.1. Manuelles Starten von Docker Compose aus dem Test



// main_test.gopackage main

import ( "context" "fmt" "os/exec" "testing" "time")

func setupTestDB(t *testing.T) string { t.Helper() // Container starten cmd := exec.Command("docker-compose", "-f", "docker-compose.test.yml", "up", "-d") if err := cmd.Run(); err != nil { t.Fatalf("failed to start docker-compose: %v", err) } // Auf PostgreSQL-Bereitschaft warten time.Sleep(3 * time.Second) return "postgres://test:test@localhost:5433/testdb?sslmode=disable"}

func TestSaveUser(t *testing.T) { dsn := setupTestDB(t) db, err := sql.Open("postgres", dsn) if err != nil { t.Fatal(err) } defer db.Close() // ... Testcode}


Nachteile: manuelles Sleep, Komplexität bei parallelen Tests. Besser Testcontainers verwenden.



2.2. Testcontainers für Go



Installieren Sie die Bibliothek:

go get github.com/testcontainers/testcontainers-go


Beispiel mit automatischer Container-Verwaltung:



// repository_test.gopackage repository

import ( "context" "testing" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" "github.com/jackc/pgx/v5/pgxpool")

func TestUserRepository_Save(t *testing.T) { ctx := context.Background()

// PostgreSQL-Container anfordern req := testcontainers.ContainerRequest{ Image: "postgres:16-alpine", ExposedPorts: []string{"5432/tcp"}, Env: map[string]string{ "POSTGRES_USER": "test", "POSTGRES_PASSWORD": "test", "POSTGRES_DB": "testdb", }, WaitingFor: wait.ForLog("database system is ready to accept connections"), }

postgres, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req

Blogs

Buchempfehlungen