5. Interpretar columnas: statements, missed, excluded y percent

5.1 Objetivo del tema

En el tema anterior generamos el reporte básico de cobertura. Ahora vamos a leerlo con más cuidado para entender qué significa cada columna y qué decisiones conviene tomar a partir de esos datos.

El reporte no debe leerse como una calificación automática de calidad. Es una pista técnica que indica qué partes del código fueron ejecutadas por las pruebas y cuáles quedaron sin recorrer.

Objetivo práctico: interpretar correctamente las columnas del reporte y usarlas para decidir qué pruebas agregar.

5.2 Generar el reporte que vamos a analizar

Desde la carpeta del proyecto, ejecuta nuevamente la medición y luego el reporte:

En Windows PowerShell:

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

En Linux o macOS:

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

Una salida posible es:

Name                     Stmts   Miss  Cover
--------------------------------------------
src\tienda\__init__.py       0      0   100%
src\tienda\precios.py       14      2    86%
tests\test_precios.py       10      0   100%
--------------------------------------------
TOTAL                       24      2    92%

5.3 Columna Name

La columna Name muestra el archivo analizado. Cada fila corresponde a un archivo que coverage tuvo en cuenta durante la medición.

En el ejemplo aparecen archivos de src y también archivos de tests. Más adelante configuraremos coverage para enfocarnos solo en el código de aplicación cuando sea necesario.

5.4 Columna Stmts

Stmts significa statements, es decir, sentencias ejecutables detectadas por coverage.

No todas las líneas del archivo cuentan como sentencia. Comentarios, líneas en blanco y algunas líneas estructurales no aumentan este número.

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

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

    return total

Coverage cuenta las instrucciones que Python puede ejecutar. Por eso Stmts no tiene por qué coincidir con la cantidad total de líneas visibles en el archivo.

5.5 Columna Miss

Miss indica cuántas sentencias ejecutables no fueron recorridas por las pruebas.

Si un archivo tiene 14 sentencias y 2 quedaron sin ejecutar, significa que las pruebas tocaron gran parte del archivo, pero todavía hay caminos pendientes.

Una sentencia faltante no siempre implica un error en las pruebas, pero sí merece una revisión: puede ser un caso borde, una validación, una rama de error o código que ya no se usa.

5.6 Columna Cover

Cover muestra el porcentaje de sentencias ejecutadas. Se calcula a partir de las sentencias totales y las sentencias faltantes.

sentencias cubiertas = Stmts - Miss
porcentaje = sentencias cubiertas / Stmts * 100

Para src\tienda\precios.py, el cálculo es:

14 - 2 = 12 sentencias cubiertas
12 / 14 * 100 = 85.71%

El reporte redondea ese valor y muestra 86%.

5.7 Columna Missing

La columna Missing aparece cuando generamos el reporte con la opción -m:

python -m coverage report -m

La salida agrega las líneas faltantes:

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

En este caso, las sentencias no ejecutadas están en las líneas 6 y 14 de src\tienda\precios.py.

5.8 Columna Excluded

La columna Excluded aparece cuando hay líneas excluidas del cálculo de cobertura. Una exclusión le indica a coverage que no tenga en cuenta cierta línea o bloque.

Una forma común de excluir una línea es usar pragma: no cover:

if __name__ == "__main__":  # pragma: no cover
    main()

Si el reporte incluye exclusiones, puede verse así:

Name                    Stmts   Miss  Cover   Missing
-----------------------------------------------------
src\app.py                20      1    95%   12

Dependiendo de la configuración y de la versión de la herramienta, también puede mostrarse una columna específica para líneas excluidas. Lo importante es entender que esas líneas no penalizan el porcentaje final.

5.9 Cómo usar estos datos

El primer archivo que conviene revisar suele ser el que combina dos señales: tiene cobertura baja y pertenece a una parte importante del sistema.

No siempre hay que empezar por el archivo con menor porcentaje. Un archivo pequeño puede mostrar 0% porque todavía no se usa, mientras que un módulo crítico con 80% puede tener caminos de error importantes sin probar.

Regla práctica: usa Miss y Missing para ubicar zonas sin ejecutar, pero decide qué probar según el comportamiento real que debe garantizar el programa.

5.10 Errores de interpretación

  • Confundir líneas con sentencias: Stmts no es la cantidad total de líneas del archivo.
  • Creer que 100% garantiza calidad: puede haber cobertura completa con aserciones débiles.
  • Ignorar archivos críticos con cobertura media: el riesgo del código importa tanto como el porcentaje.
  • Agregar pruebas solo para subir el número: las pruebas deben verificar comportamientos concretos.

5.11 Conclusión

En este tema interpretamos las columnas principales del reporte: Name, Stmts, Miss, Cover, Missing y Excluded.

En el próximo tema veremos cómo usar pytest-cov para obtener la medición de cobertura directamente al ejecutar pytest.