Quality Gates en CI: coverage mínimo con pytest-cov y bloqueo de merges

Compartir en:

Una vez que un repositorio cuenta con Integración Continua (CI), el siguiente paso natural es establecer
quality gates: reglas objetivas que determinan si un cambio puede integrarse o no a la rama principal.
En términos prácticos, un quality gate evita que se incorporen cambios que rompan pruebas o que reduzcan
la calidad por debajo de un umbral definido.

En este artículo se documenta cómo implementar un quality gate basado en cobertura de pruebas usando
pytest-cov, y cómo vincularlo a reglas de repositorio en GitHub para bloquear merges cuando la validación falla.

Objetivo

  • Agregar medición de cobertura de pruebas con pytest-cov.
  • Definir un umbral mínimo de cobertura (por ejemplo, 80%).
  • Ejecutar pruebas y cobertura automáticamente en GitHub Actions.
  • Bloquear merges a main si el status check de CI falla.

Concepto: ¿qué es un quality gate en CI?

Un quality gate es una condición de calidad que debe cumplirse para permitir la integración de cambios.
En CI, estas condiciones suelen materializarse como status checks obligatorios: si el pipeline falla, el merge
queda bloqueado. Esto permite estandarizar expectativas de calidad y reducir regresiones.

Prerrequisitos

  • Repositorio con CI configurado (GitHub Actions ejecutando pytest en cada Pull Request).
  • Estructura de proyecto tipo src/ recomendada para proyectos Python.
  • Rama main protegida mediante Rulesets (Pull Request requerido).

1) Agregar pytest-cov al proyecto

Para habilitar medición de cobertura con pytest, se agrega la dependencia pytest-cov.
En el archivo requirements.txt:

pytest==8.3.4
pytest-cov

Una vez actualizado el archivo, se instala localmente:

pip install -r requirements.txt

2) Ejecutar cobertura localmente

Antes de exigir un umbral en CI, es recomendable validar la ejecución local. En Windows PowerShell,
la variable de entorno puede definirse para la sesión actual:

$env:PYTHONPATH="src"
pytest -q --cov=qa_ci_cd_lab --cov-report=term-missing --cov-fail-under=80

Parámetros relevantes:

  • --cov=qa_ci_cd_lab: indica qué paquete medir.
  • --cov-report=term-missing: muestra líneas no cubiertas en consola.
  • --cov-fail-under=80: falla la ejecución si la cobertura total es inferior al 80%.

3) Aplicar el quality gate en GitHub Actions

El objetivo es que el mismo comando se ejecute en el pipeline. En el workflow del repositorio,
por ejemplo .github/workflows/ci.yml, se actualiza el step de pruebas para incluir coverage.

name: CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test:
    name: pytest
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run tests with coverage
        run: |
          PYTHONPATH=src pytest -q --cov=qa_ci_cd_lab --cov-report=term-missing --cov-fail-under=80

Con esta configuración, el pipeline falla automáticamente si:

  • Alguna prueba falla.
  • La cobertura total cae por debajo del umbral configurado.

4) Exigir el status check para permitir merges

Una vez que el workflow se ejecuta y genera un status check estable (por ejemplo CI / pytest),
ese check puede configurarse como requisito para mergear a main.

En GitHub:

  1. Ir a Settings → Rules → Rulesets.
  2. Editar el ruleset que aplica a main.
  3. Activar Require status checks to pass.
  4. Seleccionar el check correspondiente (por ejemplo, CI / pytest).
  5. (Recomendado) Activar Require branches to be up to date before merging.

Con esto, el merge queda bloqueado si el pipeline falla, lo que convierte la cobertura mínima en una
regla efectiva y verificable.

5) Validación del quality gate

Para validar que el gate está funcionando, se puede realizar una prueba controlada:

  1. Crear un Pull Request que agregue una función sin tests (o reduzca cobertura).
  2. Verificar que GitHub Actions ejecuta el workflow automáticamente.
  3. Confirmar que el status check falla por umbral de cobertura y que el merge queda bloqueado.

Consideraciones finales

Establecer quality gates en CI permite estandarizar criterios de calidad y reducir riesgos de integración.
En proyectos pequeños, estos mecanismos también aportan valor al mantener disciplina técnica y evitar
regresiones, especialmente cuando el repositorio se utiliza como evidencia profesional.

Repositorio de referencia

Implementación disponible en:


https://github.com/CFontalvo/qa-ci-cd-lab

Compartir en: