Las pruebas son una parte fundamental del desarrollo de software, ya que aseguran que el código funcione como se espera y ayuda a prevenir errores en el futuro. En Go, las pruebas se escriben utilizando el paquete testing
, que proporciona herramientas para crear y ejecutar pruebas unitarias, pruebas de integración y benchmarks.
Contenido
Introducción a las Pruebas en Go
Go tiene un soporte robusto para pruebas integrado en su herramienta de construcción. Las pruebas se escriben en archivos que terminan en _test.go
y se colocan en el mismo paquete que el código que están probando.
Estructura de una Prueba
Una prueba en Go es una función que sigue la convención TestXxx
y toma un parámetro de tipo *testing.T
. Aquí hay un ejemplo básico:
package main import ( "testing" ) func TestSum(t *testing.T) { total := Sum(5, 5) if total != 10 { t.Errorf("Sum was incorrect, got: %d, want: %d.", total, 10) } }
En este ejemplo:
TestSum
es el nombre de la función de prueba.t *testing.T
es el parámetro que se utiliza para reportar errores y fallos en la prueba.t.Errorf
se usa para reportar un error si la condición no se cumple.
Escribiendo Pruebas Unitarias
Las pruebas unitarias se centran en probar funciones individuales para asegurarse de que funcionan correctamente. Aquí hay un ejemplo más detallado:
Ejemplo de Función a Probar
Supongamos que tenemos una función Sum
que suma dos números:
Escribiendo la Prueba Unitaria
Ahora escribimos una prueba unitaria para esta función:
package main import ( "testing" ) func TestSum(t *testing.T) { tests := []struct { name string a, b int want int }{ {"positive numbers", 1, 2, 3}, {"zero", 0, 0, 0}, {"negative numbers", -1, -1, -2}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := Sum(tt.a, tt.b) if got != tt.want { t.Errorf("Sum(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want) } }) } }
En este ejemplo:
- Usamos una tabla de pruebas para definir múltiples casos de prueba.
t.Run
se usa para ejecutar cada caso de prueba individualmente.
Pruebas de Integración
Las pruebas de integración verifican que diferentes partes del sistema funcionen juntas correctamente. A menudo implican interacciones con bases de datos, servicios externos, etc.
Ejemplo de Prueba de Integración
Supongamos que tenemos una función que guarda datos en una base de datos:
package main import ( "database/sql" _ "github.com/lib/pq" ) func SaveToDB(db *sql.DB, data string) error { _, err := db.Exec("INSERT INTO table_name (column_name) VALUES ($1)", data) return err }
Escribiendo la Prueba de Integración
package main import ( "database/sql" "testing" _ "github.com/lib/pq" ) func TestSaveToDB(t *testing.T) { db, err := sql.Open("postgres", "user=username dbname=mydb sslmode=disable") if err != nil { t.Fatal(err) } defer db.Close() err = SaveToDB(db, "testdata") if err != nil { t.Errorf("SaveToDB failed: %v", err) } }
En este ejemplo:
sql.Open
se usa para abrir una conexión a la base de datos.t.Fatal
se usa para detener la prueba si no se puede abrir la conexión.t.Errorf
se usa para reportar un error si la funciónSaveToDB
falla.
Ejecutando Pruebas
Para ejecutar las pruebas, usa el comando go test
en el directorio que contiene los archivos de prueba:
Para obtener una salida más detallada, usa la bandera -v
:
Cobertura de Código
La cobertura de código mide qué porcentaje del código fuente es ejecutado durante las pruebas. Para generar un informe de cobertura, usa la bandera -cover
:
Para generar un informe de cobertura detallado en un archivo, usa:
Errores Comunes y Consejos
Errores Comunes
- No manejar errores correctamente: Asegúrate de verificar y manejar todos los errores en tus pruebas.
- Pruebas dependientes del entorno: Las pruebas deben ser independientes del entorno en el que se ejecutan.
- No limpiar después de las pruebas: Asegúrate de limpiar cualquier estado que tus pruebas puedan haber modificado.
Consejos
- Usa tablas de pruebas: Facilitan la adición de nuevos casos de prueba y mejoran la legibilidad.
- Pruebas paralelas: Usa
t.Parallel()
para ejecutar pruebas en paralelo y reducir el tiempo de ejecución. - Mocks y stubs: Usa mocks y stubs para simular dependencias externas y hacer que las pruebas sean más rápidas y confiables.
Conclusión
En esta sección, hemos cubierto los conceptos básicos de las pruebas en Go, incluyendo cómo escribir pruebas unitarias y de integración, cómo ejecutar pruebas y cómo medir la cobertura de código. Las pruebas son esenciales para asegurar la calidad del software y deben ser una parte integral de tu flujo de trabajo de desarrollo. En el siguiente módulo, exploraremos el benchmarking para medir y optimizar el rendimiento de tu código.
Curso de Programación en Go
Módulo 1: Introducción a Go
- Introducción a Go
- Configuración del Entorno de Go
- Tu Primer Programa en Go
- Sintaxis y Estructura Básica
Módulo 2: Conceptos Básicos
Módulo 3: Estructuras de Datos Avanzadas
Módulo 4: Manejo de Errores
Módulo 5: Concurrencia
Módulo 6: Temas Avanzados
Módulo 7: Desarrollo Web con Go
Módulo 8: Trabajando con Bases de Datos
Módulo 9: Despliegue y Mantenimiento
- Construcción y Despliegue de Aplicaciones Go
- Registro de Logs
- Monitoreo y Optimización de Rendimiento
- Mejores Prácticas de Seguridad