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.
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%
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.
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.
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.
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%.
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.
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.
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.
Miss y Missing para ubicar zonas sin ejecutar, pero decide qué probar según el comportamiento real que debe garantizar el programa.
Stmts no es la cantidad total de líneas del archivo.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.