Skip to content

About

Proyecto didáctico que muestra, paso a paso, cómo aplicar mutation testing en Python con pytest y mutmut. La idea es evidenciar la diferencia entre tener cobertura y detectar verdaderos defectos generando mutaciones realistas en el código y verificando si tus pruebas las “matan”

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

Repository files navigation

Laboratorio: cobertura no significa detectar defectos

Practica mutation testing con is_prime y safe_div. Tu objetivo es explicar qué defecto detecta cada prueba nueva. Duración orientativa: 45–60 minutos.

Preparación

Usa Python 3.10–3.13 y ejecuta los comandos desde la raíz del repositorio.

python -m venv .venv
Terminal Activación
Linux, macOS o WSL (bash) source .venv/bin/activate
Windows PowerShell .\.venv\Scripts\Activate.ps1
Windows CMD .venv\Scripts\activate.bat
python -m pip install -r requirements-dev.txt
python -m pytest -q

La ruta guiada funciona también en Windows, sin instalar mutmut.

Contrato

  • is_prime(n): para enteros, devuelve si n es primo; todo valor menor que 2 es no primo.
  • safe_div(a, b): para enteros y divisor distinto de cero, devuelve a // b (redondeo hacia menos infinito). Si el divisor es cero, lanza ValueError.
  • No se exige un texto particular para la excepción ni un tiempo de ejecución concreto.
  • Entradas de otros tipos quedan fuera del ejercicio.

1. Establece la línea base

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

Copia docs/INFORME.md como INFORME.md y registra las métricas iniciales. Identifica qué regla del contrato todavía no ejercita la suite.

2. Consigue cobertura completa

Añade a tests/test_math_utils.py este caso:

def test_is_prime_cero():
    assert is_prime(0) is False

Repite la medición. Antes de continuar, responde: ¿ejecutar todas las líneas y ramas garantiza que las condiciones tienen el límite correcto?

3. Pon a prueba esa confianza

El laboratorio incluye dos mutaciones controladas. El script ejecuta primero el código original y después cada mutante en una copia temporal; no modifica src.

python tools/check_mutants.py

Para cada superviviente, anota la modificación que muestra el script y predice una entrada que distinga el original del mutante. Un superviviente también puede preservar el contrato.

4. Diseña una prueba discriminante

Añade pruebas a tests/ para detectar el defecto del mutante de frontera. Demuestra que pasan con el original y fallan con ese mutante. Puedes usar pytest.mark.parametrize para incluir varias entradas justificadas.

python -m pytest --cov=src --cov-branch --cov-report=term-missing
python tools/check_mutants.py

Compara con la fase 2: la cobertura puede mantenerse mientras mejora la detección. No cambies el código productivo, elimines pruebas ni excluyas líneas de la medición.

5. Explica el superviviente restante

Analiza la mutación del incremento del divisor. ¿Cambia algún resultado para el dominio especificado? Argumenta sobre divisores pares e impares y terminación. Probar muchos números puede apoyar tu explicación, pero no demuestra equivalencia. No añadas una prueba de tiempo si el contrato no exige rendimiento.

Exploración con mutmut

Para esta extensión usa Linux, macOS o WSL y Python 3.10/3.11 en un entorno separado. Se fija mutmut 2.4.4 para mantener los comandos y setup.cfg de esa versión; no mezcles estas instrucciones con mutmut 3 o posterior.

python -m pip install -r requirements-mutmut.txt
mutmut run
mutmut results
mutmut show <ID>

Sustituye <ID> por un identificador real. Los identificadores, el catálogo y los recuentos no tienen por qué coincidir con los dos mutantes guiados. Después de añadir pruebas, repite mutmut run. No necesitas aplicar mutaciones a tus archivos para inspeccionarlas.

Clasifica los resultados: detectado, superviviente por una brecha, equivalente respecto del contrato o pendiente de investigación. Los errores de ejecución y timeouts se revisan por separado; no se cuentan automáticamente como éxitos.

Calcula detectados / (detectados + supervivientes) sobre casos ejecutados y clasificados. Para una puntuación ajustada, excluye únicamente los equivalentes justificados del denominador y muestra también la puntuación bruta. Un denominador vacío se informa como «no aplica».

Referencia: mutmut 2.4.4.

Entrega y evaluación

Entrega tus cambios en tests/ y el informe con resultados antes/después.

Criterio Puntos
Línea base y comparación de cobertura y mutación reproducibles 2
Prueba que pasa en el original y detecta el mutante de frontera 3
Justificación de entradas según el contrato 2
Argumento de equivalencia y tratamiento de resultados pendientes 2
Explicación de por qué 100 % de cobertura no basta 1

La extensión con mutmut amplía el análisis; no es necesaria para completar la ruta guiada. Material docente: guía y solución.

About

Proyecto didáctico que muestra, paso a paso, cómo aplicar mutation testing en Python con pytest y mutmut. La idea es evidenciar la diferencia entre tener cobertura y detectar verdaderos defectos generando mutaciones realistas en el código y verificando si tus pruebas las “matan”

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages