16. Configurar source, omit, include y branch en pyproject.toml

16.1 Objetivo del tema

Hasta ahora pasamos muchas opciones por la terminal: --cov=src, --cov-branch, --cov-report y otras. Eso sirve para aprender, pero en un proyecto real conviene guardar la configuración en un archivo.

En este tema vamos a usar pyproject.toml para configurar qué código medir, qué archivos excluir y si queremos activar cobertura de ramas.

Objetivo práctico: centralizar la configuración de coverage.py para repetir mediciones consistentes.

16.2 Por qué configurar coverage

Sin configuración, cada persona puede medir de una manera distinta. Una ejecución puede incluir tests, otra puede medir scripts auxiliares y otra puede olvidar branch coverage.

La configuración evita esos problemas porque deja por escrito las reglas de medición del proyecto.

  • source: indica qué código queremos medir.
  • omit: excluye archivos que no deben medirse.
  • include: limita la medición a patrones específicos.
  • branch: activa cobertura de ramas.

16.3 Crear pyproject.toml

En la raíz de cobertura-demo, crea o edita el archivo pyproject.toml:

cobertura-demo/
|-- pyproject.toml
|-- src/
|   `-- tienda/
`-- tests/

Si el archivo ya existe porque el proyecto usa otras herramientas, agrega las secciones de coverage sin borrar la configuración existente.

16.4 Configurar source

La opción source indica qué parte del proyecto se considera código de aplicación:

[tool.coverage.run]
source = ["src"]

Con esta configuración, coverage se enfoca en src y deja de tratar los tests como parte principal de la medición.

Luego puedes ejecutar:

python -m coverage run -m pytest
python -m coverage report -m

16.5 Activar branch

Para medir ramas por defecto, agrega branch = true:

[tool.coverage.run]
source = ["src"]
branch = true

Así ya no necesitas recordar --branch en cada ejecución con coverage.py.

python -m coverage run -m pytest
python -m coverage report -m

El reporte incluirá información de ramas cuando corresponda.

16.6 Configurar omit

omit excluye archivos o patrones que no queremos medir. Por ejemplo:

[tool.coverage.run]
source = ["src"]
branch = true
omit = [
    "*/__init__.py",
    "*/migrations/*",
    "*/scripts/*",
]

Esto puede ser útil para archivos vacíos, migraciones generadas o scripts auxiliares que no forman parte del comportamiento principal.

16.7 No abusar de omit

Excluir archivos baja el ruido, pero también puede ocultar problemas. No conviene usar omit para esconder código difícil de probar.

Antes de omitir un archivo, revisa si realmente cumple alguna de estas condiciones:

  • Es código generado por una herramienta.
  • Es un archivo de inicialización sin lógica.
  • Es un script manual fuera del flujo principal.
  • Será cubierto por otro tipo de prueba o revisión.

16.8 Configurar include

include sirve para limitar la medición a ciertos patrones. Es menos común cuando ya usamos source, pero puede ser útil en proyectos grandes.

[tool.coverage.run]
include = [
    "src/tienda/*.py",
]

En general, evita mezclar source e include sin una razón clara. Para este curso, source = ["src"] suele ser suficiente.

16.9 Configurar el reporte

También puedes configurar opciones del reporte:

[tool.coverage.report]
show_missing = true
skip_covered = false
precision = 2

Con show_missing = true, el reporte muestra líneas faltantes sin tener que pasar -m cada vez.

python -m coverage report

16.10 Configuración recomendada inicial

Para el proyecto del curso, una configuración razonable sería:

[tool.coverage.run]
source = ["src"]
branch = true
omit = [
    "*/__init__.py",
]

[tool.coverage.report]
show_missing = true
precision = 2

Esta configuración mide el código de src, activa ramas y muestra líneas faltantes en el reporte.

16.11 Usar la configuración con pytest-cov

pytest-cov también respeta la configuración de coverage. Puedes ejecutar:

En Windows PowerShell:

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

En Linux o macOS:

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

Al usar --cov sin valor, pytest-cov toma la configuración de coverage para decidir qué medir.

16.12 Verificar qué configuración se está usando

Si tienes dudas sobre la configuración cargada, ejecuta:

python -m coverage debug config

Este comando muestra qué archivo de configuración se encontró y qué opciones quedaron activas.

16.13 Ejemplo de salida esperada

Con show_missing = true y branch = true, el reporte puede verse así:

Name                   Stmts   Miss Branch BrPart   Cover   Missing
-------------------------------------------------------------------
src\tienda\tarifas.py     17      0     12      0  100.00%

Si aparecen ramas parciales, revisa si falta una prueba real o si el código necesita simplificarse.

16.14 Problemas frecuentes

  • Coverage sigue midiendo tests: revisa que source = ["src"] esté bajo [tool.coverage.run].
  • No aparece branch coverage: confirma que branch = true esté bien escrito.
  • La configuración no se aplica: ejecuta los comandos desde la raíz del proyecto.
  • Omit excluye demasiado: revisa los patrones si desaparecen archivos importantes del reporte.

16.15 Conclusión

En este tema centralizamos la configuración de coverage en pyproject.toml. Definimos source, omit, include, branch y opciones del reporte.

En el próximo tema vamos a ver cómo excluir líneas justificadas con pragma: no cover.