Pruebas en Go: unit, integration, e2e de la A a la Z

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

Introducción: ¿Por qué las pruebas en Go son una necesidad?

\n

Go (Golang) es un lenguaje de programación moderno, creado para construir sistemas confiables y escalables. Sin embargo, incluso el código más elegante no está exento de errores. Es por eso que las pruebas son una parte integral del desarrollo en Go. El paquete incorporado testing proporciona un potente conjunto de herramientas para escribir pruebas unitarias, pruebas de integración e incluso verificaciones end-to-end (e2e).

\n

En este artículo, analizaremos todos los niveles de pruebas en Go: desde pruebas unitarias simples hasta escenarios e2e complejos. Aprenderá cómo estructurar correctamente las pruebas, usar mocks, escribir pruebas table-driven y configurar pruebas de integración con dependencias reales. El material será útil tanto para principiantes como para desarrolladores experimentados que deseen sistematizar sus conocimientos.

\n\n

1. Pruebas unitarias en Go: lo fundamental

\n

Las pruebas unitarias verifican el funcionamiento de funciones o métodos individuales de forma aislada de las dependencias externas. En Go, se utiliza el paquete estándar testing para esto. Las reglas principales: los archivos de prueba deben llamarse *_test.go y las funciones de prueba deben comenzar con Test.

\n\n

1.1. Prueba unitaria simple

\n

Consideremos una función de suma de dos números:

\n
// math.go\npackage math\n\nfunc Add(a, b int) int {\n    return a + b\n}
\n

Prueba para ella:

\n
// math_test.go\npackage math\n\nimport "testing"\n\nfunc TestAdd(t *testing.T) {\n    result := Add(2, 3)\n    expected := 5\n    if result != expected {\n        t.Errorf("Add(2, 3) = %d; want %d", result, expected)\n    }\n}
\n

Ejecución de pruebas: go test ./... o go test -v para salida detallada.

\n\n

1.2. Pruebas Table-driven (pruebas tabulares)

\n

La comunidad de Go utiliza activamente el enfoque table-driven para verificar múltiples casos:

\n
func TestAddTableDriven(t *testing.T) {\n    tests := []struct {\n        name string\n        a, b int\n        want int\n    }{\n        {"positive", 2, 3, 5},\n        {"negative", -1, -2, -3},\n        {"zero", 0, 0, 0},\n    }\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            if got := Add(tt.a, tt.b); got != tt.want {\n                t.Errorf("Add() = %d, want %d", got, tt.want)\n            }\n        })\n    }\n}
\n

Este enfoque hace que las pruebas sean fáciles de leer y ampliar.

\n\n

1.3. Pruebas con errores

\n

Para funciones que devuelven errores, use t.Fatal o t.Errorf:

\n
func TestDivide(t *testing.T) {\n    _, err := Divide(10, 0)\n    if err == nil {\n        t.Fatal("expected error for division by zero")\n    }\n}
\n\n

2. Pruebas de integración: trabajo con dependencias

\n

Las pruebas de integración verifican la interacción de componentes: bases de datos, API, sistema de archivos. En Go, es común separarlas de las pruebas unitarias mediante build tags o una estructura de paquetes separada.

\n\n

2.1. Uso de build tags

\n

Cree un archivo con el tag //go:build integration al inicio:

\n
//go:build integration\n\npackage db\n\nimport (\n    "testing"\n    "database/sql"\n    _ "github.com/lib/pq"\n)\n\nfunc TestPostgresConnection(t *testing.T) {\n    dsn := "host=localhost port=5432 user=test password=test dbname=test sslmode=disable"\n    db, err := sql.Open("postgres", dsn)\n    if err != nil {\n        t.Fatalf("failed to open db: %v", err)\n    }\n    defer db.Close()\n    \n    if err := db.Ping(); err != nil {\n        t.Fatalf("failed to ping db: %v", err)\n    }\n}
\n

Ejecución solo de pruebas de integración: go test -tags=integration ./...

\n\n

2.2. Mocks y stubs

\n

Para aislar las pruebas, use interfaces y mocks. Ejemplo con la popular biblioteca gomock:

\n
// user.go\ntype UserRepository interface {\n    GetUser(id int) (*Us                

Blogs

Book Recommendations