7. Reportes en terminal: term, term-missing y lectura de líneas faltantes

7.1 Objetivo del tema

En el tema anterior usamos pytest-cov para medir cobertura desde pytest. Ahora vamos a concentrarnos en los reportes que aparecen en la terminal y en cómo leer la columna de líneas faltantes.

La terminal suele ser el primer lugar donde consultamos la cobertura, especialmente durante el desarrollo. Por eso conviene entender qué aporta cada tipo de reporte.

Objetivo práctico: comparar term y term-missing, y usar la columna Missing para decidir qué probar.

7.2 Reporte term con pytest-cov

El reporte term muestra una tabla resumida en la terminal.

En Windows PowerShell:

$env:PYTHONPATH="src"
python -m pytest --cov=src --cov-report=term

En Linux o macOS:

PYTHONPATH=src python -m pytest --cov=src --cov-report=term

La salida es similar a:

Name                     Stmts   Miss  Cover
--------------------------------------------
src\tienda\__init__.py       0      0   100%
src\tienda\precios.py       14      2    86%
--------------------------------------------
TOTAL                       14      2    86%

Este formato sirve para una revisión rápida del porcentaje por archivo.

7.3 Reporte term-missing

El reporte term-missing agrega una columna con las líneas que no se ejecutaron.

En Windows PowerShell:

$env:PYTHONPATH="src"
python -m pytest --cov=src --cov-report=term-missing

En Linux o macOS:

PYTHONPATH=src python -m pytest --cov=src --cov-report=term-missing

La salida es similar a:

Name                     Stmts   Miss  Cover   Missing
------------------------------------------------------
src\tienda\__init__.py       0      0   100%
src\tienda\precios.py       14      2    86%   6, 14
------------------------------------------------------
TOTAL                       14      2    86%

La columna Missing indica líneas concretas del archivo que no fueron ejecutadas por las pruebas.

7.4 Obtener el mismo resultado con coverage.py

Si prefieres usar coverage.py directamente, el equivalente es:

En Windows PowerShell:

$env:PYTHONPATH="src"
python -m coverage run -m pytest
python -m coverage report -m

En Linux o macOS:

PYTHONPATH=src python -m coverage run -m pytest
python -m coverage report -m

La opción -m de coverage report cumple el mismo papel práctico que term-missing: mostrar las líneas faltantes.

7.5 Cómo leer números individuales

Si el reporte muestra:

src\tienda\precios.py       14      2    86%   6, 14

la interpretación es:

  • 14: sentencias ejecutables detectadas.
  • 2: sentencias que no se ejecutaron.
  • 86%: porcentaje de sentencias ejecutadas.
  • 6, 14: líneas del archivo que quedaron sin ejecutar.

El siguiente paso es abrir el archivo y revisar qué comportamiento representa cada línea faltante.

7.6 Rangos de líneas faltantes

Cuando hay varias líneas consecutivas sin cubrir, coverage puede mostrar rangos:

src\pedidos.py       42      7    83%   18-22, 35, 39

Esto significa que no se ejecutaron las líneas 18, 19, 20, 21, 22, 35 y 39.

Los rangos suelen aparecer en bloques completos de código no visitado, como una rama de error o una función auxiliar que todavía no tiene pruebas.

7.7 Revisar el código señalado

Supongamos que el reporte marca las líneas 6 y 14 de precios.py:

def aplicar_descuento(precio, porcentaje):
    if precio <= 0:
        raise ValueError("El precio debe ser mayor que cero")

    if porcentaje < 0 or porcentaje > 100:
        raise ValueError("El porcentaje debe estar entre 0 y 100")

    descuento = precio * porcentaje / 100
    return precio - descuento


def calcular_total(items):
    if not items:
        return 0

    total = 0
    for item in items:
        total += item["precio"] * item["cantidad"]

    return total

Si una línea faltante corresponde a una validación, la prueba debería verificar ese comportamiento. Si corresponde a código que ya no se usa, quizá convenga eliminarlo o revisarlo antes de escribir una prueba artificial.

7.8 Convertir líneas faltantes en pruebas

Una línea faltante no dice automáticamente qué prueba escribir, pero sí señala dónde mirar. Para las líneas anteriores, pueden agregarse pruebas como:

def test_aplicar_descuento_rechaza_porcentaje_menor_que_cero():
    with pytest.raises(ValueError):
        aplicar_descuento(1000, -1)


def test_calcular_total_sin_items():
    assert calcular_total([]) == 0

La intención no es cubrir líneas por cubrir, sino verificar comportamientos que el programa promete manejar.

7.9 Cuándo usar cada reporte

  • term: cuando solo necesitas una vista rápida del porcentaje por archivo.
  • term-missing: cuando quieres decidir qué código revisar a continuación.
  • coverage report: cuando ya tienes datos generados con coverage run.
  • coverage report -m: cuando quieres agregar la lista de líneas faltantes.

7.10 Problemas frecuentes

  • No aparece la columna Missing: usa --cov-report=term-missing o python -m coverage report -m.
  • Las líneas no coinciden: guarda el archivo y vuelve a ejecutar la medición.
  • Se miden archivos de prueba: limita el origen con --cov=src o configura coverage más adelante.
  • El reporte es demasiado largo: enfócate primero en los módulos de mayor importancia para el proyecto.

7.11 Conclusión

En este tema comparamos los reportes term y term-missing, y vimos cómo interpretar números individuales y rangos de líneas faltantes.

En el próximo tema vamos a generar reportes HTML para navegar visualmente el código cubierto y no cubierto.