8. Generar reportes HTML y navegar el código no cubierto

8.1 Objetivo del tema

Los reportes en terminal son rápidos, pero cuando un archivo tiene muchas líneas faltantes resulta más cómodo revisar la cobertura en una página HTML.

En este tema vamos a generar un reporte navegable, abrirlo en el navegador y usarlo para encontrar visualmente qué partes del código quedaron sin ejecutar.

Objetivo práctico: crear la carpeta htmlcov y abrir index.html para inspeccionar la cobertura archivo por archivo.

8.2 Generar datos de cobertura

Primero necesitamos ejecutar las pruebas bajo cobertura. En Windows PowerShell:

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

En Linux o macOS:

PYTHONPATH=src python -m coverage run -m pytest

Esto crea o actualiza el archivo .coverage, que luego se usará para construir el reporte HTML.

8.3 Crear el reporte HTML

Después de generar los datos, ejecuta:

python -m coverage html

Coverage crea una carpeta llamada htmlcov:

cobertura-demo/
|-- .coverage
|-- htmlcov/
|   |-- index.html
|   |-- status.json
|   `-- ...
|-- src/
`-- tests/

El archivo principal del reporte es htmlcov/index.html.

8.4 Abrir el reporte en el navegador

En Windows puedes abrirlo desde el explorador de archivos o ejecutar:

start htmlcov\index.html

En Linux:

xdg-open htmlcov/index.html

En macOS:

open htmlcov/index.html

El navegador mostrará una tabla con los archivos medidos y sus porcentajes de cobertura.

Reporte HTML de cobertura con archivos medidos y porcentajes

8.5 Generar HTML con pytest-cov

Si usas pytest-cov, puedes generar el reporte HTML en la misma ejecución de pytest.

En Windows PowerShell:

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

En Linux o macOS:

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

Este comando también crea la carpeta htmlcov.

8.6 Combinar reporte terminal y HTML

Durante el desarrollo suele ser útil ver el resumen en la terminal y además generar el reporte HTML:

En Windows PowerShell:

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

En Linux o macOS:

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

Así obtienes una vista rápida en la consola y una vista navegable para inspeccionar los detalles.

8.7 Navegar el índice HTML

La página principal del reporte muestra una fila por archivo. Normalmente verás datos como:

  • Statements: sentencias ejecutables detectadas.
  • Missing: sentencias que no se ejecutaron.
  • Excluded: líneas excluidas del cálculo, si existen.
  • Coverage: porcentaje cubierto.

Haz clic en un archivo para ver su código con marcas visuales línea por línea.

8.8 Leer colores y marcas

Dentro de un archivo, el reporte HTML resalta las líneas según su estado.

  • Líneas ejecutadas: aparecen como código cubierto.
  • Líneas faltantes: aparecen resaltadas como código no ejecutado.
  • Líneas excluidas: aparecen separadas del cálculo de cobertura.

El valor principal del reporte HTML es que permite leer el código completo alrededor de cada línea faltante. Eso ayuda a entender el comportamiento que todavía no tiene pruebas.

8.9 Ejemplo de análisis

Si el reporte marca como faltante una validación como esta:

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

la pregunta no es solo cómo cubrir esa línea. La pregunta correcta es qué comportamiento falta verificar.

En este caso, una prueba útil sería comprobar que la función rechaza porcentajes inválidos:

def test_aplicar_descuento_rechaza_porcentaje_mayor_que_cien():
    with pytest.raises(ValueError):
        aplicar_descuento(1000, 101)

8.10 Regenerar el reporte

El reporte HTML no se actualiza solo cuando cambias el código o las pruebas. Debes volver a ejecutar la medición y generar el HTML.

Con coverage.py:

python -m coverage erase
python -m coverage run -m pytest
python -m coverage html

Con pytest-cov:

python -m pytest --cov=src --cov-report=html

Después de regenerarlo, actualiza la página del navegador para ver los cambios.

8.11 Qué hacer con htmlcov

La carpeta htmlcov es un resultado generado. No conviene editarla a mano ni tratarla como código fuente.

En la mayoría de los proyectos, htmlcov se agrega a .gitignore:

htmlcov/
.coverage

Cada persona puede regenerar el reporte localmente cuando lo necesite.

8.12 Problemas frecuentes

  • No such file or directory: htmlcov/index.html: primero ejecuta python -m coverage html o usa --cov-report=html.
  • No data to report: primero ejecuta las pruebas con cobertura.
  • El navegador muestra datos viejos: regenera el reporte y actualiza la página.
  • El reporte incluye archivos no deseados: limita la medición con --cov=src o configura source más adelante.

8.13 Conclusión

En este tema generamos reportes HTML con python -m coverage html y con pytest-cov. También vimos cómo abrir htmlcov/index.html y navegar las líneas cubiertas y no cubiertas.

En el próximo tema vamos a usar los reportes para mejorar la cobertura de funciones puras agregando pruebas donde el reporte lo indica.