Pruebas de integración de Go con Docker: guía paso a paso

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Pruebas de Integración en Go con Docker: Guía Completa



Las pruebas de integración son una etapa clave en el desarrollo de aplicaciones Go confiables. A diferencia de las pruebas unitarias, las pruebas de integración verifican la interacción entre componentes: bases de datos, cachés, APIs externas. Docker permite aislar el entorno de pruebas, haciendo que las pruebas sean reproducibles e independientes de la máquina host. En este artículo, analizaremos cómo configurar las pruebas de integración de aplicaciones Go con Docker, desde contenedores simples hasta escenarios avanzados con Testcontainers y CI/CD.



1. ¿Por qué Docker para pruebas de integración en Go?



Las aplicaciones Go a menudo trabajan con PostgreSQL, Redis, MongoDB u otros servicios. La configuración manual de estas dependencias en cada máquina de desarrollo y servidor CI es un camino hacia los errores. Docker resuelve este problema:

  • Reproducibilidad — mismo entorno localmente y en CI.
  • Aislamiento — las pruebas no contaminan el sistema host.
  • Velocidad — los contenedores se inician en segundos.
  • Paralelismo — se pueden ejecutar múltiples pruebas aisladas simultáneamente.


Consideremos un ejemplo básico: probamos una función que guarda datos en PostgreSQL.



2. Configuración del entorno de pruebas con Docker Compose



Creemos un docker-compose.test.yml para la base de datos de prueba:



version: '3.8'services:  postgres_test:    image: postgres:16-alpine    environment:      POSTGRES_USER: test      POSTGRES_PASSWORD: test      POSTGRES_DB: testdb    ports:      - "5433:5432"  # usamos un puerto no estándar para no interferir con la BD local    tmpfs: /var/lib/postgresql/data  # datos en memoria para velocidad


En la prueba de Go, levantamos el contenedor mediante os/exec o usamos la biblioteca testcontainers-go. Mostraremos ambos enfoques.



2.1. Inicio manual de Docker Compose desde la prueba



// main_test.gopackage main

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

func setupTestDB(t *testing.T) string { t.Helper() // Iniciamos el contenedor cmd := exec.Command("docker-compose", "-f", "docker-compose.test.yml", "up", "-d") if err := cmd.Run(); err != nil { t.Fatalf("error al iniciar docker-compose: %v", err) } // Esperamos a que PostgreSQL esté listo 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() // ... código de prueba}


Desventajas: sleep manual, complejidad con pruebas paralelas. Es mejor usar Testcontainers.



2.2. Testcontainers para Go



Instale la biblioteca:

go get github.com/testcontainers/testcontainers-go


Ejemplo con gestión automática del contenedor:



// 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()

// Solicitamos un contenedor PostgreSQL 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

Book Recommendations