Cobertura de tests con Coverage.py

Intermedio
Django
Django
Actualizado: 18/04/2026

Instalación de Coverage.py

pip install coverage

Diagrama conceptual de Cobertura de tests con Coverage.py

Ejecutar tests con cobertura

# Ejecutar tests recopilando datos de cobertura
coverage run --source='.' manage.py test

# Solo para la aplicación específica
coverage run --source='catalogo,usuarios' manage.py test

# Ver resumen en consola
coverage report

# Generar informe HTML detallado
coverage html

# Abrir el informe
# htmlcov/index.html

Ejemplo de salida de coverage report:

Name                      Stmts   Miss  Cover
---------------------------------------------
catalogo/admin.py            45      5    89%
catalogo/forms.py            38      3    92%
catalogo/models.py           67      8    88%
catalogo/views.py            89     21    76%
catalogo/serializers.py      34      2    94%
---------------------------------------------
TOTAL                       273     39    86%

Configuración .coveragerc

Crea un archivo .coveragerc en la raíz del proyecto para configurar Coverage.py:

# .coveragerc
[run]
source = .
omit =
    */migrations/*
    */tests/*
    */test_*.py
    *_test.py
    manage.py
    */settings/*.py
    */wsgi.py
    */asgi.py
    venv/*
    .venv/*

[report]
exclude_lines =
    pragma: no cover
    def __repr__
    if settings.DEBUG
    raise NotImplementedError
    if TYPE_CHECKING:
    pass
show_missing = True
skip_covered = False
precision = 2

[html]
directory = htmlcov
title = Informe de cobertura - MiProyecto

[paths]
source =
    .

Umbrales mínimos de cobertura

# Fallar si la cobertura está por debajo del 80%
coverage report --fail-under=80

pytest con pytest-django y pytest-cov

Muchos proyectos prefieren pytest sobre unittest. Con pytest-django y pytest-cov:

pip install pytest pytest-django pytest-cov
# pytest.ini o setup.cfg
[pytest]
DJANGO_SETTINGS_MODULE = mi_proyecto.settings.test
python_files = tests.py test_*.py *_tests.py
addopts = --cov=. --cov-report=html --cov-fail-under=80
# Ejecutar tests con cobertura
pytest

# Solo algunos tests
pytest catalogo/tests/ -v

# Con informe en consola
pytest --cov=catalogo --cov-report=term-missing

Integración en GitHub Actions CI/CD

# .github/workflows/tests.yml
name: Tests y cobertura

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s

    steps:
    - uses: actions/checkout@v4

    - name: Configurar Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.12'
        cache: 'pip'

    - name: Instalar dependencias
      run: pip install -r requirements.txt

    - name: Ejecutar migraciones
      run: python manage.py migrate
      env:
        DATABASE_URL: postgresql://postgres:postgres@localhost/test_db

    - name: Tests con cobertura
      run: coverage run manage.py test && coverage report --fail-under=80
      env:
        DATABASE_URL: postgresql://postgres:postgres@localhost/test_db

    - name: Subir informe de cobertura
      uses: codecov/codecov-action@v4
      with:
        token: ${{ secrets.CODECOV_TOKEN }}

Excluir código de la cobertura

Para líneas que son difíciles de testar (entornos específicos, código de fallback):

def configurar_logging():  # pragma: no cover
    """Solo se ejecuta en producción."""
    import logging
    logging.basicConfig(level=logging.ERROR)

def debug_info():
    if settings.DEBUG:  # La rama False es difícil de testar en desarrollo
        return {'debug': True}
    return {}  # pragma: no cover

Una cobertura del 80-90 % es un objetivo razonable para la mayoría de proyectos Django. Aspirar al 100 % puede resultar contraproducente si requiere tests frágiles que solo aumentan el número, no la calidad de las pruebas.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Django es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Django

Explora más contenido relacionado con Django y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Instalar y configurar Coverage.py para medir la cobertura del código Django. Ejecutar tests con coverage para recopilar datos de cobertura. Generar informes HTML detallados con coverage html. Configurar .coveragerc para excluir archivos irrelevantes. Integrar coverage en un pipeline CI/CD con umbrales mínimos.