21. Lectura de resultados: pruebas exitosas, fallidas y omitidas

21.1 Introducción

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.

21.2 Qué informa una ejecución de pruebas

La salida de una herramienta de pruebas suele informar:

  • Cuántas pruebas se ejecutaron.
  • Cuántas pasaron.
  • Cuántas fallaron.
  • Cuántas se omitieron.
  • Cuánto tiempo tardó la ejecución.
  • Qué archivo, prueba o línea produjo una falla.

El formato exacto cambia según el lenguaje y framework, pero los conceptos son parecidos.

21.3 Prueba exitosa

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.

21.4 Qué hacer cuando todo pasa

Cuando todas las pruebas pasan, podemos tener mayor confianza, pero no debemos exagerar la conclusión.

Preguntas útiles:

  • ¿Se ejecutaron las pruebas que correspondían?
  • ¿La suite cubre el comportamiento que cambiamos?
  • ¿Hay pruebas omitidas que deberíamos revisar?
  • ¿La suite fue suficientemente amplia para este cambio?

Un resultado exitoso es buena señal, pero depende de la calidad y alcance de las pruebas.

21.5 Prueba fallida

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.

21.6 Diferencia entre falla y error

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.

21.7 Ejemplo de error de ejecución

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

21.8 Prueba omitida

Una prueba omitida es una prueba que el framework reconoce, pero decide no ejecutar. Suele aparecer como skipped, skip o S.

Motivos habituales:

  • La prueba depende de una característica temporalmente no disponible.
  • Solo aplica en cierto sistema operativo.
  • Requiere una dependencia externa que no está presente.
  • Fue omitida temporalmente mientras se corrige un problema.

Omitir una prueba puede ser válido, pero debe tener una razón clara.

21.9 Omitir con explicación

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.

21.10 Falla esperada

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.

21.11 Resultado inesperadamente exitoso

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.

21.12 Interpretar el resumen

Un resumen puede verse así:

10 passed, 2 failed, 1 skipped in 0.35s

Esto indica:

  • 10 pruebas pasaron.
  • 2 pruebas fallaron y requieren análisis.
  • 1 prueba fue omitida.
  • La ejecución tardó 0.35 segundos.

La prioridad inmediata suele ser entender las fallas y revisar si la omisión sigue justificada.

21.13 Leer de arriba hacia abajo

Cuando hay varias fallas, puede ser tentador mirar todas a la vez. Normalmente conviene empezar por la primera falla clara.

Razones:

  • Una causa puede producir muchas fallas.
  • Un error de importación puede afectar todo un archivo.
  • Una falla en preparación compartida puede romper varios casos.

Corregir la primera causa real puede resolver varias fallas posteriores.

21.14 Ubicación de la falla

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.

21.15 Resultado esperado contra obtenido

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.

21.16 Tiempo de ejecución

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 prueba unitaria tarda varios segundos sin razón.
  • La suite se vuelve más lenta después de agregar pocas pruebas.
  • Las pruebas dependen de red, base de datos o archivos grandes.
  • Hay esperas artificiales en las pruebas.

Una suite lenta reduce la frecuencia de ejecución.

21.17 No confundir pasar con estar bien cubierto

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.

21.18 Tabla de estados comunes

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.

21.19 Lista de comprobación

Al leer resultados de pruebas, revisa:

  • ¿Cuántas pruebas se ejecutaron realmente?
  • ¿Hubo fallas o errores?
  • ¿La primera falla explica otras fallas posteriores?
  • ¿La diferencia entre esperado y obtenido está clara?
  • ¿Hay pruebas omitidas?
  • ¿El tiempo de ejecución sigue siendo razonable?
  • ¿El resultado exitoso cubre el cambio que estás validando?

21.20 Qué debes recordar de este tema

  • Una prueba exitosa cumplió sus aserciones.
  • Una prueba fallida ejecutó, pero no cumplió una expectativa.
  • Un error indica que la prueba no pudo completarse correctamente.
  • Una prueba omitida no se ejecutó y debe tener una razón clara.
  • Las fallas esperadas deben revisarse periódicamente.
  • El resumen de ejecución ayuda a decidir la siguiente acción.
  • Que todo pase no significa que todo esté probado.

21.21 Conclusión

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.