Lecciones del módulo (1/5)
El paquete testing
En Go, las pruebas son parte de stdlib: no hay biblioteca externa, no hay marco para configurar. Todo lo que necesita es un archivo *_test.go junto al código, algunas funciones TestXxx y el comando go test.
Convenciones básicas
- Los archivos de prueba se denominan
<something>_test.goy se encuentran en el mismo paquete que el código que prueban (o en un paquete<name>_testpara "pruebas de caja negra"). - Las funciones de prueba tienen una firma exacta:
func TestXxx(t *testing.T)dondeXxxcomienza con una letra mayúscula. - Importas
testingdesde stdlib. - Sin
assertEquals: usasif got != want { t.Errorf(...) }con verbosfmt.
// math.go
package math
func Sum(a, b int) int { return a + b }
// math_test.go
package math
import "testing"
func TestSum(t *testing.T) {
got := Sum(2, 3)
if got != 5 {
t.Errorf("Sum(2,3) = %d; voglio %d", got, 5)
}
}Ejecútelo con:
go test ./... # all packages in the module
go test -v ./pkg # verbose: prints test names
go test -run TestSum # only tests matching the regexCÓDIGOPH0 frente a CÓDIGOPH1
Estos son los dos verbos básicos para señalar un fracaso:
| Método | Efecto |
|---|---|
| CÓDIGOPH0 | Registra pero no falla (visible solo con -v o en caso de falla). |
| CÓDIGOPH2 | Registra, marca FAIL, continúa la función de prueba. |
| CÓDIGOPH3 | Como Error con formato. |
| CÓDIGOPH5 | Registra, marca FAIL, detiene la prueba (llama a runtime.Goexit). |
| CÓDIGOPH7 | Como Fatal con formato. |
Regla general: use Fatal cuando continuar no tenga sentido (por ejemplo, configuración fallida, desreferencia inminente de puntero nulo); de lo contrario, Error, que le permite ver todos los errores en una sola ejecución.
func TestOpen(t *testing.T) {
f, err := os.Open("fixtures/sample.txt")
if err != nil {
t.Fatal(err) // if it doesn't open, the next steps would fail on nil
}
defer f.Close()
// ... assert on content with t.Errorf
}Configuración y desmontaje con t.Cleanup
Para liberar recursos al final de una prueba (o subprueba), use t.Cleanup en lugar de defer:
func TestDB(t *testing.T) {
db := newTestDB(t)
t.Cleanup(func() { db.Close() })
// ... test
}La ventaja sobre defer: el asistente que crea db puede registrar la limpieza internamente, por lo que las personas que llaman no necesitan recordarla.
Ayudantes de prueba
El método t.Helper() marca una función como "ayudante": cuando una prueba falla, el seguimiento de la pila salta la función auxiliar y apunta directamente a la persona que llama:
func mustParseInt(t *testing.T, s string) int {
t.Helper()
n, err := strconv.Atoi(s)
if err != nil {
t.Fatalf("parse %q: %v", s, err)
}
return n
}Ejercicios
Defina la función TestSum que verifica Sum(2,3) == 5 usando t.Errorf con un mensaje formateado.
Solución disponible después de 3 intentos
En TestDiv, use t.Fatal para detener inmediatamente la prueba si Div devuelve un valor inesperado.
Solución disponible después de 3 intentos
¿Cuál es la diferencia fundamental entre t.Error y t.Fatal?
if err != nil {
t.???(err)
}