Cuando una prueba falla, no alcanza con mirar que la suite está en rojo. Necesitamos diagnosticar qué falló, dónde falló, si el problema está en el código, en la prueba o en los datos.
En este tema construiremos una forma ordenada de analizar fallas en suites automatizadas usando las herramientas de pytest que ya venimos practicando.
El primer error frecuente es corregir sin leer. Una salida de pytest suele mostrar:
Crea temporalmente tests/test_diagnostico.py:
from app.carrito import calcular_total
def test_calcular_total_falla_de_ejemplo():
productos = [
{"precio": 100, "cantidad": 2},
{"precio": 50, "cantidad": 3},
]
assert calcular_total(productos) == 300
El resultado correcto debería ser 350. Esta prueba fallará para practicar diagnóstico.
Ejecuta el archivo específico:
python -m pytest tests/test_diagnostico.py
Luego ejecuta la prueba exacta:
python -m pytest tests/test_diagnostico.py::test_calcular_total_falla_de_ejemplo
Aislar la prueba reduce ruido y permite concentrarse en una falla.
Para una salida compacta:
python -m pytest tests/test_diagnostico.py --tb=short
Para una línea por falla:
python -m pytest tests/test_diagnostico.py --tb=line
La traza corta ayuda cuando el error es claro. La traza larga ayuda cuando necesitas más contexto.
Si hay muchas fallas, comienza con una:
python -m pytest -x
Corregir la primera falla puede hacer desaparecer varias fallas derivadas.
Si el problema está en carrito, puedes usar -k:
python -m pytest -k carrito
O ejecutar el archivo relacionado:
python -m pytest tests/test_carrito.py
Ante una falla, no asumas automáticamente que el código está mal. También puede estar mal el valor esperado de la prueba.
Preguntas útiles:
A veces un mensaje ayuda a diagnosticar:
def test_calcular_total_falla_de_ejemplo():
productos = [
{"precio": 100, "cantidad": 2},
{"precio": 50, "cantidad": 3},
]
total = calcular_total(productos)
assert total == 350, f"Total calculado incorrecto: {total}"
No hace falta agregar mensajes a todas las aserciones. pytest ya muestra buenas diferencias en muchos casos.
Durante diagnóstico puedes usar print y ejecutar con -s:
python -m pytest tests/test_diagnostico.py -s
Pero no dejes prints de depuración permanentes si no aportan valor a la prueba.
Si el código ya registra logs, úsalos para diagnosticar. Por ejemplo:
python -m pytest tests/test_importador.py -o log_cli=true --log-cli-level=INFO
Esto puede mostrar información útil sin modificar la prueba.
Muchas fallas vienen de datos incorrectos. Revisa archivos JSON, CSV, fixtures y factories.
Ejemplo de error frecuente:
{
"precio": "100",
"descuento": "10",
"esperado": "90"
}
Si el código espera números, esos valores como texto pueden requerir conversión.
Si una prueba no se ejecuta, revisa la recolección:
python -m pytest --collect-only
Esto ayuda a detectar nombres incorrectos de archivos o funciones.
Si una prueba falla solo a veces, revisa:
No agregues reintentos antes de entender la causa.
Si una falla aparece solo con paralelización, compara:
python -m pytest
python -m pytest -n auto
Una falla solo en paralelo suele indicar estado compartido, archivos compartidos o dependencia de orden.
pytest puede abrir el depurador cuando una prueba falla:
python -m pytest tests/test_diagnostico.py --pdb
Esto es útil para inspeccionar variables en el momento del error. Es una herramienta más avanzada y conviene usarla cuando la salida normal no alcanza.
Antes de modificar el código, intenta reproducir la falla con el comando más pequeño posible.
Buen flujo:
Si una prueba falla, eliminarla rara vez es la solución correcta. Antes de borrar una prueba, entiende qué protegía.
Una prueba puede eliminarse si:
Pero no debe borrarse solo porque falla.
Cuando una falla fue difícil, conviene registrar la causa en el mensaje del cambio, en una nota interna o convirtiéndola en una prueba de regresión.
Si fue un error real, agrega o ajusta una prueba para que no vuelva a ocurrir.
Usa la prueba fallida de ejemplo de tests/test_diagnostico.py. Haz lo siguiente:
--tb=short.total antes del assert.Prueba corregida:
from app.carrito import calcular_total
def test_calcular_total_con_varios_productos_devuelve_suma_total():
productos = [
{"precio": 100, "cantidad": 2},
{"precio": 50, "cantidad": 3},
]
total = calcular_total(productos)
assert total == 350
Comandos:
python -m pytest tests/test_diagnostico.py --tb=short
python -m pytest
Antes de continuar con el próximo tema, verifica lo siguiente:
--tb, -x, -k o --collect-only cuando corresponde.En este tema practicamos un proceso de diagnóstico para fallas en suites automatizadas. Una corrección confiable empieza por reproducir, aislar y entender el problema.
En el próximo tema veremos cómo mantener pruebas automatizadas legibles y confiables a lo largo del tiempo.