Saltar al contenido principal
eLearner.app
Módulo 9 · Lección 1 de 541/50 en el curso~12 min
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.go y se encuentran en el mismo paquete que el código que prueban (o en un paquete <name>_test para "pruebas de caja negra").
  • Las funciones de prueba tienen una firma exacta: func TestXxx(t *testing.T) donde Xxx comienza con una letra mayúscula.
  • Importas testing desde stdlib.
  • Sin assertEquals: usas if got != want { t.Errorf(...) } con verbos fmt.
Go
// 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:

Bash
go test ./...        # all packages in the module
go test -v ./pkg     # verbose: prints test names
go test -run TestSum  # only tests matching the regex

CÓDIGOPH0 frente a CÓDIGOPH1

Estos son los dos verbos básicos para señalar un fracaso:

MétodoEfecto
CÓDIGOPH0Registra pero no falla (visible solo con -v o en caso de falla).
CÓDIGOPH2Registra, marca FAIL, continúa la función de prueba.
CÓDIGOPH3Como Error con formato.
CÓDIGOPH5Registra, marca FAIL, detiene la prueba (llama a runtime.Goexit).
CÓDIGOPH7Como 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.

Go
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:

Go
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:

Go
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

Ejercicio#go.m9.l1.e1
Intentos: 0Cargando...

Defina la función TestSum que verifica Sum(2,3) == 5 usando t.Errorf con un mensaje formateado.

Cargando editor...

Solución disponible después de 3 intentos

Ejercicio#go.m9.l1.e2
Intentos: 0Cargando...

En TestDiv, use t.Fatal para detener inmediatamente la prueba si Div devuelve un valor inesperado.

Cargando editor...

Solución disponible después de 3 intentos

Cuestionario#go.m9.l1.e3
Listo

¿Cuál es la diferencia fundamental entre t.Error y t.Fatal?

Go
if err != nil {
  t.???(err)
}
Opciones de respuesta