Alejandría

Busca en Alejandría

Técnicas

Mutation testing

Introduce errores deliberados para comprobar si las pruebas detectan cambios de comportamiento.

01

En pocas palabras

Introduce errores deliberados para comprobar si las pruebas detectan cambios de comportamiento.

Qué problema resuelve

Cobertura alta con aserciones débiles o pruebas que siempre pasan.

Cuándo utilizarlo

Lógica crítica de negocio. Ejemplo: verificar que las pruebas detecten un límite de aprobación incorrecto.

02

De la idea a la práctica

Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.

En el Radar compartido: Trial (valoración de la edición aportada).

Cómo funciona

La herramienta cambia operadores, constantes o retornos y ejecuta pruebas. Un mutante eliminado provoca un fallo; uno superviviente puede revelar una validación ausente.

Ejemplo de uso

Cambiar una condición monto <= limite por monto < limite. Si ninguna prueba falla, añadir un caso exactamente en el límite y verificar tanto la decisión como sus efectos.

Puntuación de mutación

mutation score = mutantes eliminados / (mutantes totales − equivalentes)

A diferencia de la cobertura de líneas, que solo indica qué código se ejecutó, la puntuación de mutación indica qué cambios de comportamiento se detectaron. Una suite con 95 % de cobertura y aserciones débiles puede tener un 40 % de mutation score.

Operadores habituales

Operador Ejemplo
Límites condicionales < → <=
Negación de condiciones == → !=
Matemáticos + → -, * → /
Valores de retorno return x → return 0 / null / true
Eliminación de llamadas auditoria.registrar(e) → (nada)
Incrementos i++ → i--

Herramientas por lenguaje

Lenguaje Herramienta Ejecución
Java / Kotlin PIT mvn org.pitest:pitest-maven:mutationCoverage
JavaScript / TypeScript, C#, Scala Stryker npx stryker run
Python mutmut, Cosmic Ray mutmut run
Rust cargo-mutants cargo mutants

Configuración de PIT con umbral

<plugin>
  <groupId>org.pitest</groupId>
  <artifactId>pitest-maven</artifactId>
  <configuration>
    <targetClasses><param>com.krediya.cartera.dominio.*</param></targetClasses>
    <mutators><mutator>STRONGER</mutator></mutators>
    <mutationThreshold>75</mutationThreshold>
    <withHistory>true</withHistory>      <!-- análisis incremental entre ejecuciones -->
    <threads>4</threads>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.pitest</groupId>
      <artifactId>pitest-junit5-plugin</artifactId>
    </dependency>
  </dependencies>
</plugin>

Leer los supervivientes

Superviviente Probable causa Acción
< → <= en un límite Falta caso en el valor exacto Prueba de frontera
Eliminar llamada a notificar() No se verifica el efecto Aserción sobre el mock o el evento
return saldo → return 0 La prueba no comprueba el valor Aserción sobre el resultado
Cambio en un log.debug Código sin comportamiento observable Excluir
Mutante equivalente (mismo comportamiento) No hay prueba posible Marcar y excluir

Estrategia de adopción

Empieza por el dominio crítico (cálculo de intereses, reglas de aprobación), ejecuta en modo incremental sobre el código cambiado en cada PR y un análisis completo nocturno. Fija el umbral a partir de la línea base actual y súbelo gradualmente. Es también una excelente forma de evaluar pruebas escritas por agentes de IA: detecta pruebas que pasan sin comprobar nada.

Criterios de implementación

Empezar por módulos críticos con Stryker, PIT o cargo-mutants. Controlar duración, filtrar equivalentes justificados y priorizar mejoras de las aserciones sobre alcanzar una cifra arbitraria.

Continúa en las fuentes

Documentación oficial para verificar detalles y explorar más.