Las pruebas de mutación (o análisis de la mutación o mutaciones programa ) se utiliza para diseñar nuevas pruebas de software y evaluar la calidad de las pruebas de software existentes. Las pruebas de mutación implican modificar un programa en pequeñas formas. [1] Cada versión mutada se llama mutante y las pruebas detectan y rechazan mutantes haciendo que el comportamiento de la versión original difiera del mutante. A esto se le llama matar al mutante. Los conjuntos de pruebas se miden por el porcentaje de mutantes que matan. Se pueden diseñar nuevas pruebas para matar mutantes adicionales. Los mutantes se basan en operadores de mutación bien definidosque imitan errores de programación típicos (como usar el operador incorrecto o el nombre de variable) o fuerzan la creación de pruebas valiosas (como dividir cada expresión por cero). El propósito es ayudar al evaluador a desarrollar pruebas efectivas o localizar debilidades en los datos de prueba utilizados para el programa o en secciones del código a las que rara vez o nunca se accede durante la ejecución . La prueba de mutación es una forma de prueba de caja blanca . [2] [3]
Introducción
La mayor parte de este artículo trata sobre la "mutación del programa", en la que se modifica el programa. Una definición más general de análisis de mutaciones es el uso de reglas bien definidas definidas en estructuras sintácticas para realizar cambios sistemáticos en los artefactos de software. [4] El análisis de mutaciones se ha aplicado a otros problemas, pero generalmente se aplica a las pruebas. Por lo tanto, las pruebas de mutación se definen como el uso del análisis de mutaciones para diseñar nuevas pruebas de software o para evaluar las pruebas de software existentes. [4] Por lo tanto, el análisis y las pruebas de mutaciones se pueden aplicar para diseñar modelos, especificaciones, bases de datos, pruebas, XML y otros tipos de artefactos de software, aunque la mutación del programa es la más común. [5]
Descripción general
Se pueden crear pruebas para verificar la corrección de la implementación de un sistema de software dado, pero la creación de pruebas aún plantea la cuestión de si las pruebas son correctas y cubren suficientemente los requisitos que han originado la implementación. [6] (Este problema tecnológico es en sí mismo una instancia de un problema filosófico más profundo llamado " Quis custodiet ipsos custodes? " ["¿Quién vigilará a los guardias?"].) La idea es que si se introduce un mutante sin ser detectado por el suite de pruebas, esto indica que el código que había sido mutado nunca se ejecutó (código muerto) o que la suite de pruebas no pudo localizar las fallas representadas por el mutante.
Para que esto funcione a cualquier escala, se suele introducir una gran cantidad de mutantes, lo que lleva a la compilación y ejecución de un número extremadamente grande de copias del programa. Este problema del costo de las pruebas de mutación había reducido su uso práctico como método de prueba de software. Sin embargo, el mayor uso de lenguajes de programación orientados a objetos y marcos de pruebas unitarias ha llevado a la creación de herramientas de prueba de mutaciones que prueban partes individuales de una aplicación.
Metas
Los objetivos de las pruebas de mutación son múltiples:
- identificar fragmentos de código débilmente probados (aquellos para los que no se matan mutantes) [1]
- identificar pruebas débiles (aquellas que nunca matan mutantes) [7]
- calcular la puntuación de mutación, [4] la puntuación de mutación es el número de mutantes muertos / número total de mutantes.
- aprender sobre la propagación de errores y la infección de estado en el programa [8]
Historia
La prueba de mutación fue propuesta originalmente por Richard Lipton como estudiante en 1971, [9] y desarrollada y publicada por primera vez por DeMillo, Lipton y Sayward. [1] La primera implementación de una herramienta de prueba de mutaciones fue realizada por Timothy Budd como parte de su trabajo de doctorado (titulado Análisis de mutaciones ) en 1980 de la Universidad de Yale . [10]
Recientemente, con la disponibilidad de una potencia informática masiva, ha habido un resurgimiento del análisis de mutaciones dentro de la comunidad informática, y se ha trabajado para definir métodos de aplicación de pruebas de mutación a lenguajes de programación orientados a objetos y lenguajes no procedimentales como XML , SMV y máquinas de estados finitos .
En 2004, una empresa llamada Certess Inc. (ahora parte de Synopsys ) extendió muchos de los principios al dominio de la verificación de hardware. Mientras que el análisis de mutaciones solo espera detectar una diferencia en la salida producida, Certess amplía esto verificando que un verificador en el banco de pruebas realmente detectará la diferencia. Esta extensión significa que se evalúan las tres etapas de verificación, a saber: activación, propagación y detección. Llamaron a esta calificación funcional.
El fuzzing puede considerarse un caso especial de prueba de mutación. En el fuzzing, los mensajes o datos intercambiados dentro de las interfaces de comunicación (tanto dentro como entre instancias de software) se modifican para detectar fallas o diferencias en el procesamiento de los datos. Codenomicon [11] (2001) y Mu Dynamics (2005) evolucionaron conceptos de fuzzing a una plataforma de prueba de mutaciones con estado completo, completa con monitores para ejercitar a fondo las implementaciones de protocolos.
Descripción general de las pruebas de mutación
La prueba de mutación se basa en dos hipótesis. La primera es la hipótesis del programador competente . Esta hipótesis establece que la mayoría de las fallas de software introducidas por programadores experimentados se deben a pequeños errores sintácticos. [1] La segunda hipótesis se llama efecto de acoplamiento . El efecto de acoplamiento afirma que las fallas simples pueden caer en cascada o acoplarse para formar otras fallas emergentes. [12] [13]
Los mutantes de orden superior también revelan fallas sutiles e importantes, que respaldan aún más el efecto de acoplamiento. [14] [15] [7] [16] [17] Los mutantes de orden superior se habilitan mediante la creación de mutantes con más de una mutación.
La prueba de mutación se realiza seleccionando un conjunto de operadores de mutación y luego aplicándolos al programa fuente uno a la vez para cada parte aplicable del código fuente. El resultado de aplicar un operador de mutación al programa se denomina mutante . Si el conjunto de pruebas es capaz de detectar el cambio (es decir, una de las pruebas falla), se dice que el mutante ha muerto .
Por ejemplo, considere el siguiente fragmento de código C ++:
si ( a && b ) { c = 1 ; } más { c = 0 ; }
El operador de condición mutación reemplazaría &&
con ||
y producir el siguiente mutante:
si ( a || b ) { c = 1 ; } más { c = 0 ; }
Ahora, para que la prueba mate a este mutante, se deben cumplir las siguientes tres condiciones:
- Una prueba debe llegar a la declaración mutada.
- Los datos de entrada de prueba deben infectar el estado del programa al generar estados de programa diferentes para el programa mutante y el programa original. Por ejemplo, una prueba con
a = 1
yb = 0
haría esto. - El estado incorrecto del programa (el valor de 'c') debe propagarse a la salida del programa y ser verificado por la prueba.
Estas condiciones se denominan colectivamente modelo RIP . [9]
Las pruebas de mutaciones débiles (o cobertura de mutaciones débiles ) requieren que solo se satisfagan las condiciones primera y segunda. Las pruebas de mutaciones fuertes requieren que se cumplan las tres condiciones. La mutación fuerte es más poderosa, ya que garantiza que el conjunto de pruebas realmente pueda detectar los problemas. La mutación débil está estrechamente relacionada con los métodos de cobertura de código . Requiere mucha menos potencia informática para garantizar que el conjunto de pruebas satisfaga las pruebas de mutación débil que las pruebas de mutación fuerte.
Sin embargo, hay casos en los que no es posible encontrar un caso de prueba que pueda matar a este mutante. El programa resultante es conductualmente equivalente al original. Estos mutantes se denominan mutantes equivalentes .
La detección de mutantes equivalentes es uno de los mayores obstáculos para el uso práctico de las pruebas de mutación. El esfuerzo necesario para comprobar si los mutantes son equivalentes o no puede ser muy elevado incluso para programas pequeños. [18] Una revisión sistemática de la literatura de una amplia gama de enfoques para superar el Problema de Mutantes Equivalentes [19] identificó 17 técnicas relevantes (en 22 artículos) y tres categorías de técnicas: detección (DEM); sugiriendo (SEM); y evitar la generación de mutantes equivalentes (AEMG). El experimento indicó que la mutación de orden superior en general y la estrategia de JudyDiffOp en particular proporcionan un enfoque prometedor para el problema de mutantes equivalentes.
Operadores de mutación
Los investigadores han explorado muchos operadores de mutación. A continuación, se muestran algunos ejemplos de operadores de mutación para lenguajes imperativos:
- Eliminación de declaración
- Duplicación o inserción de declaraciones, p. Ej.
goto fail;
[20] - Reemplazo de subexpresiones booleanas con verdadero y falso
- La sustitución de algunas operaciones aritméticas con los demás, por ejemplo,
+
con*
,-
con/
- Reemplazo de algunas relaciones booleanas con otras, por ejemplo ,
>
con y>=
==
<=
- Reemplazo de variables por otras del mismo ámbito (los tipos de variables deben ser compatibles)
- Eliminar el cuerpo del método, [21] implementado en Pitest [22]
Estos operadores de mutación también se denominan operadores de mutación tradicionales. También hay operadores de mutación para lenguajes orientados a objetos, [23] para construcciones concurrentes, [24] objetos complejos como contenedores, [25] etc. Los operadores para contenedores se denominan operadores de mutación a nivel de clase . Por ejemplo, la herramienta muJava ofrece varios operadores de mutación a nivel de clase, como Cambio de Modificador de Acceso, Inserción de Operador de Tipo Cast y Eliminación de Operador de Tipo Cast. También se han desarrollado operadores de mutación para realizar pruebas de vulnerabilidad de seguridad de programas. [26]
Ver también
- Bebugging (o siembra de fallas)
- Prueba de cordura
- Inyección de fallas
Referencias
- ^ a b c d Richard A. DeMillo, Richard J. Lipton y Fred G. Sayward. Sugerencias sobre la selección de datos de prueba: ayuda para el programador en ejercicio. Computadora IEEE, 11 (4): 34-41. Abril de 1978.
- ^ Ostrand, Thomas (2002), "Prueba de caja blanca" , Enciclopedia de ingeniería de software , Sociedad americana del cáncer, doi : 10.1002 / 0471028959.sof378 , ISBN 978-0-471-02895-6, consultado el 16 de marzo de 2021
- ^ Misra, S. (2003). "Evaluación de cuatro metodologías de cobertura de prueba de caja blanca" . CCECE 2003 - Conferencia Canadiense de Ingeniería Eléctrica e Informática. Hacia una tecnología solidaria y humana (Cat. No.03CH37436) . Montreal, Que., Canadá: IEEE. 3 : 1739-1742. doi : 10.1109 / CCECE.2003.1226246 . ISBN 978-0-7803-7781-3.
- ^ a b c Paul Ammann y Jeff Offutt. Introducción a las pruebas de software. Prensa de la Universidad de Cambridge, 2008.
- ^ Jia, Yue; Harman, Mark (septiembre de 2009). "Un análisis y estudio del desarrollo de las pruebas de mutación" (PDF) . Centro CREST, King's College de Londres , Informe técnico TR-09-06 . Archivado desde el original (PDF) el 4 de diciembre de 2017.
- ^ Dasso, Arístides; Funes, Ana (2007). Verificación, Validación y Pruebas en Ingeniería de Software . Idea Group Inc. ISBN 1591408512.
- ^ a b Smith B., "Guiar el aumento de un conjunto de pruebas automatizado mediante análisis de mutaciones", 2008
- ^ Musco, Vincenzo; Monperrus, Martin; Preux, Philippe (2016). "Inferencia gráfica basada en mutaciones para la localización de fallas" . doi : 10.1109 / SCAM.2016.24 . Cite journal requiere
|journal=
( ayuda ) - ^ a b Mutación 2000: Uniendo lo ortogonal por A. Jefferson Offutt y Roland H. Untch.
- ^ Tim A. Budd, Análisis de mutaciones de los datos de prueba del programa. Tesis de doctorado, Universidad de Yale New Haven CT, 1980.
- ^ Kaksonen, Rauli. Un método funcional para evaluar la seguridad de la implementación de protocolos (tesis de licenciatura). Espoo. 2001.
- ^ A. Jefferson Offutt. 1992. Investigaciones del efecto de acoplamiento de pruebas de software. ACM Trans. Softw. Ing. Methodol. 1, 1 (enero de 1992), 5-20.
- ^ AT Acree, TA Budd, RA DeMillo, RJ Lipton y FG Sayward, "Análisis de mutaciones", Instituto de tecnología de Georgia, Atlanta, Georgia, Informe técnico GIT-ICS-79/08, 1979.
- ^ Yue Jia; Harman, M., "Construyendo fallas sutiles usando pruebas de mutación de orden superior", Análisis y manipulación del código fuente, 2008 Octava conferencia de trabajo internacional de IEEE, vol., No., Págs. 249,258, 28-29 de septiembre de 2008
- ^ Maryam Umar, "Una evaluación de los operadores de mutación para mutantes equivalentes", Tesis de MS, 2006
- ^ Polo M. y Piattini M., "Pruebas de mutación: aspectos prácticos y análisis de costes", Universidad de Castilla-La Mancha (España), Presentación, 2009
- ^ Anderson S., "Pruebas de mutación", Universidad de Edimburgo, Escuela de Informática, Presentación, 2011
- ^ PG Frankl, SN Weiss y C. Hu. Pruebas de uso múltiple versus pruebas de mutación: una comparación experimental de efectividad. Revista de sistemas y software , 38: 235–253, 1997.
- ^ Superar el problema del mutante equivalente: una revisión sistemática de la literatura y un experimento comparativo de la mutación de segundo orden por L. Madeyski, W. Orzeszyna, R. Torkar, M. Józala. Transacciones IEEE sobre ingeniería de software
- ^ Error de SSL / TLS de Apple por Adam Langley.
- ^ Niedermayr, Rainer; Juergens, Elmar; Wagner, Stefan (14 de mayo de 2016). "¿Me dirán mis pruebas si rompo este código?" . Actas del Taller Internacional sobre Evolución y Entrega Continua de Software . CSED '16. Austin, Texas: Asociación de Maquinaria de Computación: 23–29. arXiv : 1611.07163 . doi : 10.1145 / 2896941.2896944 . ISBN 978-1-4503-4157-8.
- ^ Vera-Pérez, Oscar Luis; Monperrus, Martin; Baudry, Benoit (2018). "Descartes: un motor PITest para detectar métodos pseudoprobados: demostración de herramientas" . Actas de la 33a Conferencia Internacional ACM / IEEE sobre Ingeniería de Software Automatizada - ASE 2018 . Montpellier, Francia: ACM Press: 908–911. arXiv : 1811.03045 . doi : 10.1145 / 3238147.3240474 .
- ^ MuJava: un sistema de mutación de clases automatizado de Yu-Seung Ma, Jeff Offutt y Yong Rae Kwo.
- ^ Operadores de mutación para Java concurrente (J2SE 5.0) por Jeremy S. Bradbury, James R. Cordy, Juergen Dingel.
- ^ Mutación de objetos Java por Roger T. Alexander, James M. Bieman, Sudipto Ghosh, Bixia Ji.
- ^ Pruebas basadas en mutaciones de desbordamientos de búfer, inyecciones de SQL y errores de cadena de formato por H. Shahriar y M. Zulkernine.