Ejecutar pruebas unitarias no alcanza. También debemos saber leer los resultados que produce la herramienta de testing.
Una ejecución puede indicar pruebas exitosas, fallidas, con errores de ejecución, omitidas o marcadas como fallas esperadas. Cada estado comunica algo distinto y requiere una acción diferente.
En este tema aprenderemos a interpretar esos resultados para diagnosticar problemas con mayor rapidez.
La salida de una herramienta de pruebas suele informar:
El formato exacto cambia según el lenguaje y framework, pero los conceptos son parecidos.
Una prueba exitosa es una prueba que se ejecutó y cumplió sus aserciones. En muchos reportes aparece como passed, ok, success o con un punto.
3 passed in 0.02s
Esto significa que las tres pruebas ejecutadas coincidieron con sus resultados esperados. No significa que el programa completo no tenga errores; solo que los comportamientos cubiertos por esas pruebas pasaron.
Cuando todas las pruebas pasan, podemos tener mayor confianza, pero no debemos exagerar la conclusión.
Preguntas útiles:
Un resultado exitoso es buena señal, pero depende de la calidad y alcance de las pruebas.
Una prueba fallida es una prueba que se ejecutó, pero una aserción no se cumplió. En reportes suele aparecer como failed, failure o F.
FAILED test_descuentos.py::test_aplicar_descuento_del_10_por_ciento
assert 100 == 900
La prueba esperaba 900, pero obtuvo 100. Esto indica una diferencia entre comportamiento esperado y comportamiento real.
En muchos frameworks, una falla y un error no son exactamente lo mismo.
| Resultado | Significado | Ejemplo |
|---|---|---|
| Falla | La prueba se ejecutó, pero una aserción no se cumplió. | Esperaba 900 y obtuvo 100. |
| Error | La prueba no pudo completarse por un problema durante la ejecución. | Nombre de función inexistente o excepción no esperada. |
Esta diferencia ayuda a diagnosticar. Una falla suele apuntar a una expectativa incumplida; un error puede indicar un problema de preparación, configuración o excepción no controlada.
Supongamos esta prueba:
def test_calcular_total():
total = calcular_totl([100, 200])
assert total == 300
La función está mal escrita: calcular_totl en lugar de calcular_total. La prueba no falla por una aserción incorrecta; produce un error porque no puede ejecutar correctamente.
NameError: name 'calcular_totl' is not defined
Una prueba omitida es una prueba que el framework reconoce, pero decide no ejecutar. Suele aparecer como skipped, skip o S.
Motivos habituales:
Omitir una prueba puede ser válido, pero debe tener una razón clara.
Una prueba omitida sin explicación se convierte en deuda técnica. Debe quedar claro por qué no se ejecuta.
import pytest
@pytest.mark.skip(reason="Pendiente hasta definir regla de descuentos para empleados")
def test_cliente_empleado_tiene_descuento():
assert obtener_descuento("empleado") == 20
El detalle exacto depende del framework, pero la idea es universal: si una prueba se omite, la razón debe ser visible.
Algunos frameworks permiten marcar una prueba como falla esperada. Esto se usa cuando sabemos que un comportamiento aún no está implementado o que existe un defecto conocido.
En pytest, por ejemplo, puede aparecer como xfail.
import pytest
@pytest.mark.xfail(reason="La regla de cupones vencidos aún no está implementada")
def test_cupon_vencido_no_es_valido():
assert cupon_es_valido("PROMO") == False
Debe usarse con cuidado. Si se abusa de fallas esperadas, la suite puede ocultar problemas reales.
Si una prueba marcada como falla esperada pasa, algunos frameworks lo informan como resultado inesperado. Esto puede ser una buena noticia: quizá el defecto ya fue corregido.
En ese caso, conviene revisar la prueba y quitar la marca de falla esperada si el comportamiento ya debe cumplirse normalmente.
No hay que dejar marcas obsoletas porque confunden el estado real de la suite.
Un resumen puede verse así:
10 passed, 2 failed, 1 skipped in 0.35s
Esto indica:
La prioridad inmediata suele ser entender las fallas y revisar si la omisión sigue justificada.
Cuando hay varias fallas, puede ser tentador mirar todas a la vez. Normalmente conviene empezar por la primera falla clara.
Razones:
Corregir la primera causa real puede resolver varias fallas posteriores.
Los reportes suelen indicar archivo, nombre de prueba y línea. Esa información es clave.
test_pedidos.py::test_pedido_con_total_cero_no_se_aprueba FAILED
test_pedidos.py:24: AssertionError
Esta salida nos dice dónde empezar a mirar: archivo test_pedidos.py, prueba test_pedido_con_total_cero_no_se_aprueba, línea 24.
La parte más útil de una falla suele ser la comparación entre esperado y obtenido.
assert 'aprobado' == 'pendiente'
- pendiente
+ aprobado
La salida exacta cambia según la herramienta, pero debemos buscar la diferencia: qué esperaba la prueba y qué produjo realmente el código.
El tiempo de ejecución también comunica información. Una suite unitaria debería ser rápida. Si empieza a tardar demasiado, puede haber pruebas lentas mezcladas.
Señales de alerta:
Una suite lenta reduce la frecuencia de ejecución.
Que todas las pruebas pasen no significa que todo el sistema esté cubierto. Solo significa que las pruebas ejecutadas no encontraron diferencias en los casos que verifican.
Una suite puede pasar aunque falten casos importantes. Por eso debemos combinar lectura de resultados con buen diseño de pruebas.
El resultado exitoso es una señal positiva, pero no reemplaza el criterio para evaluar cobertura, riesgo y calidad de los casos.
| Estado | Significado | Acción habitual |
|---|---|---|
| Passed | La prueba cumplió sus aserciones. | Continuar o ejecutar una suite más amplia. |
| Failed | Una aserción no se cumplió. | Comparar esperado y obtenido. |
| Error | La prueba no pudo completarse correctamente. | Revisar preparación, imports o excepción inesperada. |
| Skipped | La prueba fue omitida. | Confirmar que la razón sigue siendo válida. |
| Xfail | Falla esperada. | Revisar periódicamente si sigue justificada. |
Al leer resultados de pruebas, revisa:
Leer resultados de pruebas es una habilidad práctica. No alcanza con ver si la salida está en verde o rojo; debemos interpretar qué pasó, dónde ocurrió, qué se esperaba y qué acción corresponde.
Una buena lectura de resultados acelera el diagnóstico y evita cambios impulsivos. Cada estado de la suite comunica información distinta.
En el próximo tema profundizaremos en cómo interpretar un mensaje de falla.