¿Qué son las pruebas de mutación? (Ejemplo)
⚡ Resumen inteligente
Las pruebas de mutación introducen deliberadamente pequeños fallos en el código fuente y, a continuación, ejecutan el conjunto de pruebas existente contra cada versión defectuosa, midiendo si esas pruebas son lo suficientemente sólidas como para detectar el cambio.
¿Qué son las pruebas de mutación?
Prueba de mutación Es un tipo de prueba de software en la que se modifican ciertas instrucciones del código fuente para comprobar si los casos de prueba son capaces de encontrar errores en dicho código. El objetivo de las pruebas de mutación es garantizar la calidad de los casos de prueba en términos de robustez, de modo que fallen ante el código fuente modificado.
El cambio realizado en un programa mutante debe mantenerse extremadamente pequeño, de modo que no afecte el objetivo general del programa. Las pruebas de mutación también se denominan estrategia de pruebas basada en fallos, porque implican crear deliberadamente un fallo en el programa. Es una forma de Blanco Box Pruebas que se aplica principalmente durante Examen de la unidad.
Las pruebas de mutación fueron propuestas en 1971 en un trabajo estudiantil por Richard Lipton y formalizadas en el artículo de 1978 "Sugerencias sobre la selección de datos de prueba" por DeMillo, Lipton y Sayward. Perdió impulso debido al costo computacional de la época y desde entonces ha recuperado terreno para lenguajes como Java, C#, Python, JavaScript y XML.
¿Cómo ejecutar las pruebas de mutación?
A continuación se detallan los pasos para realizar pruebas de mutación, también conocidas como análisis de mutación:
Paso 1: Se introducen fallos en el código fuente del programa mediante la creación de múltiples versiones llamadas mutantes. Cada mutante debe contener un único fallo, y el objetivo es provocar que la versión mutante falle, lo que demuestra la eficacia de los casos de prueba.
Paso 2: Los casos de prueba se aplican al programa original y también al programa mutante. Caso de prueba debe ser adecuado y se modifica para detectar fallas en un programa.
Paso 3: Compara los resultados del programa original y del programa modificado.
Paso 4: Si el programa original y el programa mutante generan resultados diferentes, el mutante se desactiva mediante el caso de prueba. Por lo tanto, el caso de prueba es suficientemente bueno para detectar el cambio entre el programa original y el mutante.
Paso 5: Si el programa original y el programa mutante generan el mismo resultado, el mutante se mantiene activo. En tales casos, es necesario crear casos de prueba más eficaces que eliminen todos los mutantes.
El diagrama a continuación tracson los mismos cinco pasos, desde el programa original, pasando por la generación de mutantes, hasta el veredicto de muerte o supervivencia.
¿Cómo crear programas mutantes?
Una mutación no es más que un único cambio sintáctico en una instrucción del programa. Cada programa mutado debe diferir del programa original en exactamente una mutación.
| programa original | Programa mutante |
| Si (x>y) Imprimir "Hola" otro Imprimir "Hola" |
Si (x Imprimir "Hola" otro Imprimir "Hola" |
En el par anterior, solo cambió el operador de comparación, pero un caso de prueba donde x es mayor que y ahora imprime "Hi" en lugar de "Hello". La ilustración muestra esa única modificación sintáctica.
¿Qué cambiar en un Programa Mutante?
Existen diversas técnicas que pueden utilizarse para generar programas mutantes. Las tres familias que se describen a continuación abarcan la mayoría de los operadores de mutación que incluyen las herramientas.
| Operaoperadores de reemplazo nd | Operadores de modificación de expresiones | Operadores de modificación de sentencias |
| Reemplazar el operando por otro operando (x por y, o y por x) o por un valor constante. | Reemplazar un operador, o insertar un nuevo operador, en una instrucción de programa. | Las declaraciones programáticas se modifican para crear programas mutantes. |
| Ejemplo: Si (x>y) reemplaza los valores x e y Si(5>y) reemplaza x por la constante 5 |
Ejemplo: Si(x==y) Podemos reemplazar == con >= y tener el programa mutante como If(x>=y) e insertando ++ en la declaración Si(x==++y) |
Ejemplo: Eliminar la parte else en una declaración if-else Elimine toda la instrucción if-else para comprobar cómo se comporta el programa. |
Algunos ejemplos de operadores de mutación:
- Reemplazo de etiqueta IR a
- Reemplazo de declaración de devolución
- Eliminación de declaraciones
- Inserción de operadores unarios (como – y ++)
- Reemplazo del conector lógico
- Reemplazo de nombre de matriz comparable
- Eliminar la parte "else" de una instrucción if-else.
- Agregar o reemplazar operadores
- Reemplazo de declaración cambiando los datos.
- Modificación de datos para las variables
- Modificación de tipos de datos en el programa.
OperaLos tors que tocan una condición de contorno sobreviven con mayor frecuencia, por lo que los resultados de la mutación frecuentemente apuntan a brechas en análisis de valor límite.
Tipos de pruebas de mutación
In Ingeniería de SoftwareLas pruebas de mutación se clasifican fundamentalmente en tres tipos: mutación de sentencias, mutación de valores y mutación de decisiones.
- Mutación de declaración – Se corta, pega o elimina una instrucción, por lo que el resultado puede ser la eliminación de algunas líneas de código.
- Mutación de valor – Se modifican los valores de los parámetros y constantes principales, por ejemplo, cambiando un límite de bucle o un umbral.
- Mutación de decisión – Las instrucciones de control se modifican, por ejemplo flipping un operador relacional o la negación de una condición.
Las herramientas agrupan sus operadores bajo estos tres encabezados, por lo que la familia que produjo un mutante superviviente le indica al probador qué tipo de aserción falta. Un mutante de decisión superviviente generalmente marca una rama no probada, que se superpone con prueba de bucle.
Automatización de pruebas de mutaciones
Las pruebas de mutación son extremadamente laboriosas y complicadas de realizar manualmente, por lo que se recomienda utilizar herramientas de automatización, que además reducen los costos. Una herramienta de mutación recopila los mutantes, programa las ejecuciones, registra qué mutante eliminó cada prueba fallida e informa el resultado.
Lista de herramientas disponibles:
- Stryker — un marco de pruebas de mutación de código abierto con ediciones para JavaGuión y TypeScript (StrykerJS), C# y .NET (Stryker.NET) y Scala (Stryker4s).
- PIT, también escrito PITest — un sistema de prueba de mutaciones para Java y la JVM que modifica el código de bytes compilado y se integra con Maven y Gradle construye junto a JUnit.
Ambos se ejecutan como un paso de compilación, por lo que pertenecen al mismo. integración continua oleoducto como el resto del pruebas de automatización sucesivamente.
Puntuación de mutación
La puntuación de mutación se define como el porcentaje de mutantes muertos con respecto al número total de mutantes.
Puntuación de mutación = (Mutantes asesinados / Número total de mutantes) * 100
La fórmula se muestra a continuación en el formato en que la mayoría de las herramientas la presentan.
Los casos de prueba se describen como mutación adecuada cuando la puntuación alcanza el 100 por ciento. En la práctica, el denominador debe excluir mutantes equivalentes — mutantes cuya sintaxis modificada se comporta exactamente igual que la original, por lo que ninguna prueba puede eliminarlos. Por lo tanto, las herramientas informan sobre los mutantes eliminados divididos por los mutantes eliminados más los mutantes no equivalentes supervivientes, y permiten que el probador marque los equivalentes.
Los resultados experimentales han demostrado que las pruebas de mutación son una forma eficaz de medir la idoneidad de los casos de prueba. El principal inconveniente es el coste de generar los mutantes y ejecutar cada caso de prueba contra cada uno de ellos.
Pruebas de mutación vs. Code Global
Alto prueba de cobertura Esto no demuestra la solidez de las pruebas. La cobertura de líneas y ramas registra qué instrucciones se ejecutaron, no si se verificó algo posteriormente, por lo que una prueba que llama a un método y no afirma nada sigue considerándose cubierta. Las pruebas de mutación solucionan este problema, ya que un mutante solo muere cuando una aserción falla realmente.
| Aspecto | Code cobertura | Puntuación de mutación |
| que mide | ¿Qué líneas o ramas ejecutaron las pruebas? | ¿Qué fallos inyectados detectaron las pruebas? |
| Sensible a las afirmaciones | No, una prueba sin aserciones también añade cobertura. | Sí, un mutante sobrevive cuando ninguna afirmación falla. |
| Coste de una carrera | Una prueba instrumentada | Una prueba por mutante superviviente, hasta ahora más lento |
| Uso típico | Una puerta rápida en cada compromiso | Una revisión periódica más exhaustiva de los módulos críticos. |
| Modo de fallo | Cobertura del 100 por ciento sin verificación real. | Mutantes equivalentes que nunca pueden ser eliminados |
Las dos métricas son complementarias. La cobertura nombra el código que nunca se alcanzó; la puntuación de mutación nombra el código alcanzado que nunca se comprobó. Ambas alimentan la misma proceso de gestión de defectosjunto con medidas como densidad de defectos.
Ventajas de las pruebas de mutación
Las siguientes son las ventajas de las pruebas de mutación:
- Es un método eficaz para lograr una alta cobertura del programa fuente.
- Prueba el conjunto de pruebas en sí mismo, lo que ningún otro técnica de prueba de software lo hace directamente.
- Las pruebas de mutación proporcionan un buen nivel de detección de errores al desarrollador de software.
- Este método descubre ambigüedades en el código fuente y tiene la capacidad de revelar fallos que las ejecuciones ordinarias nunca detectan.
- Los mutantes supervivientes son susceptibles de acción: cada uno nombra una línea específica y un cambio específico que el conjunto de pruebas no detectó.
- Los clientes se benefician de estas pruebas al recibir un sistema más fiable y estable.
Desventajas de las pruebas de mutación
Por otro lado, las siguientes son las desventajas de las pruebas de mutación:
- Las pruebas de mutación son extremadamente costosas y requieren mucho tiempo, ya que es necesario generar y compilar una gran cantidad de programas mutantes.
- Dado que requiere mucho tiempo, se puede afirmar que estas pruebas no se pueden realizar sin una herramienta de automatización.
- Cada mutante se somete al mismo número de casos de prueba que el programa original, por lo que es necesario ejecutar una gran cantidad de mutantes contra todo el conjunto de pruebas.
- Los mutantes equivalentes no pueden ser eliminados mediante ninguna prueba, y separarlos de los supervivientes genuinos generalmente requiere una revisión manual.
- Debido a que el método modifica el código fuente, no es aplicable a Negro Box Pruebas.
¿Cuándo utilizar las pruebas de mutación?
El perfil de costos anterior implica que las pruebas de mutación rara vez se ejecutan en todo el código fuente con cada confirmación. Se amortizan cuando un fallo no detectado es costoso y el código bajo prueba es lo suficientemente pequeño como para mutar rápidamente.
- Lógica crítica para la seguridad o lógica financiera — cálculo de pagos, normas fiscales y comprobaciones de autorización, donde una respuesta errónea silenciosa puede ser peor que un fallo del sistema.
- Suites con cobertura sospechosamente alta — cuando la cobertura se acerca al 100 por ciento, pero aún así se escapan algunos defectos.
- Se está refactorizando el código heredado. — Los resultados de las mutaciones revelan si las pruebas existentes detectarían una regresión.
- Bibliotecas y componentes compartidos — un fallo en un reutilizado componente se multiplica entre todas las personas que llaman.
- Equipos practicando desarrollo basado en pruebas — La puntuación comprueba que las pruebas escritas previamente realizan un trabajo real.
Por lo general, no vale la pena trabajar con prototipos desechables, con código generado o con poco código auxiliar sin lógica de ramificación, o con conjuntos de pruebas dominados por la lentitud. pruebas de integración que ya requieren horas para una sola pasada.
Por lo tanto, la mayoría de los equipos limitan la ejecución a los archivos modificados, establecen un umbral para los módulos que importan y dejan que el resto de los equipos... pruebas de regresión La suite lleva el resto de la ciclo de vida de las pruebas de software.



