Alejandría

Busca en Alejandría

Herramientas

cargo-mutants

Herramienta de mutation testing para comprobar la capacidad de detección de pruebas en Rust.

01

En pocas palabras

Herramienta de mutation testing para comprobar la capacidad de detección de pruebas en Rust.

Qué problema resuelve

Pruebas que ejecutan funciones pero no detectan resultados incorrectos.

Cuándo utilizarlo

Bibliotecas Rust y lógica de dominio. Ejemplo: evaluar límites de una función de cálculo.

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

Introduce cambios temporales como sustitución de retornos u operadores y observa qué pruebas fallan. Reporta mutantes detectados, supervivientes y resultados no concluyentes.

Ejemplo de uso

Ejecutar cargo mutants sobre una copia de trabajo preparada. Si sobrevive un cambio en una condición de descuento, añadir una prueba de frontera que compruebe el importe final.

Qué mutaciones genera

Mutación Ejemplo
Sustituir el cuerpo de una función Devolver Default::default(), 0, true, Ok(()) o vec![]
Operadores binarios + ↔ -, < ↔ <=, == ↔ !=, && ↔ `
Operadores unarios Eliminar ! o -
Brazos de match Eliminar o sustituir un brazo

Cada mutante se compila y se ejecuta la suite. Un mutante sobreviviente indica código cuyo comportamiento no está protegido por ninguna prueba.

Uso habitual

cargo install --locked cargo-mutants

cargo mutants --list                 # ver mutantes sin ejecutarlos
cargo mutants                        # ejecutar todo el árbol
cargo mutants -f src/intereses.rs    # acotar a un archivo
cargo mutants --in-diff cambios.diff # solo el código cambiado (útil en PR)
cargo mutants -j 4                   # paralelizar

Los resultados quedan en mutants.out/: caught.txt, missed.txt, timeout.txt y unviable.txt (no compila).

Leer los resultados

Estado Significado Acción
Caught Alguna prueba falla con el mutante Ninguna
Missed Todas las pruebas pasan Añadir una aserción o reconocer código sin valor
Timeout La suite no termina (bucle infinito) Suele contar como detectado; revisar timeouts
Unviable El mutante no compila Ignorar

Excluir lo que no aporta

#[mutants::skip] // logging o código defensivo sin comportamiento observable
fn registrar_auditoria(evento: &Evento) { /* … */ }

También se pueden excluir archivos o funciones en .cargo/mutants.toml (exclude_globs, exclude_re).

Integración en CI

Ejecutar todo el árbol en cada PR suele ser lento. Una estrategia equilibrada: --in-diff sobre el cambio del pull request y un recorrido completo nocturno o semanal, con sharding (--shard 1/4) en varios runners. La técnica general se describe en mutation testing.

Criterios de implementación

Partir de una suite estable y revisar equivalentes. Priorizar módulos críticos localmente y reservar recorridos completos para CI según su duración.

Continúa en las fuentes

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