You are on page 1of 156

Tcnicas combinatorias

de {nutacin para test!


do sistemas softwa
taedjJso*
m ay .** black
.team s y s te m
ices?

ios
'O 10IC 0100 10101
lOOlC 010101010 '
10010J 11011101
10K 01 101.01 C
1 01C
lO O li
U01U0

n icot

Macario Polo Usaola


Beatriz P r e z Lamancha
Pedro Reales Mateo

Ra-Ma
INDICE

AUTORES...........................................................................................................................11
PREFACIO..........................................................................................................................13
PRLOGO..........................................................................................................................15
CAPTULO 1. CONCEPTOS FUNDAMENTALES...................................................... 19
1.1 IMPOSIBILIDAD DE LAS PRUEBAS EXHAUSTIVAS........................................ 19
1.2 ERROR, DEFECTO O FALTA Y FALLO................................................................20
1.3 CASO DE PRUEBA.................................................................................................. 21
1.4 OBJETIVO DE LAS PRUEBAS............................................................................... 21
CAPTULO 2. NIVELES DE PRUEBA...........................................................................23
2.1 PRUEBAS DE CAJA NEGRA.................................................................................. 23
2.2 PRUEBAS ESTRUCTURALES O DE CAJA BLANCA..........................................25
2.3 PRUEBAS UNITARIAS........................................................................................... 27
2.4 PRUEBAS DE INTEGRACIN............................................................................... 27
2.5 PRUEBAS DE SISTEMA......................................................................................... 28
2.6 EJERCICIOS............................................................................................................. 28
CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS
SOFTWARE........................................................................................................................ 31
3.1 CRITERIOS DE COBERTURA.................................................................................31
3.2 UTILIDAD DE LOS CRITERIOS DE COBERTURA..............................................32
3.3 UN POSIBLE MODELO DE TRABAJO...................................................................32
3.4 CRITERIOS DE COBERTURA PARA CDIGO FUENTE.....................................34
3.4.1 Cobertura de sentencias...................................................................................... 34
3.4.2 Cobertura de decisiones, de ramas o de todos los arcos.....................................36
8 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

3.4.3 Cobertura de condiciones....................................................................................36


3.4.4 Cobertura de condiciones/decisones (Decision/Condition coverage o DCC) ...37
3.4.5 Cobertura mltiple de condiciones (M ultiple C ondition Coverage, MCC)....... 39
3.4.6 Cobertura modificada de condiciones/decisiones ( M odified C ondition/
D ecision C overage , MC/DC)..............................................................................39
3.5 CRITERIOS DE COBERTURA PARA MQUINAS DE ESTADO........................42
3.5.1 Cobertura de estados.......................................................................................... 43
3.5.2 Cobertura de transiciones................................................................................... 43
3.5.3 Cobertura de pares de transiciones......................................................................44
3.5.4 Cobertura de secuencia completa....................................................................... 45
3.6 EJERCICIOS............................................................................................................. 45
CAPTULO 4. VALORES DE PRUEBA.........................................................................49
4.1 CLASES O PARTICIONES DE EQUIVALENCIA..................................................49
4.2 VALORES LMITE (B O U N D A R Y V A L U E S) ............................................................51
4.3 CONJETURA DE ERRORES (E R R O R -G U E SSIN G ) ................................................52
4.4 APLICACIN DE LAS TCNICAS AL CONJUNTO DE DATOS DE SALIDA ... 53
4.5 CRITERIOS DE COBERTURA PARA VALORES DE PRUEBA...........................54
4.5.1 Cada uso (each use) .............................................................................................55
4.5.2 Todos los pares (pairw ise ) ..................................................................................55
4.5.3 Todas las tupias de n elementos (n -w ise) ............................................................56
4.6 EJERCICIOS............................................................................................................. 57
CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN
DE CASOS DE PRUEBA...................................................................................................59
5.1 ESTRUCTURA DE UN CASO DE PRUEBA...........................................................59
5.1.1 Ejemplo.............................................................................................................. 60
5.2 EL ORCULO.......................................................................................................... 64
5.2.1 Obtencin de casos de prueba con orculos a partir de mquinas de estado.....65
5.3 ESTRATEGIAS DE COMBINACIN......................................................................69
5.3.1 Todas las combinaciones (A ll com binations) ......................................................70
5.3.2 Cada eleccin (Each c h o ic e ) ...............................................................................74
5.3.3 AETG (A utom atic E fficient Test G en era to r) ......................................................75
5.3.4 PROW (P airw ise w ith Restrictions, O rder a n d W eig h t) ....................................79
5.3.5 Antirandom......................................................................................................... 84
5.3.6 Algoritmo del peine (C o m b ) ...............................................................................86
5.3.7 Algoritmos aleatorios......................................................................................... 86
5.4 CTWEB, UNA APLICACIN WEB PARA TESTIN G COMBINATORIO.............86
5.5 EJERCICIOS............................................................................................................. 89
RA-MA INDICE 9

CAPTULO 6. PRUEBAS MEDIANTE MUTACIN...................................................91


6.1 CONCEPTOS IMPORTANTES................................................................................91
6.2 OPERADORES DE MUTACIN..............................................................................94
6.3 PRINCIPIOS DE LA MUTACIN............................................................................96
6.4 EL PROCESO DE PRUEBAS UTILIZANDO MUTACIN....................................97
6.5 TCNICAS DE REDUCCIN DE COSTES EN EL TESTING CON
MUTACIN.............................................................................................................. 99
6.5.1 Reduccin de costes en la generacin de mutantes........................................... 100
6.5.2 Reduccin de costes en la ejecucin................................................................. 103
6.5.3 Reduccin de costes en el anlisis de resultados.............................................. 108
6.5.4 Herramientas de mutacin................................................................................. 109
6.5.5 Comparativa de herramientas de mutacin para el lenguaje Java.................... 111
CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN..... 117
7.1 LICENCIA................................................................................................................ 117
7.2 SOFTWARE EXTERNO...........................................................................................118
7.2.1 ASM.................................................................................................................. 118
7.2.2 JODE: Java Optimize and Decompile Environment......................................... 119
7.2.3 Una imagen del juego DOOM2........................................................................ 119
7.3 UN VISTAZO AL PROCESO DE PRUEBAS CON BACTERIO........................... 119
7.4 CONFIGURACIN Y EJECUCIN....................................................................... 120
7.4.1 Configuracin de carpetas.................................................................................122
7.4.2 Generacin de mutantes....................................................................................124
7.4.3 Seleccin de los elementos para mutar............................................................. 124
7.4.4 Seleccin de operadores de mutacin...............................................................125
7.4.5 Seleccin de opciones para la generacin de versiones.................................... 127
7.4.6 Generacin de clases y versiones mutantes...................................................... 130
7.4.7 Ejecucin de casos de prueba............................................................................132
7.5 ANLISIS DE RESULTADOS............................................................................... 134
7.5.1 Presencia de azar............................................................................................... 135
7.5.2 Enriquecimiento del test suite con nuevos casos de prueba.............................. 136
7.5.3 Testing exploratorio........................................................................................... 138
7.5.4 Ejecucin en paralelo........................................................................................140
CAPTULO 8. AUTOEVALUACIN............................................................................145
8.1 PREGUNTAS...........................................................................................................145
8.2 SOLUCIONES..........................................................................................................157
NDICE ALFABTICO...................................................................................................165
AUTORES

Macario Polo Usaola es licenciado en Informtica por la Universidad de


Sevilla y profesor titular de Lenguajes y Sistemas Informticos en la de Castilla-La
Mancha, en donde defendi su tesis doctoral. Su investigacin se ha dedicado
fundamentalmente a la automatizacin de procesos software, centrndose en la
actualidad en la del proceso de pruebas. En esta lnea, ha publicado diversos
artculos en revistas especializadas e impartido cursos en empresas y universidades.
As mismo, es autor de las novelas Tendiendo al equilibrio (1995), La ruta no
natural (2000), Fuera de ningn sitio (2009) y El pecador mudo (2010), y ha
dirigido el cortometraje Trastos viejos.

Beatriz Prez Lamancha es ingeniera en Computacin por la Universidad


de la Repblica, en Uruguay, y doctora por la de Castilla-La Mancha, en la que ha
elaborado una tesis sobre pruebas dirigidas por modelos. Es docente en la facultad
de Ingeniera de Montevideo y trabaja como consultora y lder de pruebas en el
Centro de Ensayos Software, una empresa uruguaya de extemalizacin de servicios
de pruebas del software. Su amplia experiencia le ha permitido difundir su
conocimiento en numerosos foros, as como transmitirlos en muchos cursos y
jomadas.

Pedro Reales Mateo es ingeniero en Informtica por la Universidad de


Castilla-La Mancha. Disfruta de una beca de Formacin de Profesorado
Universitario (FPU), gracias a la que trabaja en su tesis doctoral sobre pruebas
basadas en mutacin en el Instituto de Tecnologas y Sistemas de Informacin de la
UCLM. Es autor de diversos artculos en revistas y conferencias y desarrollador
principal de la herramienta Bacterio, que se presenta en este libro.
PREFACIO

Dios mo, Dios mo: todo lo hiciste perfecto, pero conmigo te pasaste.

(A. E. G., amigo de los autores).

La maravillosa perfeccin de la geometra, la correccin asombrosa de la


figura relajada del David de Miguel ngel, la belleza de tantas otras obras de arte,
la majestuosidad de muchas construcciones realizadas por el hombre o la
humorstica definicin que nuestro amigo A.E.G. hace de s mismo son casi
imposibles de conseguir en el desarrollo de grandes sistemas software: el gran
nmero de variables que se manipula en cualquier programa, la cantidad de
relaciones entre ellas, la dependencia de los sistemas respecto de otros sistemas
externos o su utilizacin por parte de otros usuarios prcticamente impiden la
implementacin de sistemas perfectos que se comporten correctamente en
cualquier circunstancia.

Aunque se han desarrollado multitud de tcnicas y metodologas para la


prueba del software, ninguna de ellas permite garantizar la ausencia absoluta de
errores, ya que resulta prcticamente imposible simular y controlar todos los
posibles escenarios que se darn en la ejecucin del sistema. La labor del tester,
por tanto, se limita a la aplicacin de su conocimiento para tratar de encontrar en el
sistema tantos errores como sea posible, de manera que pocos osarn a garantizar
que los sistemas que han probado estn 100% libres de errores.
14 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Contenidos

Este libro presenta una serie de tcnicas y buenas prcticas para la prueba
de software: tras el repaso de algunos conceptos importantes (captulos uno y dos),
se describen, en el captulo tres, algunos criterios de cobertura para diferentes tipos
de artefactos software. Si bien los criterios de cobertura no son la panacea con la
que asegurar la ausencia de errores, s que permiten estimar cuantitativamente, por
ejemplo, en qu grado se ha probado un programa.

Puesto que los criterios de cobertura tambin sirven al tester para proponer
nuevos casos de prueba del sistema, el captulo cuatro describe algunas tcnicas
para la propuesta de buenos valores de prueba que permitan incrementar la
cobertura que se alcance en el sistema. Una vez se han identificado esos valores
interesantes, el tester los combina para obtener buenos casos de prueba, a lo que
se dedica el captulo cinco.

Los captulos seis y siete constituyen la segunda parte del libro, dedicada a
las pruebas basadas en mutacin: el primero de ellos detalla la tcnica en
profundidad, presentando su terminologa, sus problemas de coste, las soluciones
que se han propuesto para reducirlos y para hacerla aplicable a nivel industrial y un
anlisis extenso de algunas herramientas. En el captulo sptimo se presenta la
herramienta Bacterio, que facilita el testing basado en mutacin.

Al final se incluye un test de autoevaluacin para el que se ofrecen las


respuestas correctas de forma razonada.
PROLOGO

La industria del software ya tiene casi setenta aos y, en este perodo, ha


realizado grandes avances; de hecho, el software forma parte de nuestras vidas, est
en todos los aparatos que manejamos, medios de transportes, sistemas de
telecomunicaciones, equipos mdicos, sistemas de gestin, en el arte y en cualquier
industria relacionada con el ocio y el entretenimiento. En un futuro quizs no muy
lejano, y en combinacin con la nano y la biotecnologa, formar incluso parte de
nosotros mismos...

En cualquier caso en la actualidad ya es cierto, como adverta Baijne


Stroustrup, que: Our civilization runs on software (nuestra civilizacin se ejecuta
en el software). De ah la importancia de la calidad de los productos software y de
la Ingeniera del Software. Sin embargo, comparadas con otras disciplinas (sobre
todo con ingenieras ms tradicionales), la satisfaccin de los usuarios con la
Ingeniera del Software es muy desigual. Robert X. Cringely sealaba ya hace aos
que: Si la industria automovilstica hubiera seguido el mismo desarrollo que los
ordenadores, un Rolls-Royce costara hoy 100 dlares, circulara un milln de
millas con 3,7 litros y explotara una vez al ao, eliminando a todo el que estuviera
dentro en ese momento Desafortunadamente, la situacin no ha cambiado mucho
y la calidad del software, todava en demasiados casos, brilla por su ausencia.

Un elemento vital para asegurar la calidad del software lo constituyen las


pruebas (testing), que, a pesar de ser uno de los procesos ms importantes, suele ser
de los ms descuidados, tanto en la formacin de los ingenieros informticos en las
universidades como -desafortunadamente- en la realidad cotidiana de multitud de
empresas.
16 TECNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Pero parece que algo est cambiando; si durante las dcadas de los setenta,
ochenta y noventa se conseguan pocos avances en las pruebas -el clsico libro de
G. J. Myers The art o f software testing segua (y en muchos aspectos todava sigue)
siendo el libro que explicaba casi todo lo que haba que saber para probar
software-, a partir de principios del siglo XXI, se sientan las bases para una nueva
era del testing.

De hecho, en mayo del 2002 se publica el informe The economic impacts


of inadequate inffaestructure for software testing, promovido por cl National
Institute of Standards & Technology de EE. UU, que cifraba, solo para este pas, en
casi 60.000 millones de dlares la repercusin econmica de las deficiencias en las
pruebas de software ; cifra que, en la actualidad y a nivel mundial, se ha superado
con creces. Tambin a partir del ao 2000, se publican metodologas como TMAP
o modelos de madurez como TMM, TMMI o TPI, se sientan las bases para
certificaciones -como las del International Software Testing Qualifications Board
(ISTQB)- y se empiezan a crear las factoras de testing , las oficinas de calidad,
los centros de aseguramiento de la calidad, etc., que persiguen industrializar
las pruebas de software. Incluso en estos momentos se est trabajando en
estndares internacionales para las pruebas, como la familia de normas ISO/IEC
29119.

De ah la importancia de textos como este, en el que se presentan, adems


de los conceptos fundamentales, las principales tcnicas combinatorias y de
mutacin que permiten mejorar la construccin de los casos de prueba o, lo que es
lo mismo, aumentar la probabilidad de encontrar defectos en el software. Adems,
se ofrece la herramienta Bacterio, que soporta varias de estas tcnicas y que
esperemos tenga el mismo xito evolutivo que sus homnimas biolgicas, y que
pase a engrosar el mercado de las herramientas de pruebas, cuyo crecimiento en la
actualidad es de ms del 15% anual.

El libro tambin lleva a cabo una verdadera labor de difusin de


investigaciones recientes, de las que sus autores son -en gran parte- protagonistas.
De hecho, tengo la suerte de conocer y haber podido seguir el trabajo del Dr.
Macario Polo en estos ltimos quince aos, en los que se ha convertido en una
referencia en testing, especialmente en el campo de la mutacin. Por lo que
respecta a la Dra. Beatriz Prez, a quien conozco personalmente desde hace cinco
aos, basta decir que proviene del CES (Centro de Ensayos de Software de
Uruguay), que se crea en 2004, y que es una de las organizaciones internacionales
ms importantes en proveer servicios de testing a empresas de tecnologas de la
informacin, destacando tambin por su encomiable labor evangelizadora y
docente (baste como muestra su carrera de testing ) en el mbito de las pruebas
del software. Al tercer autor, Pedro Reales, he tenido la suerte de tenerlo como
RA-MA PRLOGO 17

alumno en la Escuela Superior de Informtica de la UCLM y, sin lugar a dudas, es


una de las jvenes promesas de la investigacin en el rea de las pruebas del
software.

Confo en que el lector encuentre de utilidad este libro, que estoy


convencido de que contribuir a que el proceso de pruebas llegue a tener el papel
protagonista que le corresponde. Otra cosa diferente es, como algunos pretenden,
que se pueda industrializar totalmente de forma anloga a un proceso fabril; no
olvidemos que, segn Myers, el testing es un arte; y, como deca el pintor Ral
Soldi, "el arte nunca progresa, evoluciona".

Ciudad Real, febrero del 2012

Mario Piattini Velthuis


Captulo 1

CONCEPTOS FUNDAMENTALES

El problema fundamental respecto a la prueba de software es que no se


puede probar completamente un sistema, por lo que, en el momento de realizar las
pruebas, se deben tomar decisiones respecto a qu partes del sistema probar y el
grado de profundidad de los casos de prueba. La actitud que debe tomar la
persona frente al sistema bajo prueba no es la de demostrar que el programa
funciona correctamente, sino la de encontrarle fallos.

1.1 IMPOSIBILIDAD DE LAS PRUEBAS EXHAUSTIVAS


Para probar completamente un sistema, se deben ejercitar todos los
caminos posibles del programa que se va a probar (el PUT o SUT: program o
system under test). En rigor, para probar exhaustivamente una sencilla funcin que
devuelva la suma de dos parmetros enteros, deberamos utilizar todo el rango
posible de valores para los dos parmetros, y probando adems con todas las
combinaciones.

La prueba exhaustiva requiere probar el comportamiento de un programa


para todas las combinaciones vlidas e invlidas de todos sus posibles puntos de
entrada, y teniendo en cuenta todos los estados posibles del programa. En la
prctica esto resulta imposible, ya que el tiempo requerido es prohibitivo.
20 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

En una situacin ideal, con tiempo y recursos ilimitados, desearamos


probar un programa con todo el rango posible de datos de entrada. Incluso un
programa aparentemente simple puede tener centenares o millares de
combinaciones posibles de entrada y de salida. Crear los casos de prueba para todas
estas posibilidades no es econmicamente factible, por lo que este problema,
fundamental, tiene serias implicaciones en la economa de las pruebas, en las
suposiciones que el tester tendr que hacer sobre el programa y en la manera en la
cual se disean los casos de prueba. El objetivo debe ser maximizar la produccin
de las pruebas: esto es, maximizar el nmero de los errores encontrados por un
nmero finito y, deseablemente, pequeo, de casos de prueba1. La forma en que se
construyen y seleccionan los casos de prueba es una de las principales decisiones
que deben tomarse.

1.2 ERROR, DEFECTO O FALTA Y FALLO


En algunos libros se utilizan distintos trminos para distinguir entre la
causa de un mal funcionamiento en el sistema, que perciben los desarrolladores, y
la observacin de ese mal fncionamiento, que lo percibe el usuario del sistema.

Un error es una equivocacin cometida por una persona en cualquier


situacin de la vida; en el contexto del testing, un defecto o falta es un error
cometido al realizar alguna actividad concerniente al desarrollo del software', un
fallo es un desvo respecto al comportamiento requerido del sistema2, motivado por
la presencia de algn defecto.

Con estas definiciones, el programador introduce errores, que son


percibidos como defectos por el tester, mientras que el fallo lo detecta el usuario
por una diferencia entre el comportamiento exhibido y el esperado. No todos los
defectos corresponden a un fallo: si un trozo de cdigo defectuoso nunca se
ejecuta, el defecto nunca provocar el fallo del sistema.

La prueba puede revelar fallos, pero son los defectos los que pueden y
deben ser detectados por el tester y eliminados por el desarrollador3. No obstante, a
lo largo de este libro utilizaremos indistintamente cualesquiera de estos trminos.

1 Myers, G.J., 2004, The art o f software testing, 2nd edition, John Wiley & Sons.
2 Pfleeger, S., 2001, Software engineering, 2nd edition, Prentice Hall.
3 Bourque, P. y Dupuis, R., 2004, Guide to the software engineering body o f knowledge, SWEBOK,
IEEE Computer Society, disponible en (18 de octubre de 2010) www.swebok.org.
RA-MA CAPTULO 1. CONCEPTOS FUNDAMENTALES 21

1.3 CASO DE PRUEBA


Un caso de prueba (test case) es un conjunto de valores de entrada,
precondiciones de ejecucin, resultados esperados y poscondiciones de ejecucin,
desarrollados con un objetivo particular o condicin de prueba, tal como ejercitar
un camino de un programa particular o para verificar que se cumple un requisito
especfico4.

Un conjunto de prueba (test suite) es un conjunto de uno o ms casos de


prueba, con un propsito y una base de datos comunes, que usualmente se ejecutan
en conjunto.

Los datos de prueba (test data) son los datos que existen (por ejemplo, en
una base de datos) antes de que una prueba sea ejecutada, que se le suministran al
sistema como entrada a travs de los casos de prueba y que afectan al
funcionamiento del sistema bajo prueba5.

Uno de los aspectos a considerar al realizar pruebas es decidir cundo el


programa falla para un conjunto de datos de entrada, o sea, conocer cul es la
salida esperada del programa. Este problema es conocido como el problema del
orculo. Un orculo es cualquier agente (humano o mecnico) que decide si un
programa se comport correctamente en un caso de prueba determinado y que, por
consiguiente, produce un veredicto de "paso" o de "fallo". Existen diversas clases
de orculos, y la automatizacin del orculo puede llegar a ser muy compleja y
costosa3. El orculo ms comn es el orculo de entrada/salida, que especifica la
salida esperada para una entrada especfica6.

1.4 OBJETIVO DE LAS PRUEBAS


La prueba debe ser vista como el proceso destructivo de encontrar errores
(cuya presencia se asume) en un programa. Si el propsito del tester es verificar
que el programa funciona correctamente, entonces el tester est fallando al
conseguir su propsito cuando encuentra defectos en el programa. En cambio, si el
tester piensa que su tarea es encontrar fallos, los buscar con mayor ahnco que si
piensa que su tarea es verificar que el programa no los tiene.

4 IEEE, 1990, IEEE standard glossary of software engineering terminology. Institute of Electrical
and Electronics Engineers.
5 International Software Testing Qualifications Board, Certified Tester Foundation Level Syllabus,
2005.
6 Beizer, B., 1990, Software testing techniques, 2nd edition. Van Nostrand Reinhold Co.
22 TECNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

Si el objetivo de la prueba es encontrar errores, un caso de prueba exitoso


es uno que hace que el programa falle (es decir, que no se comporte de la forma
esperada). Por supuesto que eventualmente se puede usar la prueba para establecer
algn grado de confianza de que el programa hace lo que se supone que debe hacer
y no hace nada que no se suponga que no deba hacer.

Por tanto, la actitud del tester debe ser destructiva respecto al sistema que
est probando: debe querer que falle, debe esperar que falle y debe concentrarse en
encontrar casos de prueba que muestren sus fallos7.

7 Kaner, C., Falk, J. y Nguyen, H., 1999, Testing computer software, 2nd edition, Wiley.
Captulo 2

NIVELES DE PRUEBA

Tradicionalmente, se distinguen dos tipos bsicos de pruebas: pruebas de


caja blanca y pruebas de caja negra, que, adems, suelen subdividirse en niveles
aun ms especficos. As, las pruebas de caja blanca se aplican, normalmente, a
pruebas unitarias y a ciertas pruebas de integracin, mientras que las de caja
negra hacen referencia, en general, tanto a pruebas unitarias, como funcionales,
de integracin, de sistema e, incluso, de aceptacin.

En este captulo se presenta una breve introduccin a las pruebas de caja


blanca y negra, y se describen algunas caractersticas de los niveles de prueba.

2.1 PRUEBAS DE CAJA NEGRA


En este tipo de pruebas, el elemento que se va a probar se entiende como
una caja negra de la que solo se conocen sus entradas y sus salidas. As, al
elemento bajo prueba se le somete a una serie de datos de entrada, se observan las
salidas que produce y se determina si stas son conformes a las entradas
introducidas.

Un conocido problema que se utiliza con frecuencia en el contexto de las


pruebas de software es el de la determinacin del tipo de un tringulo, que fue
originalmente propuesto por Bertrand Myers8: adaptado a la orientacin a objetos,
se trata de probar una clase que dispone de una operacin que calcula el tipo de un

Myers, G.J., 1979, The art o f software testing, John Wiley & Sons.
24 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

tringulo segn las longitudes de los lados. Esta operacin devuelve un entero que
representa si el tringulo es equiltero, issceles, escaleno o si no es un tringulo
(porque tenga lados de longitud cero o negativa o porque la suma de dos lados sea
menor o igual a la suma del tercero). En la Figura 2.1 se muestra la estructura de la
clase tringulo, que consta de un constructor, tres operaciones set, que asignan
una longitud a cada uno de los lados del tringulo, y un mtodo getTipo, que
devuelve un entero que representa el tipo del tringulo.

Bajo un enfoque de caja negra, el punto de vista que interesa al ingeniero


de software se ilustra en las cuatro imgenes de la Figura 2.1, en las que se pasan
diferentes temas de valores a los mtodos que asignan la longitud a los lados del
tringulo (setl, setJ, setK) y luego se comprueba nicamente si el resultado
devuelto por getTipo es el correcto.

Tringulo Tringulo
Tringulo() TringuloQ
( 2 ,2 ,2 ) setl(int x) ----------EQ (2,2,3) ---------* setl(int x) IS
setJ(int y) setJ(int y)
setK(int z) setK(int z)
getTipo():int getTipo():int

Tringulo Tringulo

Tringulo() Tringulo()
(2,3,4) setl(intx) ES (2,2,4) setl(int x) NT
setJ(int y) setJ(int y)
setK(int z) setK(int z)
getTipo():int getTipo():int

Figura 2.1. El problema del tringulo, bajo un enfoque de caja negra

Como puede comprobarse, si los casos de prueba de caja negra se superan,


el ingeniero de pruebas estar seguro de que la clase bajo prueba (la class under
test, en ingls, que habitualmente se abrevia con sus siglas CUT) se comporta
correctamente para los datos de prueba utilizados en esos casos de prueba: en el
caso del tringulo issceles, por ejemplo, en la figura se comprueba que un
tringulo con longitudes 2, 2 y 3 es issceles; ahora bien, la implementacin de la
clase determinar tambin que el tringulo es issceles para lados de longitudes 2,
3 y 2? Y para 3, 2 y 2? Las pruebas deben ser tan completas como sea posible, si
bien la prueba completamente exhaustiva (comprobacin de absolutamente todo el
comportamiento del sistema o la clase para cualesquiera posibles valores de
RA-MA CAPTULO 2. NIVELES DE PRUEBA 25

entrada) es, como ya se ha comentado en el captulo anterior, normalmente


imposible.

Las pruebas de caja negra pueden aplicarse no solo a una clase o pequeo
programa, sino que son aplicables tambin a un subsistema o, incluso, al sistema
completo mediante pruebas funcionales o testing exploratorio:

En las pruebas funcionales se buscan los defectos mediante la


ejecucin de las diferentes funcionalidades del sistema. Para ejecutar
estas pruebas es necesario conocer los requisitos del sistema, ya que
los casos de prueba se disean a partir de ellos.

En el testing exploratorio no es necesario contar con los casos de


prueba antes de ejecutar las pruebas. El diseo de las pruebas se
realiza a medida que se ejecutan los propios casos de prueba,
utilizando la informacin obtenida mientras se va probando para
disear nuevas y mejores pruebas. El testing exploratorio se defne
como el aprendizaje, el diseo de casos de prueba y la ejecucin de las
pruebas de forma simultnea9. Debe tomarse tomar nota de lo que se
hizo y de lo que sucedi, con objeto de que estas pruebas sean
reproducibles, que es una de las caractersticas deseables de los casos
de prueba. El testing exploratorio es adecuado cuando hay poco
tiempo para probar el sistema.

Con el fin de alcanzar una mayor seguridad respecto a la completitud de las


pruebas, se introduce la idea de las pruebas estructurales o de caja blanca.

2.2 PRUEBAS ESTRUCTURALES O DE CAJA BLANCA


Las pruebas de caja blanca realizan, de alguna manera, un seguimiento de
las zonas del sistema que van ejecutando los casos de prueba. Si el artefacto que se
est probando es un programa, se determinan de manera concreta las instrucciones,
bloques, etc., que han sido ejecutados por los casos de prueba. En este caso, este
tipo de pruebas permiten conocer cunto cdigo se ha recorrido.

As, en el mismo problema del tringulo que comentbamos antes, el


ingeniero de pruebas se fijar ahora en el cdigo que implementa su funcionalidad

9 Bach, J., 2001, What is exploratory testing? And how it differs from scripted testing, disponible en
(18 de octubre de 2010): www.satisfice.com/articles/what_is_et.shtml.
26 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

y observar, para cada tema de entradas, el recorrido seguido por los casos de
prueba en la implementacin de la clase (Figura 2.2).

Figura 2.2. El problema del tringulo, desde un punto de vista de la caja blanca

Dependiendo, por ejemplo, de las sentencias visitadas por los casos de


prueba o (si se est considerando el diagrama de flujo del programa) dependiendo
de las ramas, caminos o nodos visitados por los casos de prueba, el ingeniero estar
ms o menos seguro de la buena, muy buena o mediana calidad tanto de los casos
de prueba como del software objeto de estudio: desde este punto de vista, son
mejores los casos de prueba que recorren mucho sistema que aquellos que
recorren poco. Existen formas muy variadas de medir la cantidad de sistema
recorrido (ese mucho o poco sistema que entrecomillbamos) mediante lo que
se llaman criterios de cobertura.

Para Cornett10, el anlisis de cobertura del cdigo es el proceso de:

Encontrar fragmentos del programa que no son ejecutados por los


casos de prueba.

Crear casos de prueba adicionales que incrementen la cobertura.

Determinar un valor cuantitativo de la cobertura (que permite, de


manera indirecta, determinar una medida de la calidad del programa).

Adicionalmcnte, el anlisis de cobertura tambin permite la identificacin


de casos de prueba redundantes, que son solo aquellos que recorren zonas del
sistema ya recorridas por otros casos, por lo que no incrementan la cobertura.

10 Cornett, S., 2002, Code coverage analysis, disponible en (18 de octubre de 2010):
www. bullseye. com/coverage. html.
RA-MA CAPTULO 2. NIVELES DE PRUEBA 27

2.3 PRUEBAS UNITARIAS


Las pruebas unitarias centran su aplicacin en lo que se denomina la
unidad de prueba, que, dependiendo del contexto, puede ser una clase, un mtodo
o un subsistema. El estndar ANSI/IEEE 1008/198711 define la unidad de prueba
de la siguiente forma:

Un conjunto de uno o ms mdulos de un programa, junto a los datos de


control asociados (por ejemplo, tablas), procedimientos de uso y procedimientos de
operacin que satisfagan las siguientes condiciones:

Todos los mdulos pertenecen a un nico programa.

Al menos uno de los mdulos nuevos o cambiados del conjunto no ha


pasado las pruebas unitarias (puesto que una unidad de prueba puede contener uno
o ms mdulos previamente probados).

El conjunto de mdulos, junto con sus datos y procedimientos asociados,


es el nico objetivo del proceso de pruebas.

En general, en orientacin a objetos se asume que la unidad de prueba es la


clase, por lo que se comprueba si el estado en el que queda la instancia de la clase
que se est probando es correcto o incorrecto para los datos que se le pasan como
entrada. En el caso de las pruebas unitarias de caja negra para un sistema orientado
a objetos, se entiende la clase como, en efecto, una caja cuyo interior no interesa: lo
nico que importa, desde este punto de vista, es el conjunto de entradas
suministradas y las salidas obtenidas.

2.4 PRUEBAS DE INTEGRACIN


Las pruebas de integracin se emplean para encontrar errores en las
unidades de prueba (que han superado sus pruebas de unidad) cuando se integran,
de manera que lo que se tiende a ir probando es la arquitectura software. Durante la
integracin, las tcnicas que ms se utilizan son las de caja negra, aunque se
pueden llevar a cabo algunas pruebas de caja blanca para asegurar que se cubren
los principales flujos de comunicacin entre las unidades12.

11 IEEE, 1987, IEEE standardfor software unit testing.


12 Pressman, R.S., 1993, Ingeniera del software, un enfoque prctico, 3a edicin, McGraw-Hill.
28 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... ORA-MA

En el contexto de la orientacin a objetos, las pruebas de integracin


observan si los mensajes que fluyen desde los objetos de una clase o componente
se envan y reciben en el orden adecuado en el objeto receptor, as como si se
producen o no en este los cambios de estado que se esperaban13.

2.5 PRUEBAS DE SISTEMA


Las pruebas de sistema tienen por objetivo encontrar errores en el sistema
(que ya ha superado las pruebas de integracin) cuando este se relaciona con su
entorno (otras mquinas, otro hardware, redes, fuentes reales de informacin, etc.).
Las pruebas funcionales forman parte de este nivel de pruebas, al igual que las
siguientes:

Pruebas de recuperacin. Consisten en forzar el fallo del software y


comprobar si la recuperacin se lleva a cabo de manera correcta,
devolviendo el sistema a un estado coherente.
Pruebas de seguridad. Intentan verificar que los mecanismos de
proteccin incorporados al sistema lo protegern, de hecho, de
penetraciones inadecuadas.
Pruebas de resistencia. Estas pruebas estn diseadas para que el
sistema requiera recursos en cantidad, frecuencia o volumen
anormales. La idea es intentar que el sistema se venga abajo por la
excesiva tensin a la que se le somete.
Pruebas de rendimiento. En sistemas de tiempo real, sistemas que
funcionan en red con mltiples usuarios o sistemas empotrados, es
inaceptable que el software proporcione las funciones requeridas fuera
de las condiciones de rendimiento exigidas.

2.6 EJERCICIOS
1. Uno de los requisitos fundamentales de los casos de prueba es la
posibilidad de que sean reejecutados tantas veces como se necesite.
Cuando el sistema utiliza una base de datos, esto puede suponer algunos
problemas, ya que los casos de prueba pueden alterar el estado de la base
de datos y dificultar la replicacin de las pruebas. Qu soluciones tiene
para ello?

13 Gallagher, L., Offutt, J. y Cincotta, A., 2006), Integration testing of object-oriented components
using finite state machines. Software Testing, Verification and Reliability, 16.
RA-MA CAPTULO 2. NIVELES DE PRUEBA 29

Se desea probar un sistema A que enviar una serie de mensajes a otro


sistema B. La interfaz de comunicacin de B, sin embargo, no la conocemos
todava. Cmo resolvera usted este problema? Indicacin: piense en la
posibilidad de aplicar el patrn adaptador (wrapper).
Captulo 3

CRITERIOS DE COBERTURA PARA


ARTEFACTOS SOFTWARE

A la hora de probar un artefacto software, al ingeniero de pruebas le


interesa conocer las porciones del sistema que sus casos de prueba estn
recorriendo. De este modo, el tester puede aadir ms casos de prueba para
buscar errores en esas zonas inexploradas. Para esto se utilizan los denominados
criterios de cobertura, que permiten conocer cuantitativamente la cantidad de
producto que se est probando. En este captulo se repasan algunos de ellos.

3.1 CRITERIOS DE COBERTURA


Cuando el tester ejecuta un conjunto de casos de prueba sobre un sistema,
aquellos avanzan a travs de ste recorriendo las regiones que correspondan a los
servicios del sistema a los que llama cada caso. La cobertura alcanzada puede
medirse de acuerdo con muy diversos criterios, unos ms estrictos y otros ms
laxos: para probar el comportamiento de una clase, por ejemplo, el tester puede
conformarse con invocar una sola vez a cada mtodo pblico (sera, claramente, un
criterio de cobertura muy pobre) o con pasar una vez por cada una de sus
sentencias (el cual es otro criterio algo ms estricto que el anterior).
C S' C \S COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

De manera general, se utilizar un criterio u otro dependiendo de alguna


caracterstica del sistema o de los elementos que lo componen, como su criticidad o
su frecuencia de uso. Por otro lado, y aunque lo habitual es utilizar criterios para
medir la cobertura de cdigo fuente, tambin se han definido criterios para otro tipo
de artefactos, como mquinas de estado, diagramas de clase o diagramas de
interaccin.

3.2 UTILIDAD DE LOS CRITERIOS DE COBERTURA


Conocer la cobertura que un conjunto de casos de prueba (test suite)
alcanza sobre el sistema que se est probando (el SUT) permite al tester determinar
las porciones del sistema que no estn siendo recorridas por los casos de prueba.
Para probar de manera ms exhaustiva el sistema, el tester debera aadir ms
casos de prueba al test suite con el objeto de que se fuerce la ejecucin del sistema
en esas zonas, cuyo comportamiento no se ha explorado.

Adems, alcanzar una cobertura alta en un sistema con un test suite que no
encuentra errores permite disponer de una garanta ms o menos alta acerca de la
calidad de dicho sistema .

3.3 UN POSIBLE MODELO DE TRABAJO


A la hora de probar un sistema o algunas de sus porciones
(funcionalidades, componentes, mdulos, subsistemas, etc.), el tester debe
determinar un criterio y un valor umbral para la cobertura que utilizar como
criterio de parada: as, por ejemplo, puede establecerse que se dejar de probar
cuando se haya recorrido el 90% de las sentencias del programa, cuando se hayan
ejecutado todos los escenarios de un cierto requisito funcional o cuando se haya
pasado por todas las transiciones de la mquina de estados que representa el
sistema.

Esta afirmacin es solo relativamente cierta, pues depende del criterio o criterios que se utilicen para
medir la cobertura.
RA-MA CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 33

Existen varios modelos de proceso para llevar a cabo las pruebas


(dependen, por ejemplo, de si el equipo de pruebas est integrado en el equipo de
desarrollo, si es un equipo independiente, si la organizacin que desarrolla el
sistema extemaliza el proceso a una tercera empresa o si se sigue alguna
metodologa como TMAP o un modelo de madurez como TPI); la Figura 3.1
muestra una propuesta de un sencillo modelo de proceso para la realizacin de
pruebas:

1. Una vez seleccionado el sistema o la porcin de l que se va a probar,


se determina a priori el valor umbral que se utilizar como criterio de
parada.

2. Una vez determinado dicho valor, se construye el conjunto de casos de


prueba (ciertamente, los casos podran haber sido construidos antes: si
se est probando el cdigo que implementa un requisito funcional,
quizs los casos ya estaban diseados desde la etapa inicial de
especificacin de requisitos) y se ejecuta sobre el sistema con el objeto
de encontrar errores.

3. Si se encuentran errores, el sistema se debe corregir por parte del


equipo de desarrollo (en este caso, si el equipo de test est separado del
equipo de desarrollo o pertenece a una tercera organizacin a la que se
ha contratado, puede que se redacte un solo informe con todos los
fallos encontrados).

4. Cuando los casos ya no encuentran errores, se mide la cobertura


alcanzada:

- Si se ha alcanzado el umbral que se preestableci, el proceso


termina, pues los casos de prueba han recorrido suficientemente el
sistema sin hallar error alguno.

- En otro caso, deben aadirse ms casos de prueba al test suite para


que se incremente la cobertura y se alcance el valor umbral, de
manera que los casos recorran tanto sistema como se deseaba.
34 TECNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

Seleccionar S (SUT)

Determinar umbral de
cobertura para S

________ ________
Construir un conjunto de
casos TC para probar S

Buscar errores en S
mediante TC C

[se encuentran errores]


Corregir S

[no se encuentran errores]

( ^ [no se alcanza umbral] ( ^


l
Medir cobertura de TC sobre C
J
K > -------- > Aadir casos a TC
K__ __y
[se alcanza umbral]

Figura 3.1. Un posible proceso de pruebas

3.4 CRITERIOS DE COBERTURA PARA CDIGO


FUENTE

3.4.1 Cobertura de sentencias


Este criterio se verifica cuando los casos de prueba recorren todas las
sentencias del programa. El lado izquierdo de la siguiente figura muestra un trozo
de cdigo que implementa el mtodo getType de la clase TriTyp, que representa el
problema de la determinacin del tipo de un tringulo (triangle-type), que ya
comentamos en la pgina 24. Se han destacado las sentencias del programa que han
sido recorridas por los casos de prueba de la derecha; las sentencias restantes no
RA-MA CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 35

han sido alcanzadas. As, si establecemos como valor umbral el recorrer el 100%
de las sentencias del programa, el tester, de acuerdo con el proceso propuesto en la
Figura 3.2, debera aadir nuevos casos de prueba al test suite.

/** import junit.framework.TestCase;


*

* ^return 1 if scalene; 2 if isosceles; public class TriTypTest extends TestCase {


* 3 if equilateral; 4 if not a triangle
*/ public void testEQUILATERO() {
public void getT y p e O { TriTyp t=new TriTypO;
t .setI (5) ;
t .setJ(5);
t.setK(5);
t .getType();
assertTrue (t.trityp==TriTyp.EQUILATERAL) ;
}

public void testISOSCELES() {


} TriTyp t=new TriTypO;
.setl(S);
if (i <= 0 II j <*= 0 II k <= 0) { t .s etJ(5);
trityp = 4; t.setK(8) ;
return; t .getType();
} assertTrue (t .trityp==TriTyp.ISOSCELES) ;
}

public void testESCALENO() {


TriTyp t=new Tr iTypO;
t .setl (4) ;
t .s etJ(5);
t .setK(8);
im m f t.getType();
) assertTrue (t.trityp==TriTyp.SCALENE) ;
}

f t nmmm public void testNOTRIANGULO() {


} if (trityp == 1 && i * j > k){ TriTyp t=new TriTypO;
t .setl (4) ;
} else if (trityp == 2 && i + k > j ) { t .setJ(5);
trityp = 2; t .setK(9);
} else if (trityp == 3 && j + k > i) { t.getType();
trityp = 2; assertTrue(t .trityp==TriTyp.NOT_A_TRIAN
GLE) ;
} else {
trityp = 4; }
} }

Figura 3.2. Cdigo recorrido (izquierda) por los casos de prueba de la derecha
36 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

3.4.2 Cobertura de decisiones, de ramas o de todos los arcos


Una decisin es una secuencia de condiciones. Una condicin es una
expresin algebraica que consta de dos expresiones relacionadas con un operador
relacional (<, >, =, >=, <= o o ) . El criterio de cobertura de decisiones (tambin
llamado de todas las ramas, all branches, o de todos los arcos, all edges) se
satisface cuando cada decisin se evala a true (verdadero) y a false (falso) al
menos una vez.

En el ejemplo del problema TriTyp {Figura 3.2), la decisin (i+j<=k ||


j+k<=i || i+k<=j) se considerar recorrida de acuerdo con este criterio, cuando se
entre a los dos bloques true y false: para recorrer la rama true, basta con hacer
cierta cualquiera de las tres condiciones de la decisin (pues son tres condiciones
separadas con or); para que sea false, debern ser tambin false las tres
condiciones.

As, para esa decisin, con los casos de prueba testNOTRIANGULO y


testESCALENO (mostrados en el lado derecho de la Figura 3.2) se verifica este
criterio, ya que ambos pasan por la decisin, el primero hacindola cierta y el
segundo hacindola falsa.

3.4.3 Cobertura de condiciones


Este criterio requiere que cada condicin de cada decisin se evale a true
y a false al menos una vez.

Volviendo al ejemplo de la decisin anterior (i+j<=k || j+k<=i || i+k<=j),


los casos de prueba habrn cumplido el criterio de condiciones cuando i+j<=k
haya sido verdadero y falso,y'+<=/ haya sido tambin verdadero y falso, e i+k<=j
haya sido tambin verdadero y falso: respecto de los valores false, el mismo caso
testESCALENO es vlido, pues las tres condiciones toman valor false. Respecto de
los valores true, un caso en el que le pasramos los valores (0, 0, 0) la cubrira en
apariencia, pero realmente la decisin sera inalcanzable porque el valor del campo
trityp sera 4 por la decisin anterior ( <= 0 ||y <= 0 || k <= 0), sealada con tres
asteriscos (***) en la Figura 3.3. Para alcanzar la decisin que nos interesa,
debemos llegar a ella con trityp=0, para lo que ni i, ni j, ni k pueden ser iguales
(dos de ellas) ni ser menores o iguales a cero. Los valores (2, 3, 5) hacen que trityp
sea cero y que se entre en la rama true de la decisin, gracias a que la primera
condicin (i+j<=k) es verdadera; para cubrir las otras dos condiciones, los casos
podran ser, respectivamente, (5, 3, 2) y (2, 3, 5). Por tanto, esa decisin sera
cubierta con el criterio de cobertura de condiciones con cuatro casos de prueba.
O RA-MA CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 37

public void getTypeO {


if (i == j) {
trityp = trityp + 1;

if (i == k) {
trityp = trityp + 2;

if (j == k) {
trityp = trityp + 3;
}
if (i <= 0 || j <= 0 || k <= 0) { ***
trityp = 4;
return;

if (trityp == 0) {
if (i + j <= k || j + k <= i || i + k <= j) {
trityp = 4;
return;
} else {
trityp = 1;
return;

Figura 3.3. Fragmento del cdigo de getTypef)

3.4.4 Cobertura de condiciones/decisiones


(Decision/Condition coverage o DCC)
Este criterio requiere que cada condicin de cada decisin se evale a true
y a false al menos una vez, y que cada decisin se evale tambin a true y a false al
menos una vez.

Aunque en apariencia pueda parecer que el cubrimiento de uno u otro


criterio pudiera implicar el cubrimiento del contrario, los siguientes contraejemplos
demuestran que no es as:

En el caso de la Tabla 3.1, se verifica el criterio de decisiones (la


decisin completa toma los valores true y false), pero no el de
condiciones, pues la condicin C no llega a tomar el valor true.

A and (B o r C )
Condiciones Decisin
A B C A and (B or C)
true true false true
false false false false
Tabla 3.1. Se verifica el criterio de decisiones, pero no el de condiciones
38 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

En la decisin de la Tabla 3.2, que consta de dos condiciones


separadas por un or exclusivo (la decisin toma valor true cuando
exclusivamente uno de los dos valores es true), se verifica el criterio
de condiciones (ambas toman los valores true y false), pero no el de
decisiones (la decisin siempre vale false).

A xor B
Condiciones Decisin
A B A xor B
true true false
false false false
Tabla 3.2. Se verifica el criterio de condiciones, pero no el de decisiones

Para que se verifiquen las condiciones/decisiones en el segundo ejemplo, el


tester debera aadir a los casos de la Tabla 3.2 o bien (true, false) o bien (false,
true), ya que se hara cierta la decisin completa. Para este mismo ejemplo, otro
posible test suite estara formado por los casos mostrados en la Tabla 3.3, ya que
cada condicin se evala a true y a false al menos una vez, y tambin la decisin
toma los dos valores booleanos.

A xor B
Condiciones Decisin
A B A xor B
true true false
true false true
false true true
Tabla 3.3. Se verifican condiciones, decisiones y condiciones/decisiones

Para el caso de la decisin (i <= 0 || j <= 0 || k <= 0) del problema del


tringulo (Figura 3.3), un posible test suite que verifica condiciones/decisiones
podra estar formado por los dos siguientes casos: (0, 0, 0) (que hace ciertas las tres
condiciones y tambin la decisin) y (7, 8, 9) (que hace falsas las tres condiciones
y tambin la decisin): sin embargo, este test suite resulta a todas luces muy pobre,
por lo que el tester debera aplicar cierta picarda a la hora de disear los casos
de prueba.
RA-MA CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 39

3.4.5 Cobertura mltiple de condiciones (Multiple Condition


Coverage, MCC)
Este criterio requiere que todas las condiciones tomen valor true y false, de
manera que se recorra la tabla de verdad completa de la decisin.

Para la misma decisin de la Tabla 3.1 se necesitaran los 23=8 casos que
se muestran en la Tabla 3.4. Este criterio de cobertura es, sin duda, el ms
completo, pero requiere un nmero de casos muy grande para cubrir cada decisin.

A and (B orC)
Condiciones Decisin
A B C A and (B or C)
truc true true true
truc true false true
true false true true
true false false false
false true true false
false true false false
false false true false
false false false false
Tabla 3.4. Cobertura de condiciones

3.4.6 Cobertura modificada de condiciones/decisiones


(Modified Condition/Decision Coverage, MC/DC).
Este criterio se verifica cuando cada posible valor de una condicin
determina la salida de la decisin al menos una vez.

Supongamos la decisin D=(A or B or C). En primer lugar, debemos


conseguir que A sirva para determinar la salida de D como true y como false,
independientemente del valor de B y de C. Para que D valga true dependiendo de
A, A debe valer true y las otras dos condiciones deben ser false', para que D valga
false gracias a A, A debe valer false, as como las otras dos condiciones. Lo mismo
podemos decir de B y C. As, cuando relacionamos dos condiciones con el
operador or, el valor false hace que no se afecte a la condicin que se est
considerando: el valor false es el denominado valor neutral del operador or.
40 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... ORA-MA

Para el caso de la decisin de la Tabla 3.4 (A and (B or Q ), sucede lo


mismo:

1. Debemos ir a la rama true gracias a la contribucin de A (para lo cual


A debe valer true) sin fijamos en las contribuciones ni de B ni de C.
Para que esto ocurra, o bien B o bien C deben valer true. Tomamos,
por ejemplo, el caso (true, true, false).
2. Debemos ir a la rama false gracias a la contribucin de A y no a la de B
ni a la de C. Para ello, hacemos A=false, B=true, C=true. El caso es,
por tanto, (false, true, true).
3. Debemos recorrer la rama true gracias a la contribucin de B, sin
fijamos ni en A ni en C. Para ello, hacemos C=false, no teniendo ms
remedio que poner A -true (porque A est separado de (B or C) con un
and). El caso de prueba, ahora, es tambin (true, true, false), que es el
que ya construimos en el punto 1.
4. Del mismo modo, debemos recorrer la rama false gracias a la
contribucin de B, sin fijamos ni en A ni en C: hacemos B=false,
A=false, B=true, quedando el caso (false, false, true).
5. Para la condicin C, tenemos que recorrer la rama true de la decisin
gracias a que C tome valor true: hacemos C=true, B=false, A=true,
quedando por tanto (true, false, true).
6. Para ir a la rama false de la decisin gracias a C, hacemos C=false,
B=true, A=false, con lo que el caso es (false, true, false).

Los casos se resumen en la Tabla 3.5: obsrvese que la decisin toma los
valores true y false gracias a los valores true y false que van tomando las
condiciones que, en la tabla, hemos denominado dominantes.

A and (B or C)
Condiciones Decisin
Condicin
A B C A and (B or C)
dominante
tme tme false tme A, B
false tme true false A
false false tme false B
tme false true tme C
false true false false C
Tabla 3.5. Casos de prueba para conseguir cobertura modificada de condicin/decisin
40 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS...______ RA-MA

Para el caso de la decisin de la Tabla 3.4 (A and (B or Q ), sucede lo


mismo:

1. Debemos ir a la rama true gracias a la contribucin de A (para lo cual


A debe valer true) sin fijamos en las contribuciones ni de B ni de C.
Para que esto ocurra, o bien B o bien C deben valer true. Tomamos,
por ejemplo, el caso (true, true, false).
2. Debemos ir a la rama false gracias a la contribucin de A y no a la de B
ni a la de C. Para ello, hacemos A=false, B=true, C=true. El caso es,
por tanto, (false, true, true).
3. Debemos recorrer la rama true gracias a la contribucin de B, sin
fijamos ni en A ni en C. Para ello, hacemos C=false, no teniendo ms
remedio que poner A =true (porque A est separado de (B or C) con un
and). El caso de prueba, ahora, es tambin (true, true, false), que es el
que ya construimos en el punto 1.
4. Del mismo modo, debemos recorrer la rama false gracias a la
contribucin de B, sin fijamos ni en A ni en C: hacemos B=false,
A=false, B=true, quedando el caso (false, false, true).
5. Para la condicin C, tenemos que recorrer la rama true de la decisin
gracias a que C tome valor true: hacemos C=true, B=false, A=true,
quedando por tanto (true, false, true).
6. Para ir a la rama false de la decisin gracias a C, hacemos C=false,
B=true, A=false, con lo que el caso es (false, true, false).

Los casos se resumen en la Tabla 3.5: obsrvese que la decisin toma los
valores true y false gracias a los valores true y false que van tomando las
condiciones que, en la tabla, hemos denominado dominantes.

A and (B or C)
Condiciones Decisin
Condicin
A B C A and (B or C)
dominante
truc truc false true A, B
false truc true false A
false false true false B
truc false true true C
false true false false C
Tabla 3.5. Casos de prueba para conseguir cobertura modificada de condicin/decisin
RA-MA CAPITULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 41

Para el ejemplo de la decisin A xor B, el mecanismo es parecido:

1. Hay que tomar true gracias a la contribucin de A y no a la de B:


tomamos el caso (true, false). Para ir a la rama false, tomamos el caso
(false, false) o (true, true), que sirve como contribucin de las dos
condiciones.

2. Hay que tomar las ramas true y fa lse gracias a B, para lo que
construimos el caso (false, true).

A xor B

Condiciones Decisin

A B A xor B

true false true

false false false

false true true

Tabla 3.6. Casos de prueba para conseguir cobertura modificada de condicin/decisin en A xor B

La decisin A xor B es equivalente a (A and not B) or (not A and B). Por


tanto, la aplicacin de este criterio de cobertura a la versin larga de la decisin
debera dar los mismos resultados. Vemoslo:

1. Para irnos a la rama true gracias a A, A debe valer true y B debe valer
false, con lo que tenemos el caso (true, false).

2. Para irnos a la rama fa lse gracias a A, A debe valer fa lse y B false, con
lo que el caso es (false, false), o bien A=true y B=true, siendo el caso
(true, true), pudindonos quedar con cualquiera de los dos. Por obtener
el mismo resultado que en la Tabla 3.6, nos quedamos con el primero.

3. Procedemos del mismo modo con B, quedndonos con (false, true)


para alcanzar la rama true, y con (false, false) o (true, true) para la
rama false.
42 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

(A and not B) or (not A and B)


Condiciones Decisin
A and not not A and (A and not B) or (not Condicin
A B
B B A and B) dominante
true false true false true A
false false false false false A, B
false true false true true B
Tabla 3.7. Casos de prueba para conseguir cobertura modificada de condicin/decisin en la versin
extendida de A xor B

El criterio MC/DC produce menos casos de prueba que MCC y, sin


embargo, es muy difcil encontrar un fallo con MCC que pase inadvertido para
MC/DC. Por ello, este criterio de cobertura se exige en la prueba de sistemas
crticos.

3.5 CRITERIOS DE COBERTURA PARA MQUINAS DE


ESTADO
Una mquina de estados es un grafo dirigido, cuyos nodos representan
estados y cuyos arcos representan transiciones entre dichos estados. En desarrollo
de software, las mquinas de estado tienen dos usos principales:

1. Describir el comportamiento de instancias de clases. De manera


general (hay muchos tipos de estados en la especificacin de UML
2.0), los nodos representan los diferentes estados en los que puede
encontrarse la instancia, siendo el estado de la instancia una funcin de
los valores de sus campos. Tambin de manera general (porque hay
muchos tipos de transiciones), las transiciones representan operaciones
de la clase que provocan el paso de un estado a otro y, quizs, la
ejecucin de otras operaciones colaterales.
2. Describir los pasos en la ejecucin de casos de uso. En este caso, cada
estado representa un paso, y la transicin entre un estado y otro
significa que el paso previo ha terminado de ser ejecutado. Puesto que
los casos de uso representan funcionalidades del sistema, la
descripcin de las funcionalidades mediante mquinas de estados
permiten al tester el diseo, construccin y ejecucin de casos de
prueba funcionales.
RA-MA CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 43

La estructura de la mquina de estados puede utilizarse para disear casos


de prueba que la recorran atendiendo a algn criterio de cobertura. A continuacin
se describen los criterios propuestos por Offutt et ll4.

3.5.1 Cobertura de estados


Este criterio se satisface cuando los casos de prueba recorren todos los
estados de la mquina. As, para la mquina de la Figura 3.4, un test suite que
satisface este criterio estara formado por la secuencia de transiciones (mi, m2, m3,
m4).

Figura 3.4. Una sencilla mquina de estados

3.5.2 Cobertura de transiciones


Este criterio se satisface cuando el conjunto de casos de prueba contiene
casos que provocan el disparo de todas las transiciones contenidas en la mquina
de estados.

Para la mquina de la Figura 3.4, un test suite que satisface este criterio
necesitara al menos dos casos de prueba, como por ejemplo: (mi, m2, m3, m3, m4,
m4, m3) y (mi, m2, m4).

14 Offutt, A.J., Liu, S., Abdurazik, A. y Amman, P., 2003, Generating test data from state-based
specifications, Software Testing, Verification and Reliability (13), 25-53.
44 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS...______ RA-MA

3.5.3 Cobertura de pares de transiciones


Este criterio se satisface cuando el conjunto de casos de prueba contiene
casos de prueba que recorren, para un estado dado, todos los pares de transiciones
de entrada y salida de ese estado.

As, para la mquina de estados de la Figura 3.5, este criterio ser


satisfecho si el conjunto de casos de prueba contiene casos que recorran (mi, m3),
(ml, m4), (mi, m5), (m2, m3), (m2, m4) y (m2, m5).

Figura 3.5. Un fragmento de una mquina de estados

Para el caso de la mquina de la Figura 3.4:

1. Como sO no tiene transiciones de entrada, el criterio no es aplicable.


2. Respecto de si, hay que recorrer el par (mi, m2).
3. Respecto de s2, hay que recorrer los pares (m2, m3) y (m2, m4).
4. Respecto de s3, consideramos tres transiciones m3 (que pueden
corresponder a la misma operacin de la clase, pero que se disparan
desde estados distintos):
- Respecto de la transicin m3 que procede de s2, construiremos los
pares (m3, m3), (m3, m4).
- Respecto de la transicin m3 que procede de s4, construimos
tambin los pares (m3, m3), (m3, m4), pero que representan
instancias diferentes de la misma operacin.
- Anlogamente, para la transicin m3 que procede de s3 y que
tambin incide en s3, consideramos lo pares (m3, m3) (la misma
instancia de m3 en este caso: es decir, la misma transicin que
entra es la que sale) y (m3, m4).
5. La situacin para s4 es muy parecida, debiendo recorrer los pares (m4,
m4), (m4, m3) (respecto de la transicin procedente de s2), (m4, m4),
(m4, m3) (respecto de la procedente de s3) y (m4, m4), (m4, m3)
(respecto de la que sale de s4).
RA-MA CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 45

3.5.4 Cobertura de secuencia completa


Este criterio se satisface cuando el conjunto de casos prueba contiene casos
que recorren los caminos (formados por transiciones) ms significativos, que son
aquellos que ha seleccionado el ingeniero de pruebas, que ha propuesto el usuario o
el cliente, etc.

3.6 EJERCICIOS
1. La autenticacin de los usuarios ante un sistema se lleva a cabo mediante
la serie de pasos que se describe en la Figura 3.6. Como se observa,
cuando un usuario se ha tratado de identificar tres veces de manera
errnea, el sistema de autenticacin le bloquea la cuenta. Igualmente, si el
usuario se identifica correctamente y ya tena una sesin abierta, se le
cierra la sesin antigua y se le crea una nueva. Se pide que proponga casos
de prueba para lograr cobertura de estados, de transiciones, de pares de
transiciones y de secuencia completa. Indicacin: considere que la
mquina posee algunos caminos infactibles, como el que consiste en las
transiciones 1-2-3-11-13-14, ya que para alcanzar 13 es necesario que la
variable contador sea 3. Este ejercicio se soluciona parcialmente en el
captulo 5.
o

Comprobar login',
[contador<3] y contrasea
2
*
~-3 [error]<^y
4 [correcto]
........
: Comprobarsiya
'tiestconectadop
I5
Cerrarsesin W X
7
6 [no]

Crearsesinjp
14
9
!
tinalistadesesiones
10

Figura 3.6. Descripcin del comportamiento de un caso de uso para identificarse ante un sistema
46 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

2. Una entidad bancada concede un determinado tipo de prstamo personal


segn los ingresos mensuales del cliente, su antigedad en el trabajo, la
tasa mensual de devolucin del prstamo y el perodo de amortizacin.
- A los que tengan menos de 19 aos no se les concede.
- A los mayores de 70 se les concede si el perodo de amortizacin
es menos de 24 meses y sus ingresos son superiores al triple de la
tasa mensual.
- A los mayores de 50 aos se les concede si tienen una antigedad
superior a 15 aos, el perodo de amortizacin es igual o inferior a
60 meses y si sus ingresos mensuales son iguales o superiores al
triple de la tasa mensual.
- A los menores de 25 aos se les concede si tienen ms de un ao
de antigedad en la empresa, si sus ingresos mensuales superan el
cudruple de la tasa mensual y el perodo de amortizacin es de 4
aos como mucho.
- A los que tienen entre 25 y 50 aos se les concede o bien cuando
los ingresos mensuales superan el cudruple de la tasa mensual, o
bien cuando los ingresos mensuales igualan o superan el triple de
la tasa, tienen una antigedad superior a 10 aos y el perodo de
amortizacin es de 5 aos como mucho.
- En otras situaciones, no se concede.

El banco ha creado la siguiente tabla de decisin, que luego se ha traducido


al cdigo que aparece ms abajo.

Edad Ingresos/mes Antigedad Meses/Amortiz. Accin

<18 No conceder

>70 >3*tasa <=24 Conceder

>=25 y <=50 >4*tasa Conceder

>=25 y <=50 >=3*tasa >10 <=60 Conceder

<25 >4*tasa >1 <=48 Conceder

>50 >=3*tasa >15 <=60 Conceder

Tabla 3.8. Tabla de decisin para la concesin de prstamos en un supuesto banco


RA-MA CAPTULO 3. CRITERIOS DE COBERTURA PARA ARTEFACTOS SOFTWARE 47

package dominio;
public class Prstamo {
public Prstamo!) {
}
public boolean conceder(int edad, double ingresosMes, int antigedad,
int mesesAmortizacion, double tasa) {
if (edad<18)
return false;
if (edad>70 && ingresosMes>3*tasa && mesesAmortizacion<=24)
return true;
if (edad>70 && mesesAmortizacion<24)
return true;
if (edad>70 && mesesAmortizacion>24)
return false;
if (edad>=25 && edad<=50) {
if (ingresosMes>4*tasa)
return true ,-
if (ingresosMes<=3*tasa && antiguedad>10 &&
mesesAmortizacion<=60)
return true;
}
if (edad>50 && ingresosMes>=3*tasa && antiguedad>15 &&
mesesAmortizacion<=60)
return true;
return false;
}
}_____________________________________________________________________
Figura 3.7. Cdigo al que se ha traducido la tabla de decisin anterior

A Ud. se le pide que verifique si la tabla de decisin procede realmente de


los requisitos, y si el cdigo procede realmente de la tabla de decisin.

Tambin se le pide que escriba uno o ms casos de prueba para comprobar


si la funcin conceder cumple con los requisitos expresados en el enunciado del
problema.

Indicacin: para encontrar errores en el cdigo de la funcin conceder, se


sugiere que utilice algn criterio de cobertura (sentencias, condiciones, decisiones,
etc.). Si utiliza Eclipse como entorno de desarrollo, puede utilizar el plugin
Eclemma Code Coverage (www.eclemma.org), que le facilitar la tarea de conocer
la cobertura de sentencias alcanzada.

3. Represente la funcin conceder del ejercicio anterior como una mquina de


estados del estilo de la mostrada en el ejercicio 1. Proponga datos y casos
de prueba para lograr diferentes criterios de cobertura sobre la mquina.
Captulo 4

VALORES DE PRUEBA

Con el objeto de encontrar pronto los errores en el sistema, el tester debe


escribir buenos casos de prueba que traten de ejercitar el sistema en todas sus
formas posibles. Para ello, los servicios invocados sobre el sistema deben recibir
buenos valores como parmetros, que procedern de la propia experiencia del
ingeniero de pruebas, de entrevistas con los usuarios o clientes o de la aplicacin
de determinadas tcnicas. En este captulo se describen algunas de ellas.

4.1 CLASES O PARTICIONES DE EQUIVALENCIA


Con la tcnica de particiones de equivalencia, se divide el dominio de
entrada de cada parmetro en conjuntos disjuntos (cada uno es una particin o clase
de equivalencia), asumindose que el sistema bajo prueba se comportar igual para
cualquier valor de la clase.

Supongamos una clase que representa una cuenta corriente de un banco. La


Figura 4.1 muestra el cdigo de su operacin transferir, que realiza una
transferencia de dinero desde la instancia de cuenta sobre la que se ejecuta la
operacin, y un ingreso sobre la cuentaDestino que se pasa como primer
parmetro. Por la realizacin de la transferencia, el banco cobra una comisin del
1% sobre el importe transferido, con un mnimo de 2 euros. Esto produce dos
movimientos sobre la cuenta origen y uno sobre la cuenta destino:

Sobre la cuenta origen se producen dos movimientos de retirada: uno


por el importe que se pasa como parmetro, y otro por la comisin.
50 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Sobre la cuenta destino se produce un ingreso por el importe


transferido.

Para que la transferencia se lleve a cab,o deben darse varias condiciones:


(1) el importe que se transfiere debe ser positivo (en caso contrario, la operacin
retirar, a la que se llama desde transferir, lanza una ImporteNegativoException)',
(2) la cuenta debe disponer de saldo suficiente (mayor o igual que el importe ms
la comisin; en caso contrario, se lanza una SaldoInsuficienteException)', y (3) la
cuenta destino debe existir (si no, se lanza la CuentalnexistenteException). Si se
dan las dos condiciones, se realizan dos movimientos de retirada sobre la cuenta
origen y uno de ingreso sobre la de destino. Si se produce algn error de acceso a la
base de datos, se lanza una SQLException.

public class Cuenta {


protected String numero;
protected java.util.Date fechaApertura;
protected Cliente titular;
protected double saldo;

public void transferir(Cuenta cuentaDestino, double importe.


String concepto) throws SQLException,
ImporteNegativoException,SaldolnsuficienteException,
CuentalnexistenteException {
double comision=2.0;
if (importe>300)
comision=importe*0.01 ,-
if (existe(cuentaDestino))
throw new CuentalnexistenteException();
this.retirar(importe, "Transferencia emitida a " +
cuentaDestino.getNumero());
this.retirar(comisin, "Comisin por transferencia");
cuentaDestino.ingresar(importe, concepto);
}

Figura 4.1. Cdigo de la operacin transferir de la clase cuenta

De acuerdo con la tcnica de las clases de equivalencia, debemos obtener


particiones para los tres parmetros:

1. Para cuentaDestino, los conjuntos disjuntos pueden estar formados por


todas las cuentas que existen en el banco y todas las cuentas que no
existen.
RA-MA CAPITULO 4. VALORES DE PRUEBA 51

2. Para el importe tenemos diferentes escenarios: por un lado, podemos


suponer una cuenta que tiene saldo suficiente para realizar una
transferencia con la comisin que corresponda; por otro, podemos
suponer una cuenta que no tenga saldo suficiente. En ambos casos,
puede ocurrir que se retiren ms de 300 euros o menos, consideracin
que habra que tomar en cuenta porque la comisin que se percibe es
distinta en ambos casos.
3. Del punto anterior se observa que los posibles valores que tome el
importe afectan al comportamiento de la instancia de la cuenta emisora
que, si bien no se pasa como parmetro, s influye decisivamente en el
escenario de ejecucin. Por ello, aadiremos el objeto this (que
representar la cuenta ordenante) a la coleccin de elementos para los
que identificaremos clases de equivalencia.
4. Para el concepto identificaremos valores de prueba ms adelante
mediante la tcnica de conjetura de errores.

Parmetro Clases de equivalencia Valores seleccionados


this (cuenta cuenta con saldo en [0, 300] cuenta con saldo 200
ordenante) cuenta con saldo en (300, +) cuenta con saldo 500
una cuenta que existe cuenta 123456
cuentaDestino
una cuenta que no existe cuenta 000000
( - , 0] -100
importe (0, 300) +100
[300, +oo) +400
concepto Pago de alquiler Pago de alquiler
Figura 4.2. Clases de equivalencia identificadas para la operacin transferir y valores seleccionados
de cada una

4.2 VALORES LMITE {BOUNDARY VALUES)


La tcnica de valores lmite complementa la anterior: en lugar de elegir
cualquier valor de la clase de equivalencia, se seleccionan los valores situados en
los lmites de las clases de equivalencia. Existen dos variantes de esta tcnica:

1. En la variante ligera, por cada clase de equivalencia se toman como


valores de prueba los propios valores lmite de la clase y los valores
adyacentes de las clases de equivalencia adyacentes.
52 TECNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

2. En la variante pesada, se toma adems el valor inmediatamente


inferior al lmite, perteneciente a la clase de equivalencia que se est
considerando.

Para el caso de la operacin retirar, consideraramos los parmetros que


puedan ser enumerables (ni cuentaDestino ni concepto lo son; incluso la cuenta
ordenante tampoco lo es, aunque s su saldo, que es el elemento compositivo de su
estado que nos interesa). En la siguiente tabla se han aadido, a los resultados de la
tabla anterior, los valores procedentes de la variante ligera de los valores lmite,
sealndose con dos asteriscos (**).

Parmetro Clases de equivalencia Valores seleccionados


this (cuenta cuenta con saldo en [0, 300] cuenta con saldo 200
ordenante) cuenta con saldo en (300, cuenta con saldo 500
+oo)
cuenta con saldo 300 **
cuenta con saldo 301 **
cuentaDestino una cuenta que existe cuenta 123456
una cuenta que no existe cuenta 000000
importe ( - , 0] -100
(0, 300) +100
[300, +) +400
Q **
] **
300 **
301 **
concepto Pago de alquiler Pago de alquiler
Tabla 4.1. Valores de prueba seleccionados, a los que se han aadido los procedentes de la variante
ligera de valores lmite

4.3 CONJETURA DE ERRORES (ERROR-GUESSING)


Mediante la tcnica de la conjetura de errores, el ingeniero de pruebas
propone valores para los que, de alguna manera, intuye que el sistema puede
mostrar un comportamiento errneo.
O RA-MA CAPITULO 4. VALORES DE PRUEBA 53

Para el concepto, por ejemplo, que se trata de una cadena de caracteres,


pueden utilizarse la cadena vaca y una cadena con ms de 255 caracteres. Para la
cuentaDestino puede utilizarse la propia cuenta ordenante o un objeto nuil. En la
Tabla 4.2 se han marcado con dos asteriscos estos nuevos valores.

Parmetro Clases de equivalencia Valores seleccionados


this (cuenta cuenta con saldo en [0, 300] cuenta con saldo 200
ordenante) cuenta con saldo en (300, +) cuenta con saldo 500
cuenta con saldo 300
cuenta con saldo 301
cuentaDestino una cuenta que existe cuenta 123456
una cuenta que no existe cuenta 000000
la propia cuenta ordenante
**
importe ( - , 0] -100
(0, 300) +100
[300, +) +400
0
1
300
301
concepto Pago de alquiler Pago de alquiler

Cadena de ms de 255
caracteres **
Tabla 4.2. Valores de prueba seleccionados, a los que se han aadido los procedentes de la conjetura
de errores

Para valores de otros tipos, como los numricos, suele utilizarse el valor 0
(ya que, por ejemplo, puede que se utilice como denominador en alguna divisin),
algn nmero negativo, etc.

4.4 APLICACIN DE LAS TCNICAS AL CONJUNTO


DE DATOS DE SALIDA
Tanto la tcnica de valores lmite como la de clases de equivalencia pueden
ser aplicadas al conjunto de salida, de forma que lo que se particiona no es el
dominio de entrada, sino el de salida, con lo que los casos de prueba que se
54 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

construyan (que sern las entradas del programa bajo prueba) debern ser capaces
de generar las salidas en cada una de las clases de equivalencia de salida.

En este punto, podemos tener en cuenta que los eventos asincronos


(excepciones) tambin pertenecen al posible conjunto de salidas de una operacin,
de manera que debemos intentar que nuestros casos de prueba lancen, con cada
operacin, todas sus posibles excepciones. La operacin transferir que veamos en
la Figura 4.1 puede lanzar cuatro excepciones: SQLException,
ImporteNegativoException, SaldoInsuficienteException y
CuentalnexistenteException. Para este ejemplo, y teniendo en cuenta que estas
excepciones forman tambin parte del posible conjunto de salidas de la operacin,
deberamos construir, al menos, cuatro casos de prueba para que se arrojen las
cuatro excepciones:

Para lanzar la SQLException, en un caso de prueba tendramos que,


por ejemplo, detener el servidor de base de datos.

Para lanzar la ImporteNegativoException, tendramos que tratar de


hacer una transferencia con un importe negativo.

Para lanzar la SaldoInsuficienteException, el importe de la


transferencia ms la comisin que corresponda debe superar el saldo
disponible en la cuenta.

Para la CuentalnexistenteException, deberamos tratar de hacer una


transferencia a una cuenta que no exista.

4.5 CRITERIOS DE COBERTURA PARA VALORES DE


PRUEBA
Una vez que el tester ha propuesto los valores de prueba conforme a alguna
de las tcnicas repasadas en las secciones anteriores, los debe combinar con alguna
estrategia de combinacin (se vern en el captulo siguiente) con el objeto de
obtener los casos de prueba. Los casos de prueba deben utilizar, de alguna manera,
los valores interesantes que el tester ha propuesto: puede, por ejemplo, utilizar cada
valor en un caso, cada valor dos veces, utilizar diferentes combinaciones de
valores, etc. Para medir el grado en que se utilizan los valores de prueba, se utilizan
criterios de cobertura para valores.
RA-MA CAPTULO 4. VALORES DE PRUEBA 55

Con objeto de ilustrar los criterios que se exponen a continuacin,


utilizaremos, a modo de ejemplo, los parmetros A, B y C, cuyos valores son los
siguientes

A={1, 2, 3, 4}, B={5, 6, 7}, C={8, 9}

4.5.1 Cada uso {each us)


Cuando se construyen casos de prueba conforme a este criterio, cada valor
interesante debe utilizarse, al menos, en un caso de prueba. Para el caso de los
parmetros A, B y C, dos test suites que verifican este criterio son los siguientes:

Test suite 1 = { (1, 5, 8), (2, 6, 9), (3, 7, 8), (4, 5, 9) }

Test suite 2 = { (2, 5, 9), (3, 6, 8), (1, 7, 8), (4, 7, 8) }

4.5.2 Todos los pares (pairwise)


Con este criterio, los casos de prueba deben visitar, al menos una vez,
todos los pares de valores de dos parmetros cualesquiera. Este criterio se utiliza
con mucha frecuencia, ya que muchos errores aparecen por la interaccin de los
valores inesperados de dos parmetros.

A primera vista, un algoritmo, para alcanzar este criterio de cobertura de


valores, requiere la construccin de las tablas de pares de los parmetros; a
continuacin, se van construyendo casos de prueba, de manera que, en cada uno, se
visite el mayor nmero posible de pares no visitados. Si hay n parmetros, habr
n-(n-l)/2 tablas de pares. Para los parmetros A, B y C, un test suite que satisface el
criterio pairwise es el siguiente:

(2,6,9), (2,5,8), (2,7,9), (1,6,8), (1,5,9), (1,7,8), (4,6,9), (4,5,8), (4,7,9),


(3,6,8), (3,5,9), (3,7,8)

En la Tabla 4.3 aparecen las tablas de pares de los tres parmetros, as


como el nmero de visitas que recibe cada par: el caso (2, 6, 9), por ejemplo, visita
los pares (2, 6) de la tabla (A, B), (2, 9) de la tabla (A, C) y (6, 9) de la tabla (B, C).
56 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

(A, B) (A, C) (B, C)


Pares Visitas Pares Visitas Pares Visitas

(1,5) 1 (1,8) 2 (5,8) 2

(1,6) 1 (1,9) 1 (5,9) 2

(1,7) 1 (2, 8) 1 (6, 8) 2

(2, 5) 1 (2, 9) 2 (6, 9) 2

(2, 6) 1 (3,8) 2 (7, 8) 2

(2, 7) 1 (3,9) 1 (7, 9) 2


(3,5) 1 (4, 8) 1
(3,6) 1 (4, 9) 2
(3, 7) 1
(4, 5) 1
(4, 6) 1

(4, 7) 1
Tabla 4.3. Tablas de pares y nmero de visitas para los parmetros A, B y C

4.5.3 Todas las tupias de n elementos (n-wise)


Este criterio es una generalizacin del anterior (pairwise), cuyo objetivo es
construir casos de prueba que visiten todas las tupias de n elementos de n
parmetros cualesquiera. Procediendo de modo parecido al caso anterior, se
construirn no tablas de pares, sino tablas de n elementos (cada elemento es una
tupia), de manera que se visiten todas las tupias.

Para el ejemplo de A, B y C, el mayor valor que puede tomar n es 3, ya que


hay tres parmetros. Para un sistema con cuatro conjuntos A, B, C y D y n=3,
existirn las tablas (A, B, C), (A, B, D) y (B, C, D). El criterio n-wise subsume al
criterio (n-l)-wise: es decir, si se visitan todas las tupias de n elementos, tambin se
estn visitando todas las tupias de n-1 elementos.
RA-MA CAPTULO 4. VALORES DE PRUEBA 57

4.6 EJERCICIOS
1. Aplicando las tcnicas enumeradas en este captulo, proponga valores de
prueba para probar suficientemente la funcin conceder de los ejercicios del
captulo anterior.
2. Utilice los valores propuestos en el ejercicio anterior para obtener dos test
suites que alcancen respectivamente cobertura each use y pairwise.
3. A primera vista, parece evidente que los casos de prueba que cumplan each
use alcanzarn menos cobertura de cdigo que los que cumplan pairwise.
Utilice la funcin conceder y los dos test suites obtenidos en el ejercicio
anterior para comprobar esa supuesta evidencia.
Captulo 5

ESTRATEGIAS DE COMBINACIN PARA LA


OBTENCIN DE CASOS DE PRUEBA

Una vez que se han propuesto los valores ms adecuados para probar el
sistema, el tester debe combinarlos con objeto de obtener buenos casos de prueba
que lo ayuden a encontrar errores en el sistema. En general, los casos de prueba
ejecutan servicios del sistema bajo prueba. Tras cada ejecucin, el caso debe ser
capaz de determinar, mediante lo que se llama un orculo, si el sistema se ha
comportado de forma correcta (no ha encontrado error) o de forma incorrecta (s
lo ha encontrado).

5.1 ESTRUCTURA DE UN CASO DE PRUEBA


Una de las caractersticas deseables de los casos de prueba es que sean
rcproducibles, en el sentido de que, independientemente del momento en que se
ejecuten, se obtengan siempre los mismos resultados. Por ello, un buen caso de
prueba establece, en su comienzo, la situacin inicial que se requiere para su
ejecucin (por ejemplo, eliminar todos los registros de la base de datos de prueba);
a continuacin, lo habitual es ejecutar servicios sobre el sistema; finalmente, al
caso de prueba se le dota de un orculo, que ayuda a determinar si el caso ha
encontrado o no error en el sistema.
60 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

5.1.1 Ejemplo
Supongamos que el sistema bancario que venimos utilizando manipula una
base de datos relacional cuyo esquema entidad-interrelacin es el que aparece en la
Figura 5.1, la base de datos almacena informacin de Clientes, cada uno de los
cuales puede tener varias Cuentas-, cada Cuenta tiene una serie de Movimientos
(ingresos y retiradas de fondos) y puede tener varias taijetas asociadas, que pueden
ser de Dbito o de Crdito. Ambos tipos de taijetas tienen tambin una serie de
Movimientos de tarjeta asociados. Las tarjetas de Dbito no aportan nada respecto
de la definicin de Tarjeta, mientras que las de Crdito tienen una columna
adicional (crdito) que denota el crdito concedido a esa tarjeta. Hay, adems, una
tabla aislada (UltimosNmeros) en la que se almacena un contador para asignar el
nmero de cuenta a las cuentas nuevas que se van creando.

_ J Cuenta 3 Movimiento
i NIF
N VARCHAFU5G) f Numero VARCHARI50) : ktevtmnto INT
: > Fecha Apertura DATETIME . O N um w oD a*o3 VARCHAR50)
# NIFTituter VARCHAR( 50) V importe DOUBLE
^ Focha DAT ETfMF
V Concepto VARCHAR{50)

Figura 5.1. Esquema entidad-interrelacin de la base de datos bancaria

La Figura 5.2 muestra el cdigo de un caso de prueba en formato JUnit


(un framework que permite automatizar la ejecucin de casos de prueba para
aplicaciones Java), que permite probar parte de la funcionalidad de la operacin
retirar de Cuenta: en su primera sentencia (double saldoPepePre=
this.cuentaPepe.getSaldoQ) se almacena en la variable saldoPepePre el saldo de la
cuenta identificada por el objeto cuentaPepe. A continuacin, se retiran 500 euros
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 61

de ella. En la ltima instruccin del bloque try, se comprueba que el nuevo saldo de
la cuenta sea el anterior menos los 500 euros que se han retirado. Si el sistema bajo
prueba se comporta adecuadamente con este caso de prueba (es decir, el saldo se
decrementa efectivamente en 500 euros), el framework JUnit mostrar, para este
caso, una barra verde; en otro caso, mostrar una barra roja.

public void LstRetirarDeCuentaO {


try {
double saldoPepePre=this.cuentaPepe.getSaldo();
this.cuentaPepe.retirar(500, "Retirada de 500");
assert True(this.cuentaPepe.getSaldo()==saldoPepePre-500);
} catch (Exception e) {
f a i l (e.toStringO ) ;

}
_}_______________________________________________________________________
Figura 5.2. Un caso de prueba para probar la operacin retirar de la clase Cuenta

El caso que se muestra en la figura anterior adolece, sin embargo, de un


elemento importante: como hemos dicho, los casos deben ser reproducibles en
cualquier momento y, tambin en cualquier momento, deben devolver siempre el
mismo resultado. Para ello, es preciso especificar la situacin inicial que, como
apuntbamos ms arriba, puede consistir en situar la base de datos en un estado
inicial conocido. JUnit y otros frameworks de pruebas incluyen la posibilidad de
ejecutar operaciones de inicializacin antes de cada caso de prueba, as como
operaciones de finalizacin despus de cada uno (liberacin de conexiones o
recursos, por ejemplo). En JUnit, la situacin inicial se especifica en un mtodo
llamado setUp\ las operaciones finales se incluyen en un mtodo llamado
tearDown.

En la Figura 5.3 se muestra el cdigo correspondiente al mtodo setUp


para el sistema bancario: en primer lugar, se eliminan todos los registros de las
tablas de la base de datos (excepto la tabla ltimosNmeros). A continuacin, se
crean dos clientes (objetos pepe y ana) y se insertan en la base de datos (en la tabla
Cliente). Luego se crea una cuenta para cada uno ellos, se les ingresan 1000 y 2000
euros respectivamente a pepe y a ana y se les crean unas tarjetas de dbito y
crdito.

Como tal vez se recuerde, el primer ejercicio del captulo 2 nos planteaba
lo siguiente:

Uno de los requisitos fundamentales de los casos de prueba es la


posibilidad de que sean reejecutados tantas veces como se necesite. Cuando el
sistema utiliza una base de datos, esto puede suponer algunos problemas, ya que
62 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

los casos de prueba pueden alterar el estado de la base de datos y dificultar la


replicacin de las pruebas. Qu soluciones tiene para ello?

En los mtodos setUp y tearDown tenemos una posible respuesta: antes de


ejecutar cada caso de prueba o cada batera de casos de prueba, incluimos
instrucciones en el mtodo setUp para que la base de datos se quede en el estado
inicial que se precisa para que los casos de prueba sean reproducibles (es decir, que
ofrezcan siempre el mismo resultado); del mismo modo, podemos hacer otras
operaciones de limpieza en el tearDown.

protected void setup() {


System.out.println("setup");
try {
Connection bd=Broker . g e t C o n n e c t i o n O ;

String SQLl="Delete from Cliente where nif='ana' or


nif= 'pepe 111
String SQL2="Delete from Cuenta where nifTitular=1an a ' or
nifTitular='pepe'";
String SQL3="Delete from Tarjeta";
String SQL4="Delete from Crdito";
String SQL5="Delete from Debito";
String SQL6="Delete from Movimiento";
String SQL7="Delete from MovimientoTarjeta";
PreparedStatement pl=bd.prepareStatement (SQL1)
PreparedStatement p2=bd.prepareStatement (SQL2)
PreparedStatement p3=bd.prepareStatement(SQL3);
PreparedStatement p4=bd.prepareStatement(SQL4);
PreparedStatement p5=bd.prepareStatement(SQL5);
PreparedStatement p6=bd.prepareStatement(SQL6)
PreparedStatement p7=bd.prepareStatement(SQL7);
p i .executeUpdate () p2 .executeUpdate () ,- p3 .executeUpdate () ;
p 4 .executeUpdate(); p 5 .executeUpdate(); p 6 .executeUpdate();
p 7 .executeUpdate();
} catch (Exception e) { f a i l (e.toString()); }
pepe=new ClienteO;
pepe.setNIF("pepe);
ana=new Cliente();
a n a .setNIF("ana");
try {
pe p e .insert();
an a .insert();
} catch (Exception e) { fail (e .toString ()) }
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 63

try {
cuentaPepe=new Cuenta(pepe);
cu e n t aAn a=n ew Cuenta (ana) ;
cuentaPepe.insert();
cuentaAna.insert();
} catch (Exception e) { f a i l (e.toString()); }

try {
cuentaPepe.ingresar(1000, "Ingreso a Pepe");
cuentaAna.ingresar(2000, "Ingreso a Ana");
} catch (Exception e) { fail (e.toStringO ) ; }

tdPepe=new TarjetaDeDebito("tdPepe, "10", "2010", cuentaPepe);


tdAna=new TarjetaDeDebito ("tdAna" , "10", "2010", cuentaAna) ,-
tcPepe=new TarjetaDeCredito("tcPepe", "10", "2010", cuentaPepe, 500);
tcAna=new TarjetaDeCredito("tcAna", "10", "2010", cuentaAna, 800);
try {
tdPepe.insert() ;
tdAna.insert() ;
tcPepe.insert();
tcAna.insert();
} catch (Exception e) { fail (e.toStringO ) ; }

)_________________________________________________________________________
Figura 5.3. Cdigo del mtodo setUp para los casos de prueba del banco

La estructura de la clase CuentaTest, que prueba algunas de las


funcionalidades ofrecidas por la clase Cuenta, aparece en la Figura 5.4. Los
mtodos cuyo nombre empieza con el prefijo test son casos de prueba; antes de
ejecutar cada uno, JUnit ejecuta el mtodo setUp (Figura 5.3), que vaca la base de
datos. Tras ejecutar cada caso, ejecuta el mtodo tearDown. Obsrvese la
presencia, en la clase, de los campos pepe, ana, cuentaPepe, cuentaAna, tdPepe,
tdAna, tcPepe y tcAna, que representan clientes, cuentas, taijetas de dbito y
tarjetas de crdito. En este tipo de frameworks, a estos objetos que se declaran
como miembros de la clase de prueba y que se reutilizan en varios casos de prueba
se los conoce con el nombre de fixtures. En el caso de la Figura 5.4, el orden de
ejecucin de los mtodos ser el siguiente: setUp, testRetirarDeCuenta, tearDown,
setUp, testRetirarConDebito, tearDown, setUp, testRetirarConCredito, tearDown,
setUp, testTransferir, tearDown, setUp, testForzarExcepcionEnlnsercionDeCuenta
y tearDown.
64 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

package bancoupm.dominio.tests;

&import ja v a .s q l.C onnection^

p u b lic c la ss CuentaTest extends TestCase {


C lien te pepe, ana;
Cuenta cuentaPepe, cuentaAna;
TarjetaDeDebito tdPepe, tdna;
TarjetaOeCredito tcPepe, tcAna;

* pro tected void set p Q {[]

pro tected void tearDown() $]

* pu b lic void testRetirarO eC uentoQ {Q

,# pu b lic void testRetirarConDebitoC) {Q

>^ pu b lic void testR etirorC onC reditoQ {Q

pu b lic void testT ro n sferirC ) {Q

public void testForzarExcepcionEnlnsercionDeCuentaO {Q


}
Figura 5.4. Campos y operaciones en la clase CuentaTest, que prueba algunas funcionalidades de la
clase Cuenta incluida en el sistema bancario

5.2 EL ORCULO
Como se ha comentado, el orculo es el mecanismo de que se dota a los
casos de prueba para determinar si el propio caso ha encontrado o no un error en el
sistema bajo prueba. El orculo debe ser lo suficientemente fino como para
comprobar adecuadamente el comportamiento obtenido por el sistema. En el
ejemplo de la Figura 5.2, el orculo viene dado por la instruccin
assertTrue(this.cuentaPepe.getSaldoQ==saldoPepePre-500), que comprueba, para
una retirada de 500 euros de la cuenta de Pepe, que el saldo, en efecto, disminuye
en esa cantidad. Un orculo menos riguroso podra comprobar, sencillamente, que
el saldo de la cuenta, despus de la retirada, es menor que el saldo antes de ejecutar
la operacin: assertTrue(this.cuentaPepe.getSaldoQ<saldoPepePre). Como se
observa, este orculo tiene una granularidad mucho ms gruesa que el anterior, y
tiene una probabilidad ms alta de pasar por alto errores en el sistema.

La escritura de buenos orculos es una de las tareas ms tediosas en la


escritura de casos de prueba. De hecho, gran parte de los casos de prueba que, en
apariencia, encuentran errores, incluyen un error en la definicin del orculo.

Por lo general, el orculo compara el resultado obtenido tras la ejecucin


del caso de prueba con el resultado que se esperaba. Estos resultados pueden
expresarse en funcin del estado de los objetos que intervienen en el escenario de
ejecucin que se est probando. Adems, puesto que el estado de un objeto es una
funcin de los valores de los campos de dicho objeto, los resultados (esperado u
O RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 65

obtenido) pueden expresarse como una funcin de los valores de los campos de los
objetos involucrados. En el ejemplo del orculo escrito para la operacin retirar, se
toma el estado del objeto cuentaPepe que, en este caso, es el nico objeto que
interviene en el escenario de ejecucin. El estado de cuentaPepe viene dado por
una llamada a su mtodo getSaldo, el cual, como se ve en la Figura 5.5, devuelve
la suma de los importes de los movimientos asociados a la cuenta: en la
determinacin del valor del estado de la instancia, entonces, intervienen los estados
de otros objetos, que son los movimientos, pero que forman parte de la definicin
de la Cuenta.

public double getSaldo() throws SQLException {


String SQL="Select su m (Importe) from Movimiento where
NumeroDeCuenta=?";
Connection bd=null;
SQLException ex=null;
PreparedStatement p=null;
double resul=0;
try {
bd=Broker .getConnection ()
p=bd.prepareStatement(SQL);
p .setstring (1, this.numero)
ResultSet r=p.executeQuery () ,-
if (r .next()) {
resul=r.getDouble(1) ;
}
}
catch (SQLException e) {
ex=e;
}
finally {
p .close ();
if (ex!=null)
throw ex;
}
return resul;
}
Figura 5.5. Cdigo del mtodo getSaldo de la clase Cuenta, que calcula el saldo en funcin de los
importes de los movimientos asociados

5.2.1 Obtencin de casos de prueba con orculos a partir de


mquinas de estado
Cuando el comportamiento de las instancias de clases se describe mediante
mquinas de estados, la propia mquina puede entenderse como un artefacto ms o
menos similar a un autmata finito, de los que pueden derivarse expresiones
66 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

regulares que describen un lenguaje regular. En el caso de la mquina de estados, el


lenguaje que acepta puede derivarse a partir de las operaciones que etiquetan las
transiciones entre estados. De este modo, recorriendo la mquina de diferentes
formas (siempre teniendo presente algn criterio de cobertura para mquinas de
estado, como los que vimos en el captulo 3, pgina 42), obtenemos diversos
escenarios de ejecucin de la instancia.

Adems, puesto que cada transicin conecta dos estados, la definicin del
estado origen puede utilizarse como precondicin del caso de prueba, y la
definicin del estado destino, como poscondicin.

Fijndonos en el ejemplo de la Figura 5.6, que representa el posible


comportamiento de una supuesta cuenta corriente, observamos que hay tres estados
(adems del estado inicial), y que se va de uno a otro en funcin de las transiciones
que se vayan disparando, algunas de las cuales cuentan adems con condiciones
de guarda.

Figura 5.6. Una posible mquina de estados para una clase Cuenta

Asumiendo que cada cuenta tiene una coleccin de movimientos asociados


y una operacin getSaldo, los tres estados mostrados en la figura se pueden
describir como en la Tabla 5.1, la cuenta est en el estado Recin creada cuando
no ha habido movimientos sobre ella; en Cero o positivo cuando el saldo es mayor
o igual a cero, y en Negativo cuando el saldo es menor que cero.
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 67

Estado Descripcin
Recin creada movimientos.size()=0
Cero o positivo getSaldo()>=0
Negativo getSaldo()<0
Tabla 5.1. Descripcin de los estados de una clase Cuenta

Suponiendo que la transicin desde el estado inicial hasta Recin creada se


corresponda con una llamada al constructor de la clase, un caso de prueba con el
que se logra cobertura de estados es el que se muestra en la Figura 5.7, obsrvese
que usamos las transiciones para construir la secuencia de operaciones del caso de
prueba, mientras que la descripcin de los estados la utilizamos para escribir los
orculos.

Cuenta c=new Cuenta();


assertTrue(c.movimientos.size()=0);
c.ingresar(lO);
assertTrue(c.getSaldo()>=0);
c.retirar(-20);
assertTrue(e.getSaldo()<0);
Figura 5.7. Un caso de prueba para la cuenta procedente de la Figura 5.6 y de la Tabla 5.1

Por otro lado, las mquinas de estado se utilizan tambin para describir
casos de uso: los estados representan pasos en la ejecucin del caso de uso, y las
transiciones representan que el paso o actividad anterior se ha terminado de
ejecutar y se pasa a ejecutar la siguiente actividad que corresponda. Puesto que los
casos de uso se corresponden de forma muy aproximada con los requisitos
funcionales del sistema, pueden utilizarse las mquinas de estado que describen
casos de uso para preparar, desde la captura de requisitos, casos de prueba
funcionales, que quizs se ejecuten en un momento mucho ms tardo (cuando, por
ejemplo, el sistema est completamente terminado).

En la Figura 5.8 se muestra una mquina de estados ya conocida (la


utilizamos en un ejercicio anterior) correspondiente a un supuesto caso de uso
Identificar, que recibe un login y una contrasea de usuario y verifica si la
combinacin de ambos es correcta. En caso negativo, puede realizar dos intentos
ms antes de que se le bloquee la cuenta; en caso afirmativo, se le cierra su sesin
anterior si es que la tena abierta y, en todo caso, se le crea una nueva, que se aade
a una lista de sesiones. Para este requisito, podramos crear casos de prueba que
68 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

logren cobertura de pares de transiciones entrada/salida (seccin 3.5.3, pgina 44).


Para ello, construimos para cada estado una lista con las transiciones que entran y
salen ( Tabla 5.2). Ntese que las transiciones que entran a los nodos choice (nodos
de eleccin) no las consideramos salidas, y que pasamos directamente a considerar
las transiciones que salen de ellos.

Estado Entradas Salidas Pares


Comprobar login y contrasea 1,12 3,4 (1,3), (1,4), (12, 3),
(12, 4)
Comprobar si ya est conectado 4 6,7 (4, 6), (4, 7)
Cerrar sesin 7 8 (7,8)
Crear sesin 6, 8 9 (6, 9), (8, 9)
Aadir sesin a una lista de 9 10 (9,10)
sesiones
Incrementar contador 3 12, 13 (3,12), (3,13)
Bloquear usuario 13 14 (13, 14)
Tabla 5.2. Transiciones de entrada, de salida y pares para la Figura 5.8

[contador<3] j
12
2
11
[contador=3] Incrementar
contador [error]
4 [correcto]

( Cerrar sesin - ^
f y
6 [no]

Crear sesin
14

Aadir la sesin a
' .una lista de sesiones

Figura 5.8. Una mquina de estados que representa el caso de uso Identificar
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 69

A continuacin, construimos los casos de prueba para ir visitando todos los


pares de transiciones. En la Tabla 5.3 se muestra la secuencia de transiciones que
componen los casos de prueba y se tachan los pares que van siendo visitados por
cada caso.

Caso de prueba Pares visitados


1-3-12-3-13-14 fh4), (1, 4), (UMD, (12, 4), (4, 6), (4, 7), (7,8),
(6, 9), (8, 9), (9, 10), (4^43), (4^44), (44^44)
1-4-6-9-10 (1,3), (1, 4), (12, 3), (12, 4), (4, 6), (4, 7), (7,8),
(6, 9), (8, 9), (9, 10), (3, 12), (3, 13), (13, 14)
1-3-12-4-7-8-9-10 (1,3), (1, 4), (12, 3), (12, 4), (4, 6), (4, 7), (7,8),
(6, 9), (8, 9), (9, 10), (3, 12), (3, 13), (13, 14)
Tabla 5.3. Casos de prueba y pares visitados

Los casos de prueba construidos cubren entonces el criterio de cobertura


que nos habamos prefijado. Por el propio diseo del sistema, el primer caso es
infactible, ya que solo se recorrer la transicin 13 cuando el contador valga 3.
Habr entonces que modificar ese primer caso y dejarlo, por ejemplo, de esta
manera: 1-3-12-3-13-12-3-12-3-13-14. Este caso adicional es un ejemplo vlido del
criterio de cobertura completa.

5.3 ESTRATEGIAS DE COMBINACIN


Una estrategia de combinacin es un algoritmo que toma como entradas un
conjunto de datos de prueba y produce, mediante algn mecanismo de combinacin
de dichos valores, un conjunto de casos de prueba. Por lo general, las estrategias de
combinacin combinan los valores de prueba con el objeto de alcanzar algn
criterio de cobertura para valores (each use, pairwise, n-wise, pgina 54).

Puesto que los casos de prueba deben ser mantenidos y ejecutados, lo cual
tiene un coste asociado, por lo general es deseable obtener test suites que no sean
demasiado grandes (es decir, que no tengan demasiados casos de prueba) y que, a
la vez, sean capaces de encontrar tantos errores como sea posible.

A continuacin se revisan algunas estrategias de combinacin. A modo de


ejemplo, supondremos que disponemos de los parmetros A, B y C, cuyos valores
son los siguientes:

A={1,2, 3, 4}, B={5, 6, 7}, C={8, 9}


70 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

5.3.1 Todas las combinaciones {All combinations)


Mediante este algoritmo, se generan todos los posibles casos de prueba,
mediante el clculo del producto cartesiano de los parmetros. Para el ejemplo,
habra 4 x 3 x 2 = 24 combinaciones, que corresponden a los 24 casos de prueba
que se muestran en la Tabla 5.4.

i A[i] B[i] C[i]


0 1 5 8
1 1 5 9
2 1 6 8
3 1 6 9
4 1 7 8
5 1 7 9
6 2 5 8
7 2 5 9
8 2 6 8
9 2 6 9
10 2 7 8
11 2 7 9
12 3 5 8
13 3 5 9
14 3 6 8
15 3 6 9
16 3 7 8
17 3 7 9
18 4 5 8
19 4 5 9
20 4 6 8
21 4 6 9
22 4 7 8
23 4 7 9
Tabla 5.4. Casos de prueba procedentes de aplicar all combinations a los parmetros de ejemplo
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 71

Resulta relativamente sencillo escribir un algoritmo recursivo para calcular


el producto cartesiano de n conjuntos; sin embargo, es posible tambin construir un
algoritmo iterativo si aadimos a la Tabla 5.4 una columna adicional que nos
muestre las posiciones que los elementos de cada conjunto ocupan en el caso de
prueba (vase Tabla 5.5): por ejemplo, el caso 0 est formado por los elementos 1,
5 y 8, que corresponden a los elementos situados en las posiciones 0, 0 y 0 de los
conjuntos A, B y C; el caso 1 corresponde a los elementos situados en 0, 0, 1; y el
caso 7, a los elementos situados en las posiciones 1, 0 y 1 de, respectivamente, A, B
y C. Observemos, adems, que los elementos del tercer conjunto (C) aparecen una
vez s, una vez no (es decir: 8, 9, 8, 9...); que los del segundo (B) aparecen tantas
veces seguidas como nmero de elementos haya en el tercero (como hay dos
elementos en C: 5, 5, 6, 6, 7, 7, 5, 5, 6, 6, 7, 7...) y que los del primero (A)
aparecen tantas veces seguidas como nmero de elementos haya en el segundo
multiplicado por el nmero de elementos en el tercero ( 3 x 2 = 6 veces: hay seis
unos seguidos, seis doses seguidos, seis treses y seis cuatros).

i A[i] B[i] cp] Posiciones


0 1 5 8 {0, 0, 0}
1 1 5 9 {0, 0,1}
2 1 6 8 {0,1,0}
3 1 6 9 {0,1,1}
4 1 7 8 {0, 2, 0}
5 1 7 9 {0, 2, 1}
6 2 5 8 {1,0,0}
7 2 5 9 {1,0,1}
8 2 6 8 {1,1,0}
9 2 6 9 {1,1,1}
10 2 7 8 {1,2,0}
11 2 7 9 {1,2,1}
12 3 5 8 {2, 0, 0}
13 3 5 9 {2, 0,1}
14 3 6 8 {2,1,0}
15 3 6 9 {2,1,1}
72 TCNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

16 3 7 8 {2, 2, 0}
17 3 7 9 {2,2,1}
18 4 5 8 {3, 0, 0}
19 4 5 9 {3,0,1}
20 4 6 8 {3,1,0}
21 4 6 9 {3,1,1}
22 4 7 8 {3,2,0}
23 4 7 9 {3,2,1}
Tabla 5.5. La Tabla 5.4, ampliada con una columna que representa la posicin de los elementos
(valores) en cada conjunto (parmetros)

De manera general, si hay n conjuntos {S, S2, ... S}, cada elemento de S
aparece |S,2 |-|&|-...-|/S'B| veces seguidas (donde \S\ es el cardinal del conjunto S); los
elementos de S2, |5?|-,Sj... jS| veces seguidas; etc. Los elementos de S aparecen
una vez cada uno, alternndose. Ya que el nmero de combinaciones es conocido a
n n

priori ( n '^ 'X dado un ndice arbitrario i, o < i < r n es posible conocer la
i=1 =1
combinacin o caso de prueba correspondiente a ese i. A continuacin, explicamos
cmo.

El primer bucle de la Figura 5.9 evala el nmero de combinaciones (es


decir, el cardinal del producto cartesiano); luego, en el segundo bucle, durante
nmeroDeCombinaciones veces, se aade al conjunto de resultados la combinacin
i-sima.

function productoCartesiano({s}) : Set(Combinacin) {


nmeroDeCombinaciones: int = 1;
for (i=0 ; i<|S|; i++) {
nmeroDeCombinaciones = nmeroDeCombinaciones * |St|
1
resultado : Set(Combinacin)=0
for (i=0; i< nmeroDeCombinaciones; i++) {
resultado= resultado u getCombinacin(S, i)
}
return resultado
}
Figura 5.9. Algoritmo iterativo para obtener el producto cartesiano de n conjuntos (versin 1)
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 73

Para completar el algoritmo de la Figura 5.9, se debe implementar la


funcin getCombinacin, que devuelve la combinacin correspondiente al caso de
prueba i-simo, recibiendo tambin como parmetro la lista de conjuntos {{S}).
Cada combinacin est compuesta de |Sj elementos (el primero del primer
conjunto, el segundo del segundo conjunto...); para el ltimo conjunto (Sn), el
elemento que se debe incluir en la combinacin i-sima (y que aparecer en la
ltima posicin de la combinacin) es el elemento de S dado por la expresin
i%\S\ (en donde % representa el resto de la divisin entera). Dada una posicin
arbitraria i de un caso de prueba (en el ejemplo, dado un nmero arbitrario entre 0
y 23), la posicin de cada conjunto Sj que se debe incluir en la combinacin
depende del nmero de valores en SJ+, Sj+2... S. El valor seleccionado del
conjunto j-simo para la combinacin i-sima es el elemento de Sj situado en la
posicin dada por la expresin que aparece en la Figura 5.10.

i
posicinDelValor(J, i) %\Sj
divisoresj

Figura 5.10. Clculo del valor del conjunto j-simo para la combinacin i-sima.

Divisoresj es el producto de los cardinales de los conjuntos que van desde


Sj hasta S, y es 1 para Sn. Para los conjuntos A, B y C de nuestro ejemplo (pgina
69), los divisores son:

divisoresA=|B|jC|=3-2=6 divisoresB=|C|=2 divisoresc=l

Por tanto, la funcin mostrada en la Figura 5.9 se puede reescribir y


dejarla como en la Figura 5.11: ahora, dentro del primer bucle hay otro bucle
anidado que va calculando los divisores de cada conjunto. En el segundo bucle
externo, getCombinacin toma ahora tres parmetros:

La lista de conjuntos (S).

La posicin de la combinacin que se desea obtener (/').

Los valores de divisores.


RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 73

Para completar el algoritmo de la Figura 5.9, se debe implementar la


funcin getCombinacin, que devuelve la combinacin correspondiente al caso de
prueba i-simo, recibiendo tambin como parmetro la lista de conjuntos ({S}).
Cada combinacin est compuesta de |Sj elementos (el primero del primer
conjunto, el segundo del segundo conjunto...); para el ltimo conjunto (S), el
elemento que se debe incluir en la combinacin i-sima (y que aparecer en la
ltima posicin de la combinacin) es el elemento de S dado por la expresin
i%\S\ (en donde % representa el resto de la divisin entera). Dada una posicin
arbitraria i de un caso de prueba (en el ejemplo, dado un nmero arbitrario entre 0
y 23), la posicin de cada conjunto Sj que se debe incluir en la combinacin
depende del nmero de valores en Sj + SJ+2... S. El valor seleccionado del
conjunto j-simo para la combinacin i-sima es el elemento de Sj situado en la
posicin dada por la expresin que aparece en la Figura 5.10.

i
p o sic i n D e lV a lo r(j,i ) =
divisoresj %1-S/l

Figura 5.10. Clculo del valor del conjunto j-simo para la combinacin i-sima.

Divisoresj es el producto de los cardinales de los conjuntos que van desde


Sj hasta S, y es 1 para S. Para los conjuntos A, B y C de nuestro ejemplo (pgina
69), los divisores son:

divisoresA=|B| jC|=3-2=6 divisoresB=|C|=2 divisoresc=l

Por tanto, la fncin mostrada en la Figura 5.9 se puede reescribir y


dejarla como en la Figura 5.11: ahora, dentro del primer bucle hay otro bucle
anidado que va calculando los divisores de cada conjunto. En el segundo bucle
extemo, getCombinacin toma ahora tres parmetros:

La lista de conjuntos (S).

La posicin de la combinacin que se desea obtener (/).

Los valores de divisores.


74 TECNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

function productoCartesiano({S }) : Set(Combinacin) {


nmeroDeCombinaciones : int = 1;
divisores : int[] = new int [|S |]
for (i=0; i < ISI ; i++) {
nmeroDeCombinaciones = nmeroDeCombinaciones * |S, |
divisores[i]=1
for (j=0; j < ISI ; j++) {
divisores [i] =divisores [i] * |S3]
}
}
resultado : S e t (Combinacin)=0
for (i=0; i< nmeroDeCombinaciones; i++) {
resultado= resultado d getCombinacin(S, i,
divisores)
}
return resultado
J ____________________________________________________________
Figura 5.11. Algoritmo iterativo para obtener el producto cartesiano de n conjuntos (versin 2)

Finalmente, la funcin getCombinacin queda como en la Figura 5.12:

function getCombinacin(S, posicin, divisores) : Combinacin {


resultado : Combinacin = new int[|s|]
for (int i=0; i<|S|; i++) {
resultado[i] = (posicin/divisores[i])% |S41
}
return resultado
_}_____________________________________________________________________
Figura 5.12. Algoritmo para obtener una combinacin arbitraria

Para un conjunto dado de valores de prueba, all combinations consigue


siempre la mxima cobertura posible en el sistema bajo prueba, adems de
conseguir cobertura total n-wise (donde n es el nmero de parmetros) y, desde
luego, each use y pairwise. Sin embargo, es tambin la que produce ms casos de
prueba y, probablemente, muchos de ellos sean redundantes.

5.3.2 Cada eleccin (Each choice)


El objetivo de esta estrategia de combinacin es la creacin de casos de
prueba de manera que cada valor interesante se utilice, al menos, en un caso de
prueba, logrando, por tanto, cobertura each use. El algoritmo, entonces, es sencillo:
mientras haya valores no visitados, se construye una combinacin vaca. Si un
conjunto tiene algn valor no utilizado, se coloca en la posicin que corresponda de
O RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 75

la combinacin; en otro caso, se toma otro valor (puede ser aleatoriamente, el que
menos veces se haya utilizado, el que el tester considere ms oportuno, etc.).

Una aplicacin del algoritmo sobre el ejemplo de los conjuntos A, B y C va


produciendo los resultados de la Tabla 5.6: se muestra, para cada iteracin, los
casos de prueba que se van seleccionando y, tachados, los valores que visita cada
caso en cada iteracin. Ntese que el algoritmo para cuando se han visitado todos
los valores al menos una vez.

Iteracin Casos de prueba Valores visitados


A={1, 2, 3,4}
0 Ninguno B={5, 6, 7}
C={8, 9}
A={4=, 2, 3, 4}
1 (1,5, 8) B={, 6, 7}
C={S, 9}
A={+,, 3,4}
(1,5, 8)
2 B={&, , 7}
(2, 6, 9)
C={8,9}
(1,5,8) A = {7,7,7,4 }
3 (2, 6, 9) B={, , 7=}
(3, 7, 8) C={&, 9}
(1,5, 8)
A={4,3, 7, 4}
(2, 6, 9)
4 B={, , 7}
(3, 7, 8)
C={$,9}
(4, 6, 9)
Tabla 5.6. Aplicacin de each choice al ejemplo de los conjuntos A, B y C

5.3.3 AETG (.Automatic Efficient Test Generator)


Este algoritmo, descrito por Cohen et l.15 y reproducido en la Figura 5.13,
genera, en tiempo polinomial, un conjunto de casos de prueba de tamao aceptable
que consigue cobertura de valores pairwise.

15 Cohen, D.M., Dalai, S.R., Kajla, A. y Patton, G.C., 1994, The automatic efficient test generator
(AETG) system, proceedings of Fifth International Symposium on Software Reliability Engineering
(ISSRE94), IEEE Computer Society Press, Los Alamitos, California, 303-309.
76 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

En un sistema con k parmetros, supngase que el parmetro i-simo tiene li


valores.
Supongamos que ya se han seleccionado r casos de prueba. El caso (r+l)-simo se
construye a partir de M casos de prueba candidatos y eligiendo aquel que cubra
ms pares nuevos. Cada caso candidato se selecciona por medio del siguiente
algoritmo voraz:
Elegir el parmetro / y un valor / de / tal que el valor del parmetro aparezca
en el mayor nmero de pares no cubiertos.
Sea fi = f elegir un orden aleatorio para los restantes parmetros, de manera
que los k parmetros quedan ordenados: f]...fk.
Supongamos que ya estn elegidos los valores para los parmetros//... f. Sea
v, el valor seleccionado para f (1 < i < j ). Para elegir el valor v,+/ del
parmetro fj+, se cuenta el nmero de pares {f+i = v y f = v para for 1 < i<
j}. El valor v,+/ que se selecciona es aquel que aparece en mayor nmero de
pares. Obsrvese que, en este paso, solo se considera una vez la inclusin de
cada valor del parmetro, y que, al elegir el valor para el parmetro fj+i, los
valores se comparan con los j valores ya elegidos para los parmetros
Figura 5.13. Pseudocdigo original del algoritmo AETG

Como se observa, el segundo paso del algoritmo introduce un factor de


aleatoriedad al ordenar al azar los parmetros cuyos valores estn pendientes de ser
elegidos. En la Figura 5.14 se ofrece una versin determinista de AETG que
elimina el factor azaroso y que aplicaremos al ejemplo de los parmetros A, B y C.

Construir las tablas de pares (tablasDePares) para S, el conjunto de parmetros.


Sea c la primera combinacin que se elige, y sea c la primera combinacin (la
0 ).

Aadir c al resultado.
Actualizar tablasDePares con los pares visitados por c.
Mientras haya pares no visitados en tablasDePares:
Inicializar c, colocando el valor que visita ms pares no visitados en
pairTables.
Completar c con valores compatibles de los restantes parmetros, de manera
que se visite el mayor nmero de pares.
Aadir c al resultado.
Actualizar tablasDePares con los pares visitados por c.
Figura 5.14. Versin determinista de AETG
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 77

Al aplicar la versin determinista de AETG a A, B y C, elegimos, en primer


lugar, la combinacin 0: resultado={(l, 5, 8)} y marcamos los pares visitados: (1,
5), (1, 8) y (5, 8). En la Tabla 5.8 se muestran las tablas de pares y la iteracin en
la que se visita cada par (el 0 corresponde a los pasos 1 a 4 del algoritmo, que se
ejecutan antes del bucle). Como quedan pares no visitados, se entra en el bucle y se
selecciona el valor que visita ms pares. Con objeto de elegir correctamente el
valor que visita ms pares (paso 5.1 del algoritmo de la Figura 5.14), en la Tabla
5.7 se muestra el nmero de pares visitados por cada valor en cada iteracin del
bucle mientras:

1. resultado= {(1, 5, 8)}.


2. La primera vez que se entra al bucle, el elemento que visita ms pares
nuevos (lnea 5.1 del algoritmo) es el 9 del conjunto C, que visita siete
pares. Por tanto, se construye una combinacin c=(-, 9). A
continuacin (lnea 5.2), se completa c con valores compatibles de los
restantes parmetros. Puesto que estamos aplicando la versin
determinista del algoritmo, continuamos completando la combinacin
por el primer parmetro (A): puesto que en la combinacin c hay un
elemento del conjunto C, nos fijamos en la tabla (A, C) y
seleccionamos el valor que ms pares visite de los elementos 1, 2, 3, y
4, ya que los pares (1, 9), (2, 9), (3, 9) y (4, 9) no han sido visitados
todava. Se selecciona el primer valor (1) y la combinacin queda
como (1, 9). Para completar con el valor de B, debemos elegir un
valor compatible con el 1 de A y el 9 de C, pudiendo aadir el 6, con lo
que c=(l, 6, 9) y resultado={(l, 5, 8), (1, 6, 9)}.
3. En la siguiente iteracin, el valor que visita ms pares no visitados es
el 7 del conjunto B, con lo que c=(-, 7, -). Para elegir el elemento de A
que se colocar en c, consideramos que, en (A, B), el 7 visita los pares
no visitados (1, 7), (2, 7), (3, 7) y (4, 7); al haber empate, el algoritmo
elige el 1, con lo que c={l, 7, -}. De C, se visitan los pares no visitados
(7, 8) y (7, 9), por lo que se elige el 7, resultado={(l, 5, 8), (1, 6, 9),
(1, 7, 8)} y se actualizan las tablas de pares y el nmero de pares
visitados por cada valor de cada parmetro.
4. Se contina de la misma manera, seleccionando los valores de la
manera descrita, actualizando las dos tablas:
- c={2, -), (2, 5, -), (2, 5, 9)
- c =(3, -), (3, 5, -), (3, 5, 8)
- c=(4, - -), (4,5, -), (4, 5, 8)
- c =(-, 6, -), (2, 6, -), (2, 6, 8)
78 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

- c=(-, 7,-), (2, 7,-), (2, 7,9)


- c =(3, -), (3, 6, -), (3, 6, 9)
- c = (4 ,-,-),(4 ,6 ,-),(4 ,6 ,9 )
- c =(-, 7, -), (3, 7, -), (3, 7, 8)
- c =(4, - -), (4, 7, -), (4, 7, 8)

5. Finalmente, resultado={(l, 5,8), (1, 6, 9), (1, 7, 8), (2,5, 9), (3, 5, 8),
(4, 5, 8), (2, 6, 8), (2, 7, 9), (3, 6,9), (4, 6, 9), (3, 7,8),(4, 7, 8)}

Conjuntos (parmetros) y sus elementos


(valores)
A B c

Iteraciones 1 2 3 4 5 6 7 8 9
0 3 5 5 5 4 6 6 5 7
1 1 5 5 5 4 4 6 5 5
2 0 5 5 5 4 4 4 3 5
3 0 3 5 5 2 4 4 3 3
4 0 3 3 5 1 4 4 3 3
5 0 3 3 3 0 4 4 2 3
6 0 1 3 3 0 2 4 0 3
7 0 0 3 3 0 2 2 0 2
8 0 0 1 3 0 1 2 0 1
9 0 0 1 1 0 0 2 0 0
10 0 0 0 1 0 0 1 0 0
11 0 0 0 0 0 0 0 0 0
Tabla 5.7. Pares visitados por cada valor en las distintas iteraciones de la versin determinista
deAETG
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 79

(A, B) (A, C) (B, C)

Pares Visitas Pares Visitas Pares Visitas

(1,5) 0 0 ,8 ) 0,2 (5, 8) 0, 4,5

0 ,6 ) 1 (1,9) 1 (5,9) 3

(1,7) 2 (2, 8) 6 (6, 8) 6

(2, 5) 3 (2, 9) 3,7 (6, 9) 1,8,9

(2, 6) 6 (3, 8) 4, 10 (7, 8) 2, 10, 11

(2, 7) 7 (3,9) 8 (7, 9) 7

(3,5) 4 (4, 8) 5, 11

(3,6) 8 (4, 9) 9

(3, 7) 10

(4, 5) 5

(4, 6) 9

(4, 7) 11

Tabla 5.8. Tablas de pares e iteraciones en que son visitados los pares de los parmetros A, B y C

5.3.4 PROW (Pairwise with Restrictions, Order and Weight)


La mayora de los algoritmos de testing combinatorio no tienen en cuenta
las restricciones entre pares. Es muy comn que determinadas combinaciones de
pares no estn permitidas en el sistema bajo prueba. En el ejemplo de la seccin
anterior, podra ocurrir que, entre los conjuntos B y C, el par (6,9) no estuviera
permitido por alguna razn. En este caso, no tendra sentido incluir este par en
ningn caso de prueba.

Los casos de prueba obtenidos con AETG en la seccin anterior son:

{(1, 5, 8), (1, 6, 9), (1, 7, 8), (2, 5, 9), (3, 5, 8), (4, 5, 8), (2, 6, 8), (2, 7, 9),
(3, 6, 9), (4, 6, 9), (3, 7, 8), (4, 7, 8)}
80 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Pero si el par (6, 9) no est permitido, entonces el caso de prueba (1, 6, 9)


que aparece en el resultado no es un caso de prueba vlido. Si eliminsemos este
caso de prueba del test suite, lo que sucedera es que los pares (1,6) entre A y B y
(1,9) entre A y C quedaran sin ser visitados, porque no se lograra la cobertura
pairwise deseada.

El algoritmo PROW ha sido ideado por los autores de este libro y da una
solucin a este problema. Las principales caractersticas de este algoritmo son:

Restricciones entre pares: permite la eliminacin a priori de los pares


de valores de parmetros que no sean vlidos.

Priorizacin de los casos de prueba: permite asignar un peso a cada


par, de forma que los casos de prueba pueden ser ordenados segn el
peso.

Para explicar el algoritmo usaremos como ejemplo los parmetros de la


Tabla 5.9: la aplicacin bajo prueba incluye distintas combinaciones de Sistema
Operativo, Navegador y Procesador de texto. Por determinadas razones, los
siguientes pares entre valores no son vlidos y deben ser eliminados antes de
obtener los casos de prueba: (Linux, IExplorer), (Linux, Microsoft Word), (Mac,
1Explorer), (Mac, MicrosoftWord) y (Windows, Opera).

Sistema Operativo Navegador Procesador de texto

Linux Firefox Microsoft Word

Windows IExplorer Open Office

Mac OS Opera Feng Office

Chrome Google Docs

Tabla 5.9. Parmetros y valores para el ejemplo de PROW

La Figura 5.15 muestra los pares generados para el ejemplo. Las tablas de
pares contienen dos columnas extras: Remove y Sel Factor. La columna Remove
indica si dicho par debe ser borrado antes de que el algoritmo genere los casos de
prueba; la columna Sel Factor permite asignarle un peso a dicho par. Una de las
propiedades de pairwise es que, cuando los parmetros tienen distinto nmero de
valores, los valores de los parmetros con menos valores se incluyen ms veces
para obtener la cobertura pairwise. En el ejemplo, ese es el caso del parmetro
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 81

Sistema Operativo. Cubrir todos los pares al menos una vez requiere incluir los
valores de Sistema Operativo, que solo tiene tres valores. Pero como no todos los
pares tienen la misma prioridad para las pruebas, el tester puede estar interesado en
darle ms prioridad a los pares que, por ejemplo, vayan a tener ms frecuencia de
aparicin o uso en el entorno de produccin. En nuestro ejemplo, al par (Linux,
Firefox) se le ha asignado un peso de 1, mientras que al par (Linux, Chrome) un
peso de 0,3. Con esto, el tester quiere expresar que es ms importante probar la
combinacin de Linux con Firefox que con el navegador Chrome. En el algoritmo
PROW, el peso de los pares se utiliza en el momento de visitar ms de una vez un
par.

La Tabla 5.10 describe el pseudocdigo del algoritmo PROW, el cual se


basa en el algoritmo AETG, modificndolo para permitir el borrado de pares y la
asignacin de pesos. PROW tiene un orden de ejecucin (coste) polinomial.

La Tabla 5.11 muestra, paso a paso, la forma en que se obtienen los casos
de prueba mediante PROW. Al igual que en AETG, PROW construye los casos de
prueba por iteraciones. Cada caso de prueba se inicializa con el valor que visite
ms pares an no visitados. Cada fila de la Tabla 5.11 muestra los pares an no
visitados de cada valor al comenzar la iteracin. Para la primera iteracin, Linux y
Mac OS aparecen en 6 pares y Windows en 7. El algoritmo selecciona el valor
Windows y completa el caso de prueba seleccionando los valores Firefox y Open
Office, ya que son los que visitan ms pares an no visitados y maximizan el peso
de la combinacin, que es 1.3: selFactor (Windows, Firefox) + selFactor
(Windows, Open Office) + selFactor (Firefox, OpenOffice) = 0.8 + 0.5 + 0 = 1.3.

16 pairs in (1, 2)
Elements Remove Sel. factor
12 pairs ib (0,1) 12 pairs in (0. 2) (Frefox. Microsoft Word) m 00
Elements Remove SeL factor Elements Remove SeL factor (Firefox Google Docs) 00
|(L*wx, Firefox) H 1 (Linax. Microsoft Word) m 00 (Firefox, Open Office) 00
(L*hk , Chrome) n 03 (Linux. Google Docs) 02 (Firefox, Feng Office) 00
:(Linux. Explorer) a 00 {Linux, Open Office) 1 (Chrome Microsoft Word) 00
(Lian, Opera) B 08 (Linux, Feng Office) 08 (Chrome. Google Docs) 00
(Windows, Fkefox) B 08 (Windows, Microsoft Word) m 1 (Chrome Open Office) 00
(Windows, Chrome) e? 03 (Windows, Google Docs) o 04 (Chrome, Feng Office) E 00
(Windows, Explorer) m 1 (Windows. Open Office) o 05 (Explorer Microsoft Word) D 1
(Windows, Opera) m 00 (Windows, Feng Office) O 02 (Explorer, Google Docs) B 00
(Ma: OS, Firefox) E 11 (Mac OS, Microsoft Word) m 00 (Explora Open Office) 00
(Mac OS, Chrome) B 08 (Mac OS, Google Docs) o 06 (Explora. Feng Office) B 00
(Mac OS, Explorer) * 00 (Mac OS, Open Office) 1 (Opera, Microsoft Word) E 00
(Mac OS, Opera) a 03 (Mac OS, Feng Office) 02 (Opera. Google Docs) B 00
(Opera, Open Office) 00
(Opera Feng Office) 00

Figura 5.15. Tabla de pares con pares borrados y pesos


82 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Entrada: S (conjunto de parmetros con valores) y pairTables (tabla de


pares con los pares borrados y los pesos asignados a cada para vlido).
Algoritmo PROW:
Mientras existan pares no visitados en pairTables y continue:
- Inicializar c con el valor que visite mas pares an no visitados en
pairTables.
- Completar c con los valores de los parmetros restantes, teniendo en
cuenta que:
o Los pares cubiertos por c existan en pairTables.
o Los valores seleccionados tomados conjuntamente visiten la
mayor cantidad de pares an no visitados.
o El peso de la combinacin c sea mximo.
- Si c cubre al menos un par no visitado an:
o Agregar c al conjunto de casos de prueba,
o Actualizar pairTables con los pares visitados por c.
- Si no, (continue := false).
El conjunto de casos de prueba se ordena segn el peso de sus pares.
Salida: conjunto de casos de prueba ordenados por peso.

Tabla 5.10. Pseudocdigo del algoritmo PROW

As, el algoritmo selecciona en cada paso la mejor combinacin de valores:


en el paso 4, por ejemplo, se selecciona Windows, pues es el valor que visita ms
pares no visitados, con lo que el caso de prueba va siendo: {Windows, -, - }. Para el
Navegador, el valor Opera es el que tiene ms pares no visitados, pero el par
(Windows, Opera) ha sido eliminado, por lo que no se selecciona. Entonces, el par
(Windows, IExplorer), que tiene peso 1, es seleccionado. Ahora, el caso de prueba,
an incompleto, es: {Windows, IExplorer, -}. Todos los valores para Procesador de
Texto tienen 5 pares no visitados: el par (Windows, Word) tiene peso 1, por lo que
el caso de prueba resultante para el paso 4 es: {Windows, IExplorer, Word}, siendo
2 el peso de este caso de prueba.

Dado que el algoritmo PROW permite el borrado de pares, es posible que


algunos pares no se visiten nunca, como el caso del par (Opera, Microsoft Word),
el cual nunca puede ser visitado porque no es posible encontrar una combinacin
de valores en la que se incluya este par. Por lo tanto, este par queda como no
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 83

visitado hasta el final del algoritmo. En el paso 16 del algoritmo ( Tabla 5.11),
solamente quedan dos valores con pares por visitar: Opera y Word. Se selecciona
Opera. Para el Sistema Operativo puede seleccionarse Linux o Mac. Se selecciona
Linux. Para el Procesador de Texto no puede seleccionarse Word debido a que el
par (Linux, Word) fue borrado. PROW, entonces, selecciona OpenOffice otro valor.
El caso de prueba resultante es {Linux, Opera, OpenOffice}. Sin embargo, como
todos los pares visitados por este caso de prueba se han visitado previamente, el
algoritmo termina.
S.O. Navegador Procesador de Texto Peso
Paso Caso d e Prueba
i intu Windows Mac Firefox texpforer Opera Chrome Word Open Feng Google Total
1 6 7 6 7 5 6 7 5 7 7 7 {Windows.Freox,OpenOffice} 0.8
2 6 5 6 5 5 6 7 5 5 7 7 {Linux, Chrome, FengOffice] 1.1
3 4 5 6 5 5 6 5 5 5 5 7 {Mac. Opera. Google} 0.9
4 4 5 4 5 5 4 5 5 5 5 5 {Windows, i Explorer,Word} 2
5 4 3 4 5 3 4 5 3 5 5 5 (Linux, Firefox, Google} 1.2
6 2 3 4 3 3 4 5 3 5 5 3 {Mac, Chrome, OpenOffice} 18
7 2 3 2 3 3 4 3 3 3 5 3 {Windows, iExplorer, Feng} 1.2
8 2 2 2 3 2 4 3 3 3 3 3 {Linux, Opera, OpenOffice} 1.8
9 0 2 2 3 2 2 3 3 1 3 3 (Mac, Firefox, Feng} 1.2
10 0 2 0 1 2 2 3 3 1 1 3 {Windows, Chrome, Google} 07
11 0 0 0 1 2 2 1 3 1 1 1 {Windows, Firefox, Word] 18
12 0 0 0 0 2 2 1 2 1 1 1 {Windows, lExpSorer, OpenOffice} 1
13 0 0 C 0 1 2 1 2 0 1 1 (Linux, Opera. Feng} 1.6
14 0 0 0 0 1 1 1 2 0 0 1 {Windows, Chrome, Word} 1.3
15 0 0 0 0 1 1 0 1 0 0 1 {Windows, Explorer. Googie} 1.4
16 0 0 0 0 0 1 0 1 0 0 0

Tabla 5.11. Algoritmo PROW paso a paso

Una vez obtenidos los casos de prueba, el algoritmo PROW los ordena
segn el peso. El resultado final del algoritmo puede verse en la Tabla 5.12. En
caso de que no se cuente con el tiempo suficiente para ejecutar todos los casos de
prueba, el tester puede ejecutarlos segn el orden establecido por el algoritmo, ya
que estar ejecutando primero los que ms importancia tienen para las pruebas.
C aso s d e P ru eb a P eso
{ W in d o w s, E x p lo re r, M ic ro s o ft W o rd } 2 .0
{M ac OS, C h r o m e , O p e n O ffice} 1 .8
{ W in d o w s, F ire fo x , M ic ro s o ft W ord} 1 .8
{Linux, O p e r a , O p e n O ffic e } 1.8
{Linux, O p e r a , F e n g O ffice} 1.6
{ W in d o w s, (E x p lo re r, G o o g le Docs} 1.4
{ W in d o w s, C h r o m e , M ic ro s o ft W ord} 1.3
{M ac OS, F ire fo x , F e n g O ffice} 1.2
{ W in d o w s, E x p lo re r, F e n g O ffic e } 1.2
{Linux, F ire fo x , G o o g le Docs} 1 .2
{Linux, C h r o m e , F e n g O ffic e } 1.1
{ W in d o w s , E x p lo re r, O p e n O ffice} 1 .0
{M ac OS, O p e r a , G o o g le Docs} 0 .9
{ W in d o w s, F ire fo x , O p e n O ffice} 0 .8
{ W in d o w s, C h r o m e , G o o g le Docs} 0 .7

Tabla 5.12. Casos de Prueba obtenidos con el algoritmo PROW y el peso asociado
84 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS...______ RA-MA

5.3.5 Antirandom
Antirandom es una estrategia de combinacin propuesta por Malayia16:
partiendo de un caso de prueba te en el test suite, el siguiente en ser elegido (sea
te2) es aquel que resulte ms diferente de tc. El tercer caso (sea teA es el que sea
simultneamente ms diferente de tc y tc2. El siguiente, el ms diferente de los
tres ya seleccionados.

El concepto de diferencia se calcula en funcin de la distancia Hamming


entre la codificacin binaria de los casos de prueba. Para cada parmetro se utilizan
tantos bits como sean necesarios para codificar sus valores: para A, que tiene 4
elementos, se utilizarn 2 bits; para B, que tiene 3 elementos, se requieren tambin
2 bits (uno de los elementos recibir dos codificaciones); y para C, que tiene 2
elementos, basta un bit (Tabla 5.13).

A |J c
Valor Bits Valor Bits Valor Bits
1 00 5 00 8 0
2 01 6 01 9 1
3 10 7 10
4 11 7 11
Tabla 5.13. Codificacin binaria de los elementos de A, B y C

El primer caso de prueba puede ser el correspondiente a los valores (1, 5,


8), cuya representacin binaria es 00000. La distancia Hamming entre dos palabras
binarias es el nmero de bits diferentes entre ambas palabras, por lo que el
siguiente caso de prueba en ser elegido ser el que corresponda a la palabra 11111,
que es el (4, 7, 9).

Para el siguiente caso, se suman las distancias Hamming de cada posible


caso a los dos ya elegidos. Como se ve en la Tabla 5.14, en la primera iteracin del
algoritmo la suma de distancias Hamming es siempre 5. Para elegir un caso cuando
hay empates, como en esta situacin, se calcula la distancia cartesiana, que es la
suma de las races cuadradas de las distancias Hamming y que se muestra en la

16 Malaiya, Y.K., 1995, Antirandom testing: getting the most out o f black-box testing, proceedings of
the International Symposium on Software Reliability Engineering (1SSRE95), Toulouse, Francia,
IEEE Computer Society Press: Los Alamitos, California, 86-95.
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 85

ltima columna de la tabla: ahora s, se toma, por ejemplo, el primer caso con
distancia 3,15, que es la palabra 01001 y que corresponde al caso (2, 5, 9).

Distancias Hamming
Distancia
Caso Al caso 00000 Al caso 11111 Total
cartesiana
00001 1 4 5 3
01000 1 4 5 3
01001 2 3 5 3,15
01010 2 3 5 3,15
01011 3 2 5 3,15
01100 2 3 5 3,15
01101 3 2 5 3,15
01110 3 2 5 3,15
01111 4 1 5 3
10000 1 4 5 3
10001 2 3 5 3,15
10010 2 3 5 3,15
10011 3 2 5 3,15
10110 3 2 5 3,15
10111 4 1 5 3
11000 2 3 5 3,15
11001 3 2 5 3,15
11010 3 2 5 3,15
11011 4 1 5 3
11100 3 2 5 3,15
11101 4 1 5 3
lino 4 1 5 3,15
Tabla 5.14. Distancias Hamming en la primera iteracin del algoritmo Antirandom
86 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

5.3.6 Algoritmo del peine (Comb)


Este algoritmo est ideado por los autores de este libro y est inspirado en
Antirandom. Una de las desventajas de Antirandom es que, para seleccionar el
siguiente caso de prueba, deben calcularse las distancias Hamming o cartesiana a
cada uno de los casos del test suite, lo que supone un coste computacional muy
alto.

Puesto que el mximo nmero de combinaciones es conocido ( J- ||s|),


i=l
donde n es el nmero de parmetros y S, representa el parmetro i-simo), Comb
toma, como primer caso de prueba, el que se encuentra en la primera posicin (el
0); a continuacin, aade al test suite el ms alejado (en el ejemplo de los conjuntos
A, B y C, el 23); despus, el que se encuentre a la misma distancia de ambos (el
12); luego, el que se encuentre equidistante entre el 0 y el 12 y otro que se
encuentre equidistante entre el 12 y el 23 (el 18). El algoritmo evoluciona de esta
forma hasta que se haya generado el nmero de casos preestablecido. La
equidistancia que se va manteniendo entre las combinaciones elegidas puede
recordar a las pas de un peine (en ingls, comb), motivo por el cual se lo ha
bautizado de esta manera.

5.3.7 Algoritmos aleatorios


Los algoritmos aleatorios generan casos de prueba al azar, siguiendo a
veces alguna distribucin de probabilidad. Un posible algoritmo de este tipo puede
guardar en una lista n nmeros aleatorios entre 0 y el nmero mximo de
combinaciones menos 1 y, luego, recorrer la lista mediante la funcin
getCombinacin (Figura 5.12) para obtener los casos de prueba que correspondan.

5.4 CTWEB, UNA APLICACIN WEB PARA TESTING


COMBINATORIO
CTWeb es una aplicacin web (disponible en alarcosj.esi.uclm.es/CTWeb)
en la que se implementan diversas estrategias de testing combinatorio, entre ellas
todas las mencionadas en la seccin anterior.

La siguiente figura muestra la pgina principal de la aplicacin, que se ha


cargado con los datos que se obtienen al pulsar el botn Play example. Este
ejemplo representa los diferentes elementos necesarios para construir juegos de
mesa: hay seis parmetros (de la A a la F) y cada uno tiene una serie de valores: A
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 87

(que representa el juego) toma los valores Ludo, Trivial, Checkers y Chess
(respectivamente: parchs. Trivial Pursuit, damas y ajedrez); B toma Dice cuando el
juego requiere dados, y nuil en otro caso; C denota al jugador oponente que puede
ser una persona o el ordenador; D indica el nmero de jugadores (2 o 3); E
representa el mtodo de pago (tarjeta Visa, Master Card o American Express) y F
denota si el juego lleva un sistema de preguntas o no, lo cual es aplicable para el
caso del Trivial Pursuit.

El funcionamiento de la aplicacin es sencillo: se introducen los datos en la


matriz de cajas de texto (se aaden parmetros pulsando el botn Add set, y se
aaden valores pulsando Add row), se selecciona en la izquierda la estrategia de
combinacin que se desea aplicar, se pulsa el botn Execute y la aplicacin
devuelve, en el lado inferior, los resultados.

Combinatorial testing page


Cite diis te as: Polo M . a n d Prez B . (20 JOK A fram ework a nd a web implementation fo r combinatorial testing. White paper o f the Atareos Research Group. Available at (current date);
hnpu/aiarcosj .estMclm.esiCTWeb
Find o f all, we add so many columns as sets we need (with die A dd set button), and sow many tows (A dd row ) as elements
>:.v. e xam gt )
Please, press die Play example button to continue.
Upload feature model file Upload variables file (asg example o f idUtShHC?______________________________________ ___________ ______
D ata

G Each choice Iverv low cost) A


(3 Antirandom (exponential cost) 0 Ludo
C'Comb (lineal cost!
GGsaefe;
O Costiv pairwise (exponential cost'i
1 "itwisi.......
2 Chcfc*i IAmerican express
OAETGQ 3
Expression to generate test cases:
Example
O Customizable pa>Vtse.(ponmM.cost) public void testTCNUMBER {
O Bacteriologic ClassUnderTesi o=new ClassUndeiTest(#A, #B);
O R*n4ofn fliaeal cost) o. method !(#C);
(dmkumJ double reailt=ojnetbod2(#C, #B, #A);
Verbose: ;>
........... .........." r 1
Additional stuff
Algorithms in Excel, developed by fos Antonio Cruz.

Developed by Macario Polo Usaola and Beatriz Prez Lamancha


Atareos Group
Department of Information Systems and Technologies
University of C'astiila-La Mancha
Spain

Figura 5.16. Pgina principal del sistema CTWeb, cargada con datos de ejemplo

El tester puede utilizar el rea de texto situada bajo la etiqueta Expression


to generate test cases para escribir una expresin que le permita generar el cdigo
de datos o casos de prueba. Supongamos que los casos de prueba consisten en la
creacin de una instancia de clase Game (juego) y, a continuacin, en la asignacin
de los diferentes posibles elementos (dados, oponente, etc.). En esa zona de texto
podemos escribir cdigo u otro tipo de texto que haga referencia al valor de cada
conjunto de cada combinacin, utilizando el smbolo almohadilla seguido de la
letra correspondiente a cada conjunto (Figura 5.17).
88 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Expression to generate test cases:


C a rn e g - n e w # A 0
g .s e tD ic e (# B ):
O p p o n e n t o p p = n e w #CQ;
g .s e t O p p o n e n t ( o p p ) ;
g .s e tP !a y e r s (# D );
g .s e t P a y m e n t M e t h o d ( # ) ;
g .s e t Q u iz ( # f ) ;
a

Figura 5.17. Cdigo de ejemplo para generar casos de prueba con cdigo

As, a partir del ejemplo mostrado, y para el ejemplo de los juegos de


mesa, la herramienta devuelve los resultados con el algoritmo AETG que aparecen
en la Figura 5.18: en la primera columna aparece el nmero de combinacin; en la
segunda, los elementos que la componen; y en la tercera y ltima, el cdigo que
procede de sustituir los valores de los conjuntos A a F en el texto mostrado en la
Figura 5.17. Ms abajo se indica el tiempo que ha tardado el servidor en realizar el
cmputo y el porcentaje de pares de valores (es decir, la cobertura pairwise) que
visita el test suite.

Algorithm netgn
I Results fur 192 combinations
{Trivial .null.Computer 3 -Master Game g=new TriviaiQ; g.setDice(null); Opponent opp=new Computed); g.setOpponent(opp); g.setPlayers(3);
; jord.-} jg.setPaymentMcthod(Master card); g.setQuiz(-);
. {Trivial .nullPerson .3 American Game g=new TrivialO: g.setDice(null); Opponent opp=new PersonO; g.setOpponent(opp); g.setPlayenf3);

Game g=new TrivialO; g.setDice(Dice); Opponent opp=new PersonO; g.setOpponent(opp); g.setPlaycrs(2);


j|{Trvial .Dice.Person,2,Visa,Quiz}
g.setPaymentMethod(Visa); g.setQuiz(Quiz);
1 Game g=new LudoO; g.setDice(null); Opponent opp=new Computed); g-setOpponent(opp); g.setPlayers(2);
1(Ludo rOull .Computer2 ,Visa,-}
g.setPaymentMethodfVisa); g.setQuiz(-);
{LudoxuUPerson^ American Game g=new LudoO'. g.setDice(null); Opponent opp=new PersonO: g.setOpponent(opp); g.setPlayers(3);
express,-} g.setPay raentMethod (A menean express); g.setQuizt-);
{Ludo,Dice,Computex3.Master Game g=oe* LudoO: g setDice(Dicc). Opponent opp=new ComputcrO; g .setOpponcnttopp): g ,setPla>ro(3);
card .Quiz} g.setPaymentMetbod(Mastercard); g.setQuiz(Quiz);
Ciamc g=ncu ChessO. g setDicc(null); Opponent opp=ncw ComputcrO: g setOpponcnttopp); g.sctPlayers(3);
{Chessjtull.Computer3.Visa,Quiz}
g.setPay mentMethod(Visa); g.setQuiz(Quiz):
{Chess.null .Computer 3 .American (iame g=new ChessO- g.sctDice(nui!); Opponent oppsnew Computed); g setOpponcnttopp); g.sctPlayers(3),
express.-} g setPaymentMethod(American express); g.setQuiz(-);
Game g=ncw ChessO: g.setDice(Dice); Opponent opp=new PersonO; g.sctOpponent(opp); g.setPlayers(2);
{Chess .Dice.Person 2 Master card,-}
g .setPaymentMethod (Master card); g ,setQuiz(-);
{Checkers,nuli,Coroputer3 .Master Game g=new CheckersO; g.setDice(null); Opponent opp=new ComputcrO; g.setOpponent(opp);
[card,-} g.setPiaycrs(3); g.setPay mcnlMethod (Master card); g.sctQuiz(-);
Game g=ncw CheckersO; g.sctDicc(null); Opponent opp=new ComputcrO; g.setOpponcnttopp);
{Checkers .null.Computer 3 .Visa,-} g.sctPlaycrs(3); g.setPaymentMcthod(Visa); g.sctQuiz(-);

|{Chcckcrs,null,Computer3 American Game g=ncw CheckersO; g.sctDicc(null); Opponent opp=new ComputcrO; g.setOpponcnttopp);
' Sexpress, } g.setPiayers(3): g.setPaymentMethod(American express); g.setQuiz();
{CheckersT)icePerson3 American Game g=new CheckersO; g.setDice(Dice); Opponent opp=new PersonO: g.setOpponent(opp); g.setPlayers(2);
iexpress.Quiz} g.setPaymentMethod(Amcricac express); g.setQuiz(Quiz);

Computed in 15 milliseconds
Pairs visited: 100.0%

Figura 5.18. Resultados de aplicar AETG a los datos de los juegos de mesa con el cdigo
de la Figura 5.17
RA-MA CAPTULO 5. ESTRATEGIAS DE COMBINACIN PARA LA OBTENCIN DE... 89

5.5 EJERCICIOS
1. Se dispone de un sistema que permite realizar conversiones entre diferentes
unidades de medida:
- De temperatura, entre grados Celsius, Fahrenheit y Kelvin.
- De longitud, entre metros, yardas, pulgadas, kilmetros y millas.
- De masa, entre kilogramos, libras y onzas.

Se pide que utilice la herramienta CTWeb para generar datos de prueba


con diferentes algoritmos, que sirvan para probar suficientemente este
sistema. Puede utilizar, por ejemplo, el algoritmo PROW para excluir de
los casos generados aquellos que conviertan entre medidas incompatibles
(de temperatura a longitud, por ejemplo).

2. En alarcosj.esi.uclm.es/ConversionMedidas se encuentra un sistema web


que implementa el sistema de conversiones de medidas indicado en el
ejercicio anterior. Observe {Figura 5.19) que la herramienta dispone de un
sencillo lenguaje de comandos para realizar conversiones entre unidades.
Se le pide que utilice las funcionalidades de CTWeb para generar una lista
de estos comandos y que trate de encontrar fallos en la aplicacin (los hay).
Indicaciones: no deben existir, por ejemplo, medidas de masa o de
longitud negativas, ni tampoco de grados Kelvin. Observe en la Figura
5.17 la forma en que CTWeb puede ayudarle a generar la lista de
comandos.

Figura 5.19. Dos comandos (izquierda) para convertir de kilmetros a metros y viceversa
Captulo 6

PRUEBAS MEDIANTE MUTACIN

La mutacin es una tcnica de pruebas que, tradicionalmente, se ha


utilizado en trabajos de investigacin para evaluar tanto la bondad de estrategias
de generacin como la calidad de test suites. Tras treinta aos de aplicacin a la
investigacin, la tcnica se encuentra hoy suficientemente madura como para ser
aplicada a nivel industrial. Este captulo presenta con detalle esta tcnica de
pruebas de software.

6.1 CONCEPTOS IMPORTANTES


Supongamos que debe usted contratar a una persona que debe actuar como
corrector ortotipogrfico en una editorial. Una posible forma de seleccionar, de
entre los candidatos, al ms adecuado, consiste en presentarles un texto con erratas,
faltas de ortografa o fallos de puntuacin, de manera que se contratar a aquel que
detecte el mayor nmero de lugares en donde el texto debe ser corregido. De este
modo, para el texto presentado en el lado izquierdo de la Figura 6.1, esperamos
que el mejor corrector detecte todos los errores artificialmente introducidos, que se
resaltan en su lado derecho.

Si, una vez contratado, presentamos al corrector un texto y no encuentra


ningn error en l, entonces, muy posiblemente, el texto est correctamente escrito
y puntuado, pues el corrector es altamente fiable y no ha encontrado ningn fallo.

Esencialmente, la mutacin consiste prcticamente en lo mismo: en la


generacin de versiones defectuosas (es decir, con uno o ms fallos sembrados,
inyectados o introducidos artificialmente) del programa que se va a probar, que son
ejecutadas por los casos de prueba del test suite. Si los casos de prueba encuentran
92 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... O RA-MA

todos los errores sembrados, entonces se dice que el test suite es adecuado para la
mutacin (mutation adequate). Para detectar los fallos, los casos de prueba se
ejecutan contra el programa original (sin fallos artificiales, con lo que se presume
que es correcto) y contra los mutantes: si, con un caso de prueba tc, se observa que
el mutante se comporta de manera diferente al programa original, entonces tc ha
encontrado el fallo introducido (o fallos introducidos) en el mutante y se dice que
el mutante est muerto; en otro caso (el comportamiento observado es el mismo),
se dice que el mutante est vivo. El primer objetivo de las pruebas mediante
mutacin consiste, precisamente, en evaluar la calidad de los test suites midiendo el
porcentaje de mutantes que se matan: en efecto, si nuestro test suite encuentra
todos los errores sembrados en los mutantes, entonces tenemos una garanta muy
alta respecto de la buena calidad del test suite. Adems, si el mismo test suite (que
detecta todos los fallos introducidos artificialmente) pasa por el programa original
(es decir, el programa que se est probando) sin encontrar ningn error, entonces
hay una garanta muy alta respecto de la buena calidad del programa bajo prueba.
Insistiendo en el smil del corrector ortotipogrfico, si este no encuentra ninguna
errata en un texto que se le pasa es porque el texto, probablemente, no tiene
ninguna.

Fragmento de La casada infiel, de Federico Garca Lorca


Y que yo me la llev al rio Y que yo me la llev al ro
creyendo que era mozuela, creyendo que era mozuela,
pero tenia marido. pero tena marido.
Fue la noche de Satniago Fue la noche de Santiago
y casi por conpromiso. y casi por compromiso.
Se apagaron los faroles Se apagaron los faroles
y se encendieron los grillos. y se encendieron los grillos.
En las ultimas esquinas En las ltimas esquinas
toqu sus pechos dormidos, toqu sus pechos dormidos,
y se me avrieron de pronto y se me abrieron de pronto
como ramos de jacintos. como ramos de jacintos.
El almidn de su enagua El almidn de su enagua
me sonaba en el oido, me sonaba en el odo,
como una pieza de seda como una pieza de seda
rasgada por diez cuchiyos. rasgada por diez cuchillos.
Sin luz de plata en sus copas Sin luz de plata en sus copas
los rboles han cresido, los rboles han crecido,
y un orizonte de perros y un horizonte de perros
b - 4 - L-
ladra muy lejos del rio. ladra muy lejos del ro.
Figura 6.1. Fragmento del poema La casada infiel con y sin errores
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 93

En el lado izquierdo de la Tabla 6.1 se ofrece un pequesimo ejemplo de


un programa que se desea probar (programa P) y que consiste en una sencilla
funcin Java que devuelve la suma de los dos nmeros que se le pasan como
parmetro. Debajo aparecen cuatro mutantes, cada uno de los cuales contiene una
modificacin sintctica: en los mutantes 1, 2 y 3, el operador + se ha sustituido por,
respectivamente, los operadores -, * y /; en el mutante 4 se ha respetado el operador
aritmtico, pero se ha aadido a la variable b un operador de posincremento (++).
En el lado derecho, aparecen cuatro posibles casos de prueba para este sistema, y se
muestran los resultados que devuelve cada uno de los cinco programas con los
datos de prueba: al ejecutar P con los parmetros 1 y 1, el resultado devuelto es 2;
no obstante, al ejecutar el Mutante 1 con los mismos valores, el resultado es 0, ya
que el + se ha sustituido por un El Mutante 2 devuelve tambin 1, porque lo que
realmente hace es multiplicar los dos valores; el Mutante 3 los divide, devolviendo
tambin 1. El Mutante 4, sin embargo, devuelve 2 (igual que P), ya que el valor de
b se incrementa despus de devolver el resultado, por lo que este no es observable
desde el exterior. De este modo, el caso de prueba (1, 1) mata a los mutantes 1, 2 y
3; el caso (0, 0) mata solamente al Mutante 3; (-1, 0) mata a los mutantes 2 y 3; por
ltimo, (-1, -1) mata a los mutantes 1, 2 y 3, ya que devuelven resultados distintos
del devuelto por el programa original. El Mutante 4, sin embargo, permanece vivo
con estos cuatro casos de prueba y, adems, permanecer siempre vivo y ser
imposible de matar, se le pase el caso de prueba que se le pase. A estos mutantes
cuyo comportamiento es siempre exactamente igual al del programa original se les
llama mutantes funcionalmente equivalentes o, simplemente, mutantes
equivalentes, y realmente representan ruido que dificulta el anlisis de los
resultados (es decir, conocer el porcentaje real de mutantes que mata el test suite).

Versin Cdigo
P (original) int su m (int a, int b)
{ Datos de prueba
return a + b;
} (1,1) (0,0) (-1,0) (-1,-1)
Mutante 1 int s u m (int a, int b)
p 2 0 -1 -2
{
return a - b;
Mutante 1 0 0 -1 0
}
Mutante 2 int su m (int a, int b) 1
Mutante 2 1 0 0
{
return a * b;
Mutante 3 1 Error Error 1
}
Mutante 3 int s u m (int a, int b) -1 -2
Mutante 4 2 0
{
return a / b;
i
Mutante 4 int s u m (int a, int b)
{
return a + b++;
J _______________________
Tabla 6.1. Un programa original (P), cuatro mutantes y los resultados de cada mutante con algunos
casos de prueba
94 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Para medir la calidad del test suite, por tanto, se necesita conocer el
nmero de mutantes generados, el nmero de imitantes muertos y el nmero de
mutantes equivalentes. La calidad se mide con el mutation score, que viene dado
por la expresin de la Figura 6.2.

P : programa bajo prueba

T : test suite

MS(P,T) = ----- 5donde: f . nmero de mutantes muertos


M E

M : nmero de mutantes generados

E : nmero de mutantes equivalentes

Figura 6.2. Clculo del mutation score

6.2 OPERADORES DE MUTACIN


En el ejemplo de la Tabla 6.2 hay cuatro mutantes, hay casos de prueba
que matan a los tres primeros y queda uno equivalente (ningn caso de prueba del
test suite mata el muante y, adems, es imposible construir un caso de prueba que
lo consiga), por lo que el mutation score es 3 / (4-1) = 100% = 1, resultando que el
test suite es mutation adequate. Obviamente, la calidad real del test suite depende
de la naturaleza de los fallos introducidos. Por lo general, los fallos se introducen
mediante herramientas que aplican determinados operadores de mutacin al
programa que se est probando: el operador AOR (arithmetic operator
replacement), por ejemplo, reemplaza un operador aritmtico por otros operadores
(es el caso de los mutantes 1,2 y 3 de la Tabla 6.3).

Los fallos que introducen los operadores de mutacin deben ser parecidos a
los que cometen involuntariamente los programadores. Han de ser fallos buenos;
es decir, fallos de buena calidad. Existen operadores de mutacin tradicionales
(que son aplicables prcticamente a cualquier lenguaje de programacin, como los
mostrados en la Tabla 6.2), otros que son dependientes del paradigma (Tabla6.3)
y otros que se disean para algn lenguaje de programacin especfico (para C17,
por ejemplo).

17 Barbosa, E.F., Maldonado, J.C. y Rizzo Vincenzi, A.M., 2001, Toward the determination of
sufficient mutant operators for C, Software Testing, Verification and Reliability, 11(2), 113-136.
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 95

Operadores tradicionales
Sustitucin de una variable por el valor absoluto
ABS (absolute value)
de dicha variable.
ACR (array reference for constant Sustitucin de una referencia variable a un array
replacement) por una constante.
AOR (arithmetic operator
Sustitucin de un operador aritmtico.
replacement)
CRP (constant replacement) Sustitucin del valor de una constante.
ROR (relational operator
Sustitucin de un operador relacional.
replacement)
RSR (return statement
Sustitucin de la instruccin return.
replacement)
SDL (statement deletion) Eliminacin de una sentencia.
Insercin de operador unario (por ejemplo: en
UOI (unary operator insertion)
lugar de x, poner -x).

Tabla 6.2. Algunos operadores de mutacin tradicionales 18

Operadores para orientacin a objetos

AMC (access modifier Reemplazo del modificador de acceso (por ejemplo: ponemos
change) private en lugar de public).
Cambio del orden de los argumentos pasados en la llamada a
AOC (argument order un mtodo (por ejemplo: en lugar de Personap=new
change) Persona(Paco , Pil ), poner Persona p=new
Persona(Pil , Paco ).
Sustitucin de una referencia a una instancia de una clase por
CRT (compatible
una referencia a una instancia de una clase compatible (por
reference type
ejemplo: en vez de poner Persona p=new EmpleadoQ, poner
replacement)
Persona p=new EstudianteQ).
Cambio de una instruccin de manejo de excepciones (try...
EHC (exception handling
catch) por un sentencia que propague la excepcin {throw), y
change)
viceversa.

18 DeMillo, R.A. y Spafford, E.H., 1986, The Mothra software testing environment, proceedings of
the 11th NASA Software Engineering Laboratory Workshop, Goddard Space Center, EE. UU.
96 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

EHR (exception handling


Eliminacin de una instruccin de manejo de excepciones.
removal)

HFA (hiding field Adicin en la subclase una variable con el mismo nombre que
variable addition) una variable de su superclase.
MIR (method invocation Reemplazo de una llamada a un mtodo por una llamada a
replacement) otra versin del mismo mtodo.
OMR (overriding method Eliminacin en la subclase la redefinicin de un mtodo
removal) definido en una superclase.

Cambio del orden de los parmetros en la declaracin de un


POC (parameter order
mtodo (por ejemplo: poner Persona(String apellidos, String
change)
nombre) en vez de Persona(String nombre. String apellidos).

SMC (static modifier


Adicin o eliminacin del modificador static.
change)

Tabla 6.3. Algunos operadores de mutacin para orientacin a objetos

6.3 PRINCIPIOS DE LA MUTACIN


Los fallos introducidos en los mutantes por los operadores de mutacin son
fallos muy simples, que tratan de imitar los posibles sencillos errores que pudiera
cometer un programador con, por ejemplo, un pequeo despiste. Esta idea se
refiere a la hiptesis del programador competente19, que afirma que los
programadores competentes tienden a escribir programas casi correctos: es decir,
sus programas pueden ser incorrectos, pero diferirn de la versin correcta en un
nmero pequeo de fallos simples.

Esta hiptesis est muy relacionada con el efecto acoplamiento20, que


afirma que si un test suite es capaz de detectar fallos simples (como los
introducidos artificialmente por los operadores de mutacin), entonces tambin
ser capaz de detectar fallos ms complejos.

19 Aeree, A.T., Budd, T.A., De Millo, R.A., Lipton, R.J. y Sayward, F.G., 1979, Mutation analysis,
technical report GIT-ICS-79/08, School of Information and Computer Science, Georgia Institute of
Technology, Atlanta, Georgia, EE. UU.
20 De Millo, R.A., Lipton, R.J. y Sayward, F.G., 1978, Hints on test data selection. Help for the
practicing programmer, IEEE Computer, 11 (4), 34-41.
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 97

6.4 EL PROCESO DE PRUEBAS UTILIZANDO


MUTACIN
Como se puede deducir de lo comentado hasta ahora, el proceso de
mutacin consta de una serie de pasos que han de ejecutarse junto con el resto de
tareas de prueba de un programa. Bsicamente, el proceso de mutacin est
compuesto por tres tareas bsicas:

1. Generacin de mutantes. Consiste en crear mutantes del programa


original usando operadores de mutacin.
2. Ejecucin de casos de prueba contra el programa original y contra los
mutantes.
3. Anlisis de resultados. Consiste en analizar los resultados de las
ejecuciones y calcular el mutation score para evaluar la calidad de los
casos de prueba.

As, partiendo de un programa y de un conjunto de casos de prueba,


ejecutando las tres tareas, se puede conocer si los casos de prueba son adecuados
para probar el programa. Sin embargo, el proceso no es tan sencillo, ya que pueden
darse al menos dos situaciones adversas:

1. Que el conjunto de casos de prueba no sea adecuado (es decir, que su


mutation score sea demasiado bajo), por lo que habr que aadir ms
casos de prueba y volver a evaluarlos.
2. Que las pruebas encuentren fallos en el programa bajo prueba, con lo
que habr que realizar las correcciones oportunas y volver a ejecutar y
a evaluar los casos de prueba. Es posible, adems, que, puesto que el
programa ha sido modificado, los mutantes anteriores no sean ya
vlidos y sea preciso generar nuevos mutantes.

El diagrama que aparece en la Figura 6.3 21 representa un posible proceso


de pruebas utilizando mutacin: se parte de un test suite inicial (7) y de P, el
programa que se va a probar. Inicialmente, se ejecuta T sobre P con objeto de
comprobar que P se comporta correctamente con los casos de prueba: si T21

21 Polo, M. y Reales, P., 2010, Mutation testing cost reduction techniques: a survey, IEEE
Software, 27(3), 80-86.
98 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

encuentra errores en P, P se corrige hasta que los casos no evidencien ya ningn


error. A continuacin, se genera el conjunto de mutantes y se van ejecutando los
casos de prueba de T sobre cada muante vivo (si un caso de prueba tc mata al
mutante my, ya no es preciso seguir ejecutando los restantes casos de prueba sobre
el mutante, puesto que ya se ha cumplido el objetivo de matarlo). Cuando se ha
ejecutado completamente T, se eliminan los mutantes funcionalmente equivalentes
y se evala el mutation score: si se ha alcanzado el umbral (que se ha debido
preestablecer con antelacin), entonces el proceso se detiene. En otro caso, se
aaden nuevos casos de prueba a T y se repite el proceso.

Corregir P

Test suite (T)


r
Ejecutar T
sobre P

Programa bajo
prueba (P)
A
Aadir casos de
prueba a T Crear mutantes
A

Ejecutar T sobre

I
cada mutante vivo

Eliminar casos de Eliminar mutantes


prueba inefectivos equivalentes

Figura 6.3. Un posible proceso de pruebas basado en mutacin

Obsrvese que, al aadir ms casos de prueba a T, estos se ejecutan


inicialmente sobre el programa bajo prueba P, existiendo la posibilidad de que los
nuevos casos encuentren errores en P (es decir, que la salida de P, P(T), no sea
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 99

correcta), con lo que P debe ser corregido y sus mutantes regenerados (dejan de ser
vlidos los que tenamos de antes, pues procedan de una versin anterior del
programa). Por ello, para evitar esta segunda regeneracin de mutantes, es preciso
tener una cierta garanta de que el test suite que ejecutamos inicialmente alcanzar
una cobertura amplia sobre P, para lo que es recomendable utilizar buenos valores
de prueba y combinarlos adecuadamente con una buena estrategia de combinacin.

6.5 TCNICAS DE REDUCCIN DE COSTES EN EL


TESTING CON MUTACIN
Puesto que cada operador de mutacin puede aplicarse en multitud de
sentencias, y cada sentencia se puede adems mutar con diferentes operadores de
mutacin, el nmero de mutantes que puede obtenerse para un programa pequeo
puede ser muy grande. Un nmero muy grande de mutantes ralentiza y puede
dificultar las tres etapas fundamentales del proceso de pruebas basado en mutacin:

1. Generacin de mutantes.
2. Ejecucin de casos de prueba contra el programa original y contra los
mutantes.
3. Anlisis de resultados.

Por ello, durante aos de investigacin se han desarrollado diferentes


tcnicas para abaratar sus costes.

En el proceso propuesto en la Figura 6.3 hay dos pasos en los que se


aplican dos tcnicas de reduccin de costes: en Ejecutar T sobre cada muante
vivo, se desprecian los mutantes que ya han sido muertos por casos de prueba
anteriores; en Eliminar casos de prueba inefectivos, se eliminan del test suite
aquellos casos de prueba que no han matado ningn mutante. En la Tabla 6.4 se
muestra una sencilla matriz de muertos de un supuesto sistema con 7 mutantes y 6
casos de prueba: si se ejecutan todos los casos de prueba contra todos los mutantes,
se producen 7 x 6 = 42 ejecuciones. Sin embargo, si se aplica el proceso propuesto
en la figura, al ejecutar tc sobre M (conjunto de mutantes), se matan m y m2; el
siguiente caso de prueba, tc2, se ejecuta nicamente sobre los mutantes de m a m7
(ya no sobre m y m2, que han sido muertos por el caso anterior), y se elimina m_
para las siguientes ejecuciones por estar ya muerto; a continuacin, tc se lanza
solamente contra m4 a m7, eliminndose m4, m y m6 para los siguientes casos. Tc4
se ejecuta contra el nico mutante que queda vivo (m7), pero no lo mata, resultando
adems ser un caso de prueba inefectivo que puede ser eliminado del test suite, ya
que no mata el nico mutante sobre el que se ejecuta (es decir, no encuentra el fallo
100 TECNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

introducido); tcs se ejecuta tambin solamente contra m7, que no llega a morir
(obsrvese que tc5 no llega a ejecutarse contra m2, ya que este mutante fue muerto
por tc, por lo que tc tambin se considera ahora inefectivo). Finalmente, tc6 se
ejecuta y mata a m7. Con este proceso, en lugar de 42 ejecuciones de casos de
prueba, hay 7 + 5 + 4 + 1 + 1 + 1 = 19, lo que reduce ostensiblemente el coste de
las pruebas.

Casos de prueba
tcl tc2 tc3 tc4 tc5 tc
mi X X
m2 X X X
m3 X X
Mutantes

m4 X X
m5 X X
m6 X X
mi X
Tabla 6.4. Matriz de mulantes muertos

No obstante, ejecutar todos los casos contra todos los mulantes puede ser
conveniente en algunas ocasiones: si tenemos en cuenta las futuras etapas de
mantenimiento y modificacin del software, con las consiguientes pruebas de
regresin, puede ser conveniente priorizar los casos de prueba con el objeto de
abaratar las pruebas en un futuro. As, a partir de la matriz completa de muertos del
ejemplo, podra obtenerse un test suite reducido formado por los casos tc6 y tc, que
conseguira un mutation score idntico al del test suite original.

6.5.1 Reduccin de costes en la generacin de mutantes


Cuando se generan los mutantes, prcticamente cada instruccin del
programa original se puede mutar con distintos operadores de mutacin, por lo que
el nmero de mutantes procedentes de un programa de tamao mediano puede ser
realmente enorme, lo que puede suponer costes altos de compilacin (cuando la
hay) y, desde luego, costes tambin altos en las etapas posteriores.
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 101

Para reducir los costes en esta etapa, se realizan dos tipos de selecciones:
seleccin aleatoria de mutantes (es decir, utilizacin de un conjunto aleatorio de los
imitantes generados) y seleccin de los mejores operadores de mutacin (lo que se
llama mutacin selectiva).

Respecto de la seleccin aleatoria, se ha mostrado experimentalmente que


alcanzar un 100% de mutation score en un 10% de mutantes elegidos al azar
representa tambin casi un 100% de mutation score sobre el conjunto original222345'23,
24 y 25

La mutacin selectiva ha sido la principal lnea de trabajo en la que se ha


investigado. Consiste en la generacin de mutantes utilizando solamente un
subconjunto de los operadores de mutacin. Un operador de mutacin se selecciona
o se excluye en funcin de la bondad de los mutantes que genera. En un estudio de
Mresa y Botacci26, se determinan los mejores operadores de mutacin y se compara
adems esta tcnica con la seleccin aleatoria de mutantes. Observan, por ejemplo,
que los operadores SVR {scalar variable replacement), ASR {array reference for
scalar variable replacement) y CSR {constant for scalar variable replacement)
generan demasiados mutantes y no se deberan incluir en el conjunto de operadores
ideal. Estos autores observan que:

Si se requiere obtener un mutation score muy prximo al 100%, entonces


es preferible seleccionar mutantes aleatoriamente en lugar de aplicar mutacin
selectiva.

Si no se requiere un mutation score tan alto, entonces pueden utilizarse los


siguientes operadores, que resultan ser suficientemente eficientes: AOR {arithmetic
operator replacement), SAN {statement analysis), SDL {statement deletion), ROR
{relational operator replacement) y UOI {unary operation insertion).

22 DeMillo, R.A. y Spafford, E.H., 1986, The Mothra software testing environment, 11* NASA
Software Engineering Laboratory Workshop, Goddard Space Center, EE. UU.
23 Aeree, A.T., 1980, On mutation, PhD Thesis, School of Information and Computer Science,
Georgia Institute of Technology, Atlanta, Georgia, EE. UU.
24 DeMillo, R.A., Guindi, D.S., King, K.N., McCracken, W.M. y Offutt, A.J., 1988, An extended
overview of the Mothra software testing environment, Second Workshop on Software Testing,
Verification and Analysis, Banff, Alberta, Canada, 142-151, IEEE Computer Society Press.
25 King, K.N. y Offutt, A.J., 1991, A fortran language system for mutation based software testing.
Software: Practice and Experience, 21(7), 685-718.
26 Mresa, E.S. y Bottaci, L., 1991, Efficiency of mutation operators and selective mutation strategies:
an empirical study, Software Testing, Verification and Reliability, 9(4), 205-232.
102 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

En un estudio anterior, Offutt et l.27 observan que, con los operadores


AOR, ROR, UOI, ABS (insercin de valor absoluto) y LCR (reemplazo de
conector lgico), se reduce en un 77,5% el nmero de mutantes generados y que, si
un test suite es adecuado (mutation-adequate) para estos mutantes, es casi
adecuado (el mutation score alcanza un 99%) cuando se utilizan todos los
operadores.

Otra estrategia que se puede utilizar para reducir costes en la generacin de


mutantes consiste en introducir ms de un fallo en cada muante, obteniendo lo que
se llaman high-order mutants, mutantes de mayor orden: los mutantes con dos
fallos son mutantes de orden 2 o 2-order; si contienen tres fallos, son mutantes de
orden 3 3-order. Si obtenemos mutantes de orden 2, el conjunto de mutantes
tendr aproximadamente la mitad de mutantes del conjunto de orden 1, pero los
mutantes tendrn dos errores cada uno. Adems, como se muestra en la seccin
6.5.3 con ms profundidad, esta tcnica se puede usar para reducir el nmero de
mutantes equivalentes, con lo que se reducen costes en el anlisis de resultados.

Sin embargo, al usar mutacin de mayor orden siempre existe la


posibilidad de que los mutantes generados sean de menor calidad (ya que, al tener
ms de un fallo, son ms fciles de matar), por lo que la evaluacin de las pruebas
puede ser menos fiable. Para solucionar este problema, Ji y otros2829desarrollaron
una tcnica basada en clustering, para clasificar los mutantes en funcin de los
casos de prueba, de manera que se pueden seleccionar solamente aquellos que sean
de mayor calidad y que son matados por diferentes pruebas.

Adems de estas, existen otras tcnicas para reducir costes en la generacin


de mutantes, como es la mutacin a nivel de bytecode29 (cdigo de byte del
lenguaje Java, el cual es ejecutado directamente por la mquina virtual de Java).
Con esta tcnica, las mutaciones son insertadas directamente en el bytecode con lo
que no se requiere la compilacin de cada muante.

Para reducir costes de compilacin, tambin existen otras dos tcnicas que
pueden ser aplicadas a sistemas que se basen en cdigo interpretado (o
semiinterpretado, como Java). La primera consiste en integrar operadores de

27 Offutt, A.J., Rothermel, G., Untch, R.H. y Zapf, C., 1996 An experimental determination of
sufficient mutant operators, ACM Transactions on Software Engineering and Methodology, 5(2), 99-
118.
28 Ji, C., Chen, Z., Xu, B. y Zhao, Z., 2009, A novel method of mutation clustering based on domain
analysis, 21st International Conference on Software Engineering and Knowledge Engineering
(SEKE'09), Boston, Massachusetts.
29Ma, Y.S., Offutt, J. y Kwon, Y.R., 2005, MuJava: an automated class mutation system, Software
Testing, Verification and Reliability, 15(2), 97-133.
RA-MA CAPITULO 6. PRUEBAS MEDIANTE MUTACION 103

mutacin directamente en los compiladores (compiler-integration), de manera que


al compilar el cdigo fuente se genere no solo el archivo ejecutable del sistema
original, sino todos los ejecutables de los mutantes. El problema es que esta tcnica
es demasiado costosa. Otra alternativa consiste en construir un nico sistema que
contenga tanto al sistema original como a los mutantes, de manera que solo se
necesita compilar una vez. Esta tcnica se conoce como mutant schemata. La
desventaja de esta tcnica es que, al introducir dentro del mismo sistema tanto el
cdigo del sistema original como el de los mutantes, el entorno de ejecucin debe
tener algn mecanismo para controlar la parte del cdigo que se ejecuta.

6.5.2 Reduccin de costes en la ejecucin


Adems de la posibilidad indicada al principio de esta seccin de ejecutar
los casos de prueba nicamente sobre los mutantes que van quedando vivos,
existen diferentes formas de ejecutar los casos de prueba sobre los mutantes, que
pueden acelerar el proceso. De manera general, para que un caso de prueba mate un
muante deben darse tres condiciones, habitualmente llamadas condiciones RIP:

1. Reachability (alcance): el caso de prueba debe alcanzar la instruccin


mutada en la que se ha introducido el cambio.
2. Infection (infeccin): con el caso de prueba, el estado del programa
original debe ser diferente del estado del mutante tras ejecutar la
instruccin mutada. A ese estado diferente que se logra en el mutante
se le llama estado errneo.
3. Propagation (propagacin): el estado errneo se debe propagar hasta la
salida del programa, con el objeto de que sea observable y pueda
compararse con el del programa original y determinarse que aquel ha
muerto.

Al modo de ejecucin que, para matar a un mutante, requiere de las tres


condiciones anteriores, se le conoce con el nombre de mutacin fuerte (strong
mutation). El cdigo de la Figura 6.4 corresponde a un caso de prueba para el
problema del tringulo (Figura 3.3)\ se construye una instancia de la clase, se
asignan valores a los tres lados y, a continuacin, se construye una cadena formada
por la concatenacin de la longitud de los tres lados y el tipo del tringulo. Este30

30 Untch, R., O (fut, A.J. y Harrold, M.J., 1993, Mutation analysis using program schemata.
International Symposium on Software Testing and Analysis, Cambridge, Massachusetts, ACM Press.
104 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

caso de prueba puede ejecutarse bien con la herramienta MuJava31 o bien con
testooj32. Estas dos herramientas ejecutan el caso contra el programa original (que,
por ejemplo, devolvera la cadena 4,1,5.4, correspondiendo el 4 a un no tringulo,
pues esta instancia corresponde a una lnea recta, ya que la suma de los dos
primeros lados es igual a la longitud del segundo) y, luego, contra cada mutante.
Supongamos que uno de los mutantes incrementa el valor del lado J en el mtodo
setJ (que pasa a valer 2), con lo que el tringulo pasa a ser escaleno: ahora, la
cadena devuelta por el caso de prueba sera 4,2,5,3 (suponiendo que el valor 3
corresponda al tipo escaleno), y el caso de prueba habra matado el mutante.

public String testAR20_l() {


try {
TriTyp obtained = new TriTyp();
obtained.setI(4)
obtained, set J (1)
obtained.setK(5);
obtained.getTipoO;
return obtained, getl () + " ," + obtained. g e t J O + +
obtained. getK() + +
obtained.getType();
} catch (Exception e) {
return e .toString();
}
2 _____________________________________________________
Figura 6.4. Un caso de prueba para matar a un mutante del tringulo por mutacin fuerte

En efecto, ese caso de prueba consigue las tres condiciones RIP necesarias
para la mutacin fuerte: la instruccin mutada (en setJ) se alcanza; se produce un
estado intermedio errneo (el propio incremento del lado); y el estado errneo es
observable al finalizar la ejecucin del caso de prueba.

Otra posibilidad (llamada mutacin dbil, weak mutation, por


contraposicin a la strong mutation) consiste en requerir solamente las dos
primeras condiciones (alcance e infeccin) para dar por muerto al mutante. En

31 Ma, Y.S., Offutt, J. y Kwon, Y.R., 2005, MuJava: an automated class mutation system. Software
Testing, Verification and Reliability, 15(2), 97-133. MuJava est disponible en (18 de octubre de
2010): es.gmu.edu/~offutt/mujava/.
32 Polo, M., Tendero, S. y Piattini, M., 2007, Integrating techniques and tools for testing
automation. Software Testing, Verification and Reliability, 17(1), 3-39. Testooj est disponible en
(18 de octubre de 2010): alarcos.esi.uclm.es/testooj3/.
RA-MA CAPITULO 6. PRUEBAS MEDIANTE MUTACION 105

weak mutation33'34, se detiene la ejecucin del caso de prueba despus de ejecutar la


instruccin mutada y se realiza una comparacin: si el estado del programa original
en ese punto es distinto del estado del mutante, este se da por muerto. Tanto si el
muante est vivo como si est muerto, se detiene la ejecucin del caso de prueba,
con lo que se acelera el tiempo de ejecucin, ya que el estado no se propaga hasta
la salida del programa. El momento de despus (es decir, el punto en el que se
detiene la ejecucin) puede variar. Ofifutt y Lee24 definieron cuatro tipos de weak
mutation, en funcin del lugar en el que se detenga la ejecucin del programa y se
realice la comparacin:

1. Ex-weak/I mutation. La ejecucin se detiene justo despus de evaluar


la parte mutada de una instruccin. Por ejemplo, si la instruccin int a
= 3*4/6 se muta a int a = 3-4/6, la ejecucin se para justo despus de
calcular 3-4 y el resultado de esa operacin se usa para comparar con
el programa original. En el ejemplo, se comparara 3*4 con 3-4, y
como resultado el mutante resultara muerto.
2. St-weak/1 mutation. La ejecucin se detiene justo despus de ejecutar
la instruccin mutada completa. En el ejemplo, se comparara 3*4/6
con 3-4/6.
3. BB-weak/1 mutation. La ejecucin se detiene justo despus de ejecutar
el bloque bsico de cdigo donde se encuentra la instruccin. Un
bloque bsico de cdigo es una secuencia de instrucciones sin saltos,
de manera que si se ejecuta la primera, se ejecutarn todas las
instrucciones de la secuencia.
4. BB-weak/N mutation. Este tipo es similar a BB-weak/1, pero con la
diferencia de que si el bloque bsico est dentro de un bucle, la
ejecucin contina hasta que se llegue a la ltima iteracin del bucle.
De esta manera, los mutantes que necesitan ejecutar varias iteraciones
para llegar a un estado errneo pueden ser detectados.

Como resultado de los experimentos realizados comparando estos tipos de


mutacin dbil, Offutt y Lee determinaron que St-weak/l y BB-weak/1 obtienen
resultados similares, los cuales son de una calidad aceptable con una gran

33 Howden, W.E., 1982, Weak mutation testing and completeness of test sets, IEEE Transactions
on Software Engineering, 8(4), 371-379.
j4 Offutt, A.J. y Lee, S.D., 1994, An empirical evaluation of weak mutation, IEEE Transactions on
Software Engineering, 20(5), 337-344.
106 TECNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

reduccin del coste de ejecucin. Sin embargo, B B -w eak/N obtiene resultados de


mejor calidad, ya que permite ejecutar varias iteraciones en los bucles, obteniendo
resultados muy cercanos a stro n g m utation con una reduccin de los costes de
ejecucin.

Todas estas tcnicas de mutacin fueron estudiadas para algoritmos


codificados dentro de un mtodo. No obstante, para sistemas ms grandes, con
mltiples clases interactuando para ejecutar ciertas funcionalidades, los resultados
de estas tcnicas son peores, ya que es ms difcil que se cumpla la condicin de
propagacin.

Recientemente se ha propuesto una nueva tcnica llamada flexible weak


mutation35 (mutacin dbil flexible), por la que un motor de ejecucin compara
continuamente el estado del programa original y el del mutante. La herramienta
Bacterio, que implementa la fle x ib le w eak m utation, instrumenta el cdigo original
y el de los mutantes, de manera que al entrar y salir de cada mtodo se deje en un
fichero de lo g una representacin (en forma de cadena o de un valor hash) del
estado del objeto y de los objetos asociados. Cuando se ejecuta un mutante, el
motor de ejecucin guarda el resultado en el lo g y lo compara con el que dej el
programa original: si es diferente, el mutante se ha comportado de manera distinta
y se da por muerto; en otro caso, la ejecucin del caso de prueba contina,
comparndose nuevamente los valores cada vez que se entra en un nuevo mtodo
del mutante. El mutante solamente se considera vivo cuando se llega al final de la
ejecucin del caso de prueba sin que se haya observado diferencia de estado en el
log.

Tradicionalmente, las pruebas mediante mutacin se han aplicado para la


realizacin de pruebas unitarias y, en menor medida, de integracin. La mutacin
dbil flexible, sin embargo, es adecuada para las pruebas de sistema e integracin.
En el lado izquierdo de la Figura 6.5 se muestra la estructura de una posible
aplicacin Java, compuesta de un conjunto de libreras, imgenes, ficheros
auxiliares y el conjunto de clases compiladas (A .class, B.cla ss... Z .class). Para
generar los mutantes. Bacterio aplica sus operadores de mutacin al b yteco d e de
cada fichero .class, obteniendo el amplio conjunto de mutantes { A l.class,
A 2 .c la ss... A n.class, B l . class, etc.), que se muestra en el lado derecho de la figura.3

33 Reales, P., Polo, M. y OfTutt, A.J., 2010., Mutation at system and functional levels, proceedings
of the 2010 Third International Conference on Software Testing, Verification and Validation
Workshops, 110-119, IEEE Computer Society.
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 107

j application |

-l ^
-| c la s s e s

|^A1 .class j

S te p 1. A2. c la ss ] j B 2 .class |
M utant generation
GZ] I
j Z .c la s s |

f '* I A n.class | jfim .c la s s j Z p.class


X-jar__ |
H 7 .jar |
es


O riginal a p p lic a tio n

Figura 6.5. Generacin de clases matantes en Bacterio

Bacterio genera versiones defectuosas (es decir, introduciendo, al menos,


un muante en cada una) de la aplicacin {Figura 6.6): as, monta una versionl en
la que, por ejemplo, introduce cl mutante A 1 de la clase A y el Z1 de la clase Z. En
este ejemplo, se habra producido una versin mutada de orden 2: es decir, con dos
clases incorrectas (A y Z). El tester puede elegir el orden de los mutantes al generar
las versiones. En realidad, Bacterio no construye las copias de la aplicacin (la
figura es meramente ilustrativa), sino que, durante el tiempo de ejecucin, cargar
la clase o clases mutantes que correspondan a la versin defectuosa.

Figura 6.6. Generacin de versiones mutantes en Bacterio


108 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... O RA-MA

6.5.3 Reduccin de costes en el anlisis de resultados


Uno de los principales obstculos al analizar los resultados (bsicamente,
al calcular el m utation sco re ) reside en la presencia de mutantes funcionalmente
equivalentes, de los que suele haber en tomo a un 18-20% de los mutantes totales.
Lo habitual es buscarlos entre los mutantes que permanecen vivos tras ejecutar el
te st su ite (Figura 6.3). Su bsqueda, sin embargo, requiere un tiempo muchas
veces prohibitivo36 que, en algunos casos, requiere un tiempo medio de 15
minutos37. Por ello, cuando se calcula el m utation sco re puede asumirse que en
tomo al 2 0 % de los mutantes sern equivalentes y hay que conformarse, entonces,
con alcanzar un 80% de muertos, si bien esto depende de lo crtico del sistema que
se est probando.

Una lnea de trabajo reciente investiga la mutacin de orden n (mencionada


en las dos secciones anteriores), en la que se introducen n fallos en cada mutante38.
As, cuando se mata un mutante de orden 2 puede ocurrir que sea porque se ha
encontrado uno de los dos errores o los dos. Al combinar los mutantes de orden 1
en mutantes de orden 2 , el nmero total de mutantes se reduce a la mitad y,
adems, se reduce significativamente el porcentaje de mutantes equivalentes:
asumiendo un 2 0 % de probabilidad de que un mutante de orden 1 sea
funcionalmente equivalente, combinar al azar dos de estos mutantes tiene una
probabilidad de un 4%. De este modo no solo hay menos mutantes, sino que hay
tambin menos equivalentes. Bacterio combina mutantes de orden 1 en mutantes de
orden superior, tanto a nivel intraclase como interclase:

A nivel intraclase, una versin de orden 2 contendr una clase con dos
fallos. Por ejemplo, la clase A del sistema que mencionbamos arriba
podra ser sustituida por A j , que contiene los fallos introducidos en
los mutantes A , y A 2 de A. Esta versin defectuosa del sistema, por
tanto, quedara compuesta por las clases (A .class, B .cla ss... Z .class).

A nivel interclase, una versin de orden 2 contendr dos clases con un


fallo, como por ejemplo (A.class, B.class... Z .class), que contiene los

36 Frankl, P.G., Weiss, S.N. y Hu, C., 1997, All-uses vs mutation testing: an experimental
comparison of effectiveness, Journal o f Systems and Software, 38(3), 235-253.
37 Griin, B.J.M., Schuler, D. y Zeller, A., 2009, The impact of equivalent mutants, IEEE
International Conference on Software Testing, Verification, and Validation Workshops, Denver,
Colorado, EE. UU 192-199.
38 Polo, M , Piattini, M. y Garca-Rodrguez, I., 2008, Decreasing the cost of mutation testing with
second-order mutants, Software Testing, Verification and Reliability, 19(2), 111-131.
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 109

fallos 1 y 3 introducidos, respectivamente, en las clases A y B,


permaneciendo el resto como copias de las clases del sistema original.

La desventaja de la mutacin de orden n es la probabilidad de tener un test


su iteadecuado para ese orden (es decir, un te st su ite que mate todos los mutantcs)
pero que, sin embargo, que no descubra todos los fallos que se han sembrado
individualmente en cada mutante.

Polo, Piattini y Rodrguez38 describen tres algoritmos para combinar


mutantes de orden 1 en mutantes de orden 2, que son implementados en Bacterio:

1. D ifferen tO perators combina mutantes generados con diferentes


operadores de mutacin. Puesto que cada operador tiene una distinta
propensin a generar mutantes equivalentes (el operador A O IS de
M uJava, por ejemplo, genera muchsimos), combinar los mutantes
procedentes de un operador con los procedentes de otro disminuye el
porcentaje de mutantes equivalentes de orden 2 .
2. L astT oF irst toma los mutantes en el mismo orden en que se han
generado y combina el primero con el ltimo, el segundo con el
penltimo, etc.
3. R andom M ix combina mutantes de orden 1 al azar.

Otra lnea de investigacin consiste en evaluar los mutantes generados para


determinar si son equivalentes o no. Esta tcnica se basa en la evaluacin del
impacto de las mutaciones dentro del sistema39. Para analizar el impacto, se toman
medidas de las diferencias del flujo de datos y del flujo de control entre el sistema
original y el mutante, de manera que cuando las diferencias son bajas existe una
alta probabilidad de que el mutante sea equivalente.

6.5.4 Herramientas de mutacin


Debido a los altos costes que supone realizar todas las tareas necesarias
para evaluar las pruebas mediante mutacin, es muy importante disponer de
herramientas que automaticen o ayuden a realizar las tareas relacionadas con la

39 Schuler, D. y Zeller, A., 2010, (Un-) Covering equivalent mutants, proceedings of the 3rd
International Conference on Software Testing Verification and Validation (ICSTTO), Pars, Francia.
110 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

mutacin. En esta seccin estn comentadas las herramientas de mutacin ms


importantes.

Entre las herramientas de mutacin clsicas, las dos herramientas ms


importantes e influyentes son Mothra y Proteum. Mothra fue la primera
herramienta de mutacin, y se dise para programas escritos en Fortran 77.
Muchos de los resultados de investigacin sobre pruebas basadas en mutacin
provienen de experimentar con esta herramienta. Aunque hoy en da se ha dejado
de usar por la obsolescencia de su tecnologa, sigue disponible en
cs.gm u.edu/~ojfutt/rsrch/m ut.htm l. Por otro lado, Proteum es otra de las primeras
herramientas de mutacin que ha tenido una gran influencia, y est diseada para
sistemas escritos en C, aunque, tras diversas versiones y modificaciones, tambin
puede usarse para sistemas en C++. Con respecto a herramientas comerciales,
actualmente solo existen dos herramientas que dan soporte al proceso de proceso
de pruebas mediante mutacin:

Una de ellas es PlextTets++, desarrollada por ITRegister para


sistemas C++. Esta herramienta implementa un motor de mutacin
junto con un fra m e w o rk de pruebas unitarias. No obstante, y de
acuerdo con su pgina web, PlexTest++ solo implementa un operador
de mutacin que consiste en la eliminacin de expresiones del cdigo
del sistema original. Como se ha mencionado, la calidad del test su ite
depende del m utation sco re , pero tambin de la calidad de los fallos
introducidos por los operadores de mutacin.

La segunda herramienta de mutacin comercial es Certitude, la cual


est diseada para probar TML verification s (diseos de sistemas
h a rd w a re) mediante mutacin. Para ello Certitude implementa
operadores de mutacin para cdigo C++, el cual se usa para definir
las TML verification s. Si bien podramos considerar que esta
herramienta no es una herramienta de mutacin de softw are, ya que
sirve para evaluar diseos h ardw are, actualmente es la herramienta de
mutacin comercial ms importante.

A pesar de que solo existen dos herramientas de mutacin comerciales, hay


una gran cantidad de herramientas gratuitas de libre distribucin. Concretamente
para tecnologa Java existen al menos doce herramientas (Jester, JavaMut, MuJava,
MuClipse, Jumble, Javalanche, ExMan, Mugamma, AjMutator, Judy, testooj y
Bacterio).
RA-MA CAPITULO 6. PRUEBAS MEDIANTE MUTACION 111

Una de las herramientas ms importantes es Mujava. Esta fue la primera


herramienta de mutacin para Java que incorpor operadores de mutacin
especficos para mutar caractersticas propias de los sistemas orientados a objetos.
Muclipse es la adaptacin de MuJava como plugin para Eclipse.

Otra herramienta importante es Bacterio, comentada anteriormente y cuya


forma de utilizacin se explica ampliamente en el siguiente captulo. Esta
herramienta est especialmente diseada para pruebas a nivel de sistema. Adems,
implementa gran cantidad de tcnicas de reduccin de costes, lo que la hace de
especial inters para usarla en proyectos reales.

6.5.5 Comparativa de herramientas de mutacin para el


lenguaje Java
Para que podamos elegir una herramienta de mutacin adecuada a las
necesidades de nuestro proyecto es importante conocer las caractersticas de cada
una de las herramientas de mutacin. Esta seccin muestra una comparativa de las
herramientas de mutacin Java. La Tabla 6.5 muestra las caractersticas principales
de cada una de las herramientas Java que existen actualmente.

Caractersticas generales
Nombre
Operadores
Tipo de test Disponible Ao Web
de mutacin

Jester Unitarios Dinmicos* S 2001 jester.sourceforge.net/

Tradicionales
Unitarios y de
JavaMut y a nivel de No 2002 -
clase
clase

Tradicionales
Unitarios y de
MuJava y a nivel de S 2004 cs.gmu.edu/~offutt/mujava/
clase
clase

De
A nivel de faculty.uoit.ca/bradbury/conman/
ExMan concurrencia/c S 2006
concurrencia
ualquiera**

Generacin de
test de
Mugamma Ninguno*** No 2006 -
regresin
unitarios
112 TECNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

Tradicionales
Unitarios y de
Muclipse y a nivel de S 2007 mucl ipse.sourceforge.net/
clase
clase

Jumble Unitarios Tradicionales S 2007 jumble.sourceforge.net/

Testooj Unitarios Ninguno*** S 2007 alarcos.inf-cr.uclm.es/testooj3/

Nivel www.javalanche.org/
Javalanche Unitarios S 2009
tradicional

A nivel de www.irisa.ir/triskell/Softwares
Aj Mutator Para aspectos S 2009 / protos/Aj Mutator/
aspectos

Tradicionales
Unitarios y de
Judy y a nivel de No 2010 -
clase
clase

Unitarios, de Tradicionales www.alarcosqualitycenter.com


Bacterio integracin y y de S 2009 /index.php/products/bacterio?It
funcionales integracin emid=109

* J e s t e r implementa sus operadores de mutacin mediante sustitucin de cadenas de texto que pueden ser
configuradas.
* * E x M a n tiene una arquitectura basada en p lu g in s la cual permite aplicar cualquier operador de mutacin usando
el p lu g in adecuado.
* * * T e sto o j y M u g a m m a usan MuJava para generar mutantes.

Tabla 6.5. Herramientas de mutacin para Java

En la tabla encontramos informacin sobre el tipo de pruebas que se


pueden evaluar y el tipo de operadores de mutacin que implementa cada
herramienta, su ao de construccin, si estn disponibles y la pgina web donde
podemos encontrarla.

La Tabla 6.6 muestra las tcnicas de reduccin de costes que implementa


cada herramienta. En la tabla hay una columna de tcnicas bsicas para realizar
anlisis basados en mutacin, pero que no suponen una reduccin de costes. Estas
tcnicas son strong mutation y compiler based (mutar el cdigo fuente para
posteriormente compilarlo y as obtener los mutantes).

Los datos ms significativos de la comparacin de la Tabla 6.6 es que


todas las herramientas implementan mutacin selectiva siempre que implementen
operadores de mutacin.
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 113

t cnicas de reduccin de costes


Tcnicas
bsicas Tcnicas de generacin y Tipos de
Reduccin de mutantes
ejecucin mutacin

Bytecode translation
Selective mutation

Parallel execution
Mutant clustering

Mutant schemata
Mutant sampling
Compiler-Based

Strong mutation

Weak mutation

Flexible weak
Higher order

integration
Compiler-
mutation

mutation
Jester Si S No Si No No No No No No No No

JavaMut S S No Si No No S No No No No No

MuJava S S No Si No No No Si Si No No No

ExMan S S No Si No No No No No No No No

Mugamma** S No - - - - No Si No No Si No

Muclipse S S No Si No No No No No No No No

Jumble No S No Si No No No No Si No No No

Testooj** S S - - Si - No No No No No No

Javalanche No S No Si No No No Si Si Si No No

AjMutator S S No Si No No No No No No No No

Judy S S No Si No No No Si* No No No No

Bacterio No S Si Si Si No No No Si Si Si Si

* Judy usa una optimizacin de mutant schemata basada en programacin orientada a aspectos.
** Mugamma y testooj usan MuJava para generar mutantes.
Tabla 6.6. Tcnicas de reduccin de costes implementadas por cada herramienta de mutacin Java

Como se observa, la tcnica de mutacin selectiva es implementada por 10


herramientas (esto supone el 100% de las herramientas de mutacin para Java que
implementan operadores de mutacin. Recordemos que Mugamma y Testooj usan
MuJava para generar mutantes, por lo que no incluyen la tcnica de mutacin
selectiva). El xito de esta tcnica de reduccin de mutantes se debe a que reduce el
esfuerzo en la construccin de las herramientas, ya que implica el desarrollo de
menos operadores de mutacin.

Las tcnicas mutant schemata y bytecode translation han sido


implementadas por cuatro herramientas, lo cual indica que los beneficios que se
obtienen durante el proceso de mutacin compensan el coste de implementar estas
114 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

tcnicas. Sin embargo, el hecho de que el resto de las tcnicas estn implementadas
en una o dos herramientas puede ser un indicador de que el coste de
implementacin es alto. Estos costes suponen que todas estas tcnicas no han sido
implementadas juntas. Como muestra la Figura 6.7, la mayora de las herramientas
de mutacin solo implementan una o dos tcnicas de reduccin de costes. Solo la
herramienta Bacterio y, en menor medida, MuJava y Javalanche incluyen un
conjunto grande de tcnicas de reduccin de costes.

pode
mutMiR
T c n ic a s de

generacin y
eecuoon
T c n ic a s *
reduccin de
m utantes

Figura 6.7. Nmero de tcnicas para reducir costes implementadas en cada herramienta

Como muestra la Figura 6.7, existe una carencia en la implementacin de


tcnicas de reduccin de costes, ya que stas no suelen estar implementadas en la
misma herramienta, por lo que no se puede obtener el beneficio conjunto de aplicar
varias tcnicas. Afortunadamente, estn apareciendo nuevas herramientas como
Bacterio, que aglutinan un conjunto mayor de tcnicas de reduccin.

Otro punto de vista interesante est relacionado con las caractersticas que
permite probar cada herramienta de mutacin. La Figura 6.8 muestra las
caractersticas del sistema que cada herramienta permite.

Figura 6.8. Caractersticas que pueden ser probadas con cada herramienta
RA-MA CAPTULO 6. PRUEBAS MEDIANTE MUTACIN 115

Como se ve en la Figura 6.8, aproximadamente la mitad de las


herramientas soportan pruebas unitarias de mtodos y clases. El resto de las
herramientas solo permiten probar una determinada caracterstica. Una excepcin
es la herramienta Bacterio, que soporta pruebas de tres tipos: unitarias, de
integracin y de sistema. Sin embargo, la herramienta ideal de mutacin debera
soportar cualquier tipo de test y, como podemos ver, incluso quedan caractersticas
por cubrir relacionadas, por ejemplo, con cuestiones de rendimiento o de
usabilidad.

A pesar de las carencias mostradas, todas estas herramientas son


indudablemente tiles. La mayora de las herramientas de mutacin estn
enfocadas a la investigacin, lo cual se demuestra con la evidente carencia de
herramientas comerciales disponibles (solo dos: Certitude y PlexTest C++). Sin
embargo, algunas de ellas pueden ser usadas perfectamente en la industria, como
son el caso de MuJava, Javalanche o Bacterio.

Teniendo en cuenta que el time-to-market es un factor crtico en la


construccin del software, que las tareas de pruebas son esenciales para asegurar su
calidad y que la mutacin es una de las tcnicas de prueba ms efectivas, las
herramientas de mutacin comerciales deberan ser fciles de usar, minimizar los
tiempos de generacin y ejecucin de mutantes, as como facilitar las tareas de
anlisis de resultados. Por otro lado, las herramientas de mutacin industriales
deberan soportar cualquier tipo de test y trabajar con tecnologas actuales, como la
web.
Captulo 7

HERRAMIENTA BACTERIO: MANUAL DE


UTILIZACIN

Bacterio es una herramienta para la prueba de aplicaciones Java basada


en mutacin, que aplica los operadores de mutacin a nivel de bytecode. Soporta
mutacin fuerte, diferentes tipos de mutacin dbil (BB-Weak/1 y BB-Weak/N),
cualificacin funcional y mutacin dbil flexible. En este captulo se explica con
detalle cmo probar un sistema por medio de Bacterio, mostrndose su forma de
utilizacin con un pequeo sistema llamado Sudoku Solver, que ayuda al usuario a
resolver los populares sudokus.

7.1 LICENCIA
La herramienta ha sido desarrollada por Pedro Reales y Macario Polo
(investigadores del Grupo Alarcos, Universidad de Castilla-La Mancha). La
empresa Alarcos Quality Center la comercializa y distribuye. No obstante, las
instituciones docentes y de investigacin pueden solicitar una licencia gratuita y
completa de Bacterio. En www.alarcosqualitycenter.com/index.php/productos/
bacterio puede solicitarse una licencia as como descargar el manual de usuario.
118 TECNICAS COMBINATORIAS Y DE MUTACION PARA TESTING DE SISTEMAS... RA-MA

7.2 SOFTWARE EXTERNO


Bacterio utiliza el siguiente software desarrollado por terceros:

7.2.1 ASM
ASM es un framework para analizar y manipular bytecode de Java. Permite
modificar clases existentes o generar clases de forma dinmica directamente en
formato binario. Permite realizar operaciones similares a las de otros frameworks
pero, en opinin de los desarrolladores de Bacterio, de forma ms sencilla.

Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved.


Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,


this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS


AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

Figura 7.1. Licencia del proyecto ASM


RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 119

7.2.2 JODE: Java Optimize and Decompile Environment


JODE es un paquete Java que contiene un descompilador y un optimizador
de cdigo y que est disponible bajo licencia GNU GPL. El descompilador lee los
ficheros con extensin .class y produce cdigo fuente Java, no igual pero s similar
al del fichero Java original. Por ejemplo, salvo que el cdigo se compile con la
opcin de depuracin, no se obtienen los comentarios ni los nombres de las
variables locales.

JODE is Copyright 1998-2000 by Jochen Hoenicke.

This program is free software; you can redistribute it and/or modify it


under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any later
version.

You can redistribute some of the packages under the terms of the of
the GNU Lesser General Public License as published by the Free Software
Foundation. See the copyright headers in the source code.

This program is distributed in the hope that it will be useful, but without
any warranty; without even the implied warranty of merchantability or fitness
for a particular purpose. See the GNU General Public License for more details.

Figura 7.2. Licencia de JODE

7.2.3 Una imagen del juego DOOM2


Bacterio utiliza una imagen del popular juego DOOM2 (distribuido con
licencia GNU GPL) para animar la ventana de ejecucin de casos de prueba.

7.3 UN VISTAZO AL PROCESO DE PRUEBAS CON


BACTERIO
El proceso de pruebas con Bacterio consta de tres etapas: generacin de
mutantes, ejecucin de casos de prueba y anlisis de resultados.

Con respecto a otras herramientas de mutacin, Bacterio genera en un solo


paso todos los mutantes para todas las clases del SUT. As, si un sistema est
compuesto por las clases A, B, C y D, Bacterio genera los mutantes para las cuatro.
Suponiendo que se generan P mutantes para A, Q para B, R para C y S para D, el
120 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

lado izquierdo de la Figura 7.3 muestra estos conjuntos de mutantes agrupados por
su correspondiente clase original; en el lado derecho se muestran todos los
mutantes de clase agrupados.

Sistema o rig in a l- A. B. C. D j
M{A], A 2, ... A P}
Mb={B, B 2, ... Bq},
M - { A h A 2, ... Ap,B/, B2, ... Bq, C i , C2, ... Cr, D, D 2, ... D s}
Mc={ch c2, . . . cy
M d = { D , , D 2, ... D s}

Figura 7.3. Mutantes que genera Bacterio para una supuesta aplicacin

Puesto que est enfocado hacia la prueba de sistemas completos. Bacterio


construye a continuacin versiones mutadas del sistema completo. Cada versin
contiene al menos una clase mutada con un fallo, aunque puede haber ms. El
orden de una versin mutada representa el nmero de fallos que contiene. La
Figura 7.4 ilustra esta idea: las versiones mutantes de orden 1 contienen un fallo;
los de orden 2 , dos fallos; etc.

Sistema original = { A, B, C, D}
Mutantes de orden 1 Mutantes de orden 2 Mutantes de orden 3 Mutantes de orden 4
M I ={A, B, C, Dj M1={A, Bj, C, D M1={A, Bh Cu Dj Ml={Ah B,, Ch D ,j
M2={A2, B, C, D} M2={A B2, C, D} M2={A|, B,, C2, D} M2={A|, B|, C|, D2}

Mj={A, B0, C, D) Mj={A, B4, Cr , D)

Figura 7.4. Algunos mutantes de diferentes rdenes

Una vez que se dispone de las versiones mutadas, el tester puede lanzar la
ejecucin de los casos de prueba contra ellas. A continuacin, tras esta ejecucin.
Bacterio muestra los resultados: matriz de muertos, mutation score y otros datos de
inters.

7.4 CONFIGURACIN Y EJECUCIN


Bacterio funciona sin problemas en sistemas Windows, Linux y Mac OS.
Los ejemplos que se muestran a continuacin se han ejecutado en un ordenador
porttil MacBook Pro con sistema operativo Mac OS X.
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 121

Utilizaremos como SUT de ejemplo el sistema Sudoku Solver, que


tenemos salvado en una carpeta SudokuSolver de nuestro escritorio. La aplicacin
tiene la estructura de carpetas que se muestra en la Figura 7.5: el cdigo fuente
est bajo la carpeta src, mientras que el cdigo compilado est bajo bin. Obsrvese
que se dispone tambin de una carpeta tests que contiene un fichero Testl.class,
que contiene casos de prueba en formato JUnit.
* SudokuSolver
* bin
sudokusolver
v i dominio
I Cas!'la.ctass
Ristras.class
H Shower .class
* Sudoku.class
l ] Utifidades.ciass
put
t g tests
H Testl.dass
* SFC
^ sudokusolver
f g | d o m im o
' Castlla.java
Ristras.java
Shower .java
Sudoku.java
_ utftidades.java
B 9'
w gg tests
Testi.java

Figura 7.5. Estructura de carpetas del proyecto Sudoku Solver

Bacterio se ejecuta lanzando el fichero Bacterio.jar. Aparece entonces la


ventana principal de la herramienta (Figura 7.6).
<>.#1 A -, ^ ifrTnrfirf <.... MutiUlan fawgBjwrttratan
Configuration Mutation Help Exploratory Testing

Mutation Test System

Figura 7.6. Ventana principal de Bacterio


122 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

7.4.1 Configuracin de carpetas


La configuracin de la herramienta se realiza a travs de la opcin
Configuration del men, que muestra el cuadro de dilogo de la Figura 7.7.

KA Configuration
V e r s io n f o ld e r : c :/d o m in io / ( Select")

T e s t c a s e s f o ld e r . c :/d o m in io /o r ig in a l/ S e le c t

T im e o u t ; | 20000 Q

A v a n c e d O p t io n s )

( * )

Figura 7.7. Dilogo de configuracin (I)

Debemos establecer la ubicacin de una carpeta ( Version folder) para


almacenar las versiones mutantes y otros resultados intermedios que requiere
Bacterio: crearemos, por ejemplo, una carpeta llamada versions en el escritorio de
nuestro Mac. La carpeta Test case folder debe apuntar a la carpeta raz bajo la que
cuelgan los casos de prueba compilados: en este ejemplo, los casos de prueba estn
en bin/tests/Testl.class: ntese que el nombre completo de la clase con los casos de
prueba es tests. Testl. class; as, la carpeta Tests cases folder ser bin, de modo que
dejamos la ventana de configuracin como en la Figura 7.8.

V e r s io n fo ld e r : /U s e r s /M a c o /D e s k to p /v e r s io n s ( S e le c t

T e s t c a s e s fo ld e r : / U s e r s /M a c o /D e s k t o p / S u d o k u S o lv e r /b in S e le c t

T im e o u t. 20000 ?

' Avanced O ptions ;

( OK ) C C a n c e l ~)

Figura 7.8. Valores de configuracin para el ejemplo del Sudoku Solver

Como, algunas veces, el fallo introducido en un mutante puede llevar a la


ejecucin de un bucle infinito (vase el ejemplo de la Figura 7.9), en el campo
Timeout de la configuracin podemos establecer un tiempo mximo de ejecucin
de un caso de prueba sobre un mutante, de manera que este se considere muerto si
se supera el valor establecido como timeout.
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 123

Original Mutante
public void testl0 { public void testl () {
for (int i=0; i<100; i++) for (int i=0; i<100; i++)
System.out.println(i); System.out.println ( i- - ) ; (*)
} }
Figura 7.9. Un operador de mutacin que produce un bucle infinito

Los casos de prueba que tenemos disponibles en Testi. class son casos de
prueba JUnit, y pueden ejecutarse con la tcnica de cualifcacin funcional
(Functional Qualification). Si pulsamos el botn Advanced options, podemos
seleccionar Functional Qualification como el tipo de mutacin (Kind o f mutation)
seleccionado {Figura 7.10).

i* ...................... C o n f ig u ra tio n
J S y te C o d e m o d if ic a tio n in r u n tim e

C o m p a ris o n M eth o d : 0 to S trin g

O F ield s i n s p e c tio n
0 to S tr in g if d e fin e d , o t h e r w i s e fie ld s i n s p e c tio n
Q H a s h c o d e fie ld s in s p e c t io n

0 to S tr in g if d e fin e d , o t h e r w i s e H a s h c o d e f ie ld s in s p e c t io n

D e p th in f ie ld in s p e c t io n

S e rv ers c o n fig u r a tio n Wf L ocal e x e c u t i o n

L ocal IP J 27.0.0.1

L ocal P o r t . 3650

S e rv e r IP: 1 2 7 .0 .0 .1

S e rv er P ort; 36S1

C a p tu re d T e s ts F o ld e r: c :/c a p iu r e d T e s ts / S e | < )

Kind o f m u ta tio n : Q F le x ib le W eak M u ta tio n

Q BB-W eak /1 M u ta tio n


0 BB- W eak i N M u ta tio n
0 S tro n g M u ta tio n
0 F u n c tio n a l Q u a lific a tio n

E x e c u tio n C o s t: U I n s tr u m e n t m u ta n t s t o g e t n u m b e r o f s o u r c e c o d e lin e s e x ...

P arallel e x e c u t i o n ( n / p r o c ... i 0

G S t o p t h e e x e c u t i o n b e tw e e n t e s t c a s e s

^ B asic o p t io n s }

1 C ancel ;

Figura 7.10. Dilogo de configuracin (II)

Para esta primera toma de contacto, la configuracin de la herramienta


queda completada y podemos pulsar OK para salvarla.
124 TECNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

7.4.2 Generacin de mutantes


Los mutantes se ejecutan a partir de la opcin Mutation, Generation de la
barra de men de la pantalla principal. Aparece entonces la ventana de la Figura
7.11.
A c r . ........................................................................ _ .... Mus*** AmcVooaJ trst-ng
Configuration Mutation Help Exploratory Testing

Classpath { ) ) Apply mutation on

High order mutation: O Do * join matan of the u r n opwator

O Oo not join mutants in th# same c lo t

t J Do not join nwa:> in the same method

O ta c h choice 0 Pat- ante


Interlace mutation operators
-----Soap parameters Throw exceptions Q INC 2 DEC Lr Each choice fust-last

7.4.3 Seleccin de los elementos para mutar


En el recuadro superior izquierdo de la ventana de generacin de mutantes
(Figura 5.5) debe cargarse la ubicacin del SUT, incluyendo, si las hay, libreras y
otros recursos adicionales. Pulsando el botn etiquetado "+" aadimos elementos a
ese cuadro: en nuestro caso, todos los ficheros requeridos del SUT estn en la
carpeta /Users/Maco/Desktop/SudokuSolver/bin. Una vez que se ha aadido la
ubicacin o ubicaciones del SUT, el tester pasa a la derecha (mediante el botn
etiquetado " " ) las carpetas que contienen los ficheros .class que van a mutarse.
En este ejemplo, la ventana queda como se muestra en la Figura 7.12.

CE3

Figura 7.12. Seleccin de la ubicacin del sistema bajo prueba (izquierda) y de los ficheros .class
que deben mutarse (derecha)
RA-MA___________ CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 125

7.4.4 Seleccin de operadores de mutacin


Para generar los imitantes, el tester debe seleccionar los operadores que
desea aplicar. Bacterio implementa diez operadores de mutacin:

Cinco de ellos (Swap, Parameter increment, Parameter decrement, Nullify


y Throw exceptions) estn inspirados en los operadores propuestos por Ghosh y
Mathur40, que definen operaciones para la mutacin de interfaces para probar
componentes desde un punto de vista de caja negra:

Swap intercambia, en una operacin, los valores de dos parmetros de


tipos compatibles mediante la modificacin de la signatura de la
operacin: as, si una clase tiene una supuesta operacin foo (int a, int
b, int c), los mutantes contendrn los nombres de los parmetros (a, b,
c) intercambiados, como por ejemplo: (b, a, c) o (c, a, b).

Incremento y decremento de parmetros (INC y DEC). Estos dos


operadores proceden del operador Twiddle, y actan incrementando y
decrementando respectivamente el valor de los parmetros numricos
cuando se entra en un mtodo.

Nullifier establece el valor de un parmetro de tipo complejo a nuil.

Throw exceptions: si un mtodo lanza n excepciones, se generan n


mutantes. En cada mutante se reemplaza el cdigo original del mtodo
por una sentencia sencilla que lanza cada una de las posibles
excepciones.

Los otros cinco operadores introducen pequeos cambios sintcticos en la


estructura del cuerpo de cada mtodo: AOR (arithmetic operator replacement'.
reemplazo de operador aritmtico), ROR (relational operator replacement:
reemplazo de operador relacional), ABS (absolute value insertion: insercin de
valor absoluto), LCR (logical connector replacement: reemplazo de conector
lgico) y UOl (unary operator insertion: insercin de operador unario) son
operadores de mutacin clsicos y son los que producen mejores resultados, de
acuerdo con diversos estudios de mutacin selectiva.

40 Ghosh, S. y Mathur, A.P., 2001, Interface mutation, Software Testing, Verification and
Reliability, (11), 227-247.
126 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

La Tabla 7.1 muestra los cambios introducidos por esos operadores en un


fragmento de cdigo Java. Las mutaciones se introducen a nivel del bytecode; no
obstante, se muestran en el correspondiente cdigo fuente con propsitos
ilustrativos.

Cdigo original
int div(int a, int b) throws NaNException, ByZeroException {
if (a==0 && b==0) throw new NANException();
if (b==0) throw new ByZeroException();
return a/b;
}
Operador Cambios introducidos
Swap int div(int b, int a)
INC int div(int a, int b) int div(int a, int b) throws ... {
throws... { b++;
a++; if ...
if . if ~
if ~ return a/b;
return a/b;
}
}
DEC int div(int a, int b) int divtint a, int b) throws _ {
throws { b--;
a- - ; if _
if ... if _
if return a/b;
return a/b;
}
}
Nullif ier int div(int a, int b) int div(int a, int b) throws _ {
throws {
a=null; b=null; /* Not
if _. applicable to int type.
if if // It is just an
example.
return a/b;
if _ */
} return a/b;
i
Throw int div(int a, int b) nt div(int a, int b) throws ~ {
exceptions throws _ { throw new ByZeroException ();
throw new
NaNException(); }
}
AOR int div(int a, int int div(int a, int int div(int a, int
b) throws...{ b) throws... { b) throws... {
if ~ if if _
if _. if if ~
return a+b; return a-b; return a*b;
i } }
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 127

ROR int div(int a, int b) throws ... {


if (a==0 || b = = 0 ) throw new N A N E x c e p t i o n ();

ABS int div(int a, int b) throws ... { int div(int a, int b) throws ...
if (Math.abs(a) ==0 && {
b==0) throw ... if (a==0 &&Math.abs (b) ==0)
if (b==0) throw new throw _
B y Z e r o E x c e p t i o n (); if (b==0) throw new
B y Z e r o E x c e p t i o n ();
return a/b;
return a/b;
i
}

UOI int div(int a, int b) throws ._{ int div(int a, int b) throws {
if (-a==0 && b==0) throw if (a==0 &&-b==0) throw

if (b==0) throw ... if (b==0) throw _.


return a/b; return a/b;
} }

LCR int div(int a, int b) throws NaNException, ByZeroException {


if (a==0 b==0) throw n e w N A N E x c e p t i o n ();
if (b==0) throw n e w B y Z e r o E x c e p t i o n ();
return a/b;
}

Tabla 7.1. Representacin en cdigo fuente de algunos cambios introducidos en una funcin Java

Para el siguiente ejemplo, seleccionamos todos los operadores de mutacin


excepto LCR (Figura 7.13).
Interfacemutationoperators:
fSw ap parameters ffThrowexceptions Sf INC ( j DEC f NUL

Traditionalmutationoperators
I AOR f ROR gf ASS Si UOt e LCR

( G et v e r s io n s

Figura 7.13. Seleccin de los operadores de mutacin

7.4.5 Seleccin de opciones para la generacin de versiones


Supongamos que disponemos del sistema que se muestra en la figura 52,
que est compuesto de cuatro clases: A, B, C, D, que han producido,
respectivamente, 5, 4, 6 y 3 mutantes.
128 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Sistema original={A, B, C, D}
Mutantes de clase=
{Ai, A2, A3, A4 , A5,
B|, B2 , B3, B4,
Ci, C2, C3, C4, C5, c 6.
Di, D2, D3 }

Figura 7.14. Sistema compuesto por cuatro clases y sus mutantes

Como se muestra en la Figura 7.18, estas clases mutantes se pueden


combinar en versiones mutantes aplicando dos tcnicas: high order mutation
(mutacin de orden superior) y mutant sampling (mutacin por muestreo).

La mutacin de orden superior combina ms de un mutante en cada


versin y se puede aplicar con varios algoritmos:

Un fallo por versin (one fault/version). En este caso, cada versin


mutante contiene un solo fallo artificial. En la Figura 7.15 aparecen
las dieciocho versiones mutantes del sistema de ejemplo. Como se ve,
cada clase mutante se incluye, al menos, en una versin, por lo que el
nmero de versiones coincide con el nmero total de clases mutantes.

{A,,B,C,D} {A, B|, C, D} {A, B, C|, D} {A, B, C, D,}


{A2, B, C, D} {A, B2, C, D} {A, B, C2, D} {A, B, C, D2}
{A3, B, C, D} {A, B3, C, D} {A, B, C3, D} {A, B, C, D3}
{A4, b , C, D} {A, B4, C, D} {A, B, C4, D}
{A5, B, C, D) {A, B, C5, D}
{A, B, Ce, D}

Figura 7.15. Las 18 versiones mutantes producidas por one fault/version

Tres algoritmos que introducen un fallo en cada clase de la versin


mutante (each choice). El nmero de versiones coincide con el nmero
de mutantes de la clase para la que se han generado ms mutantes:
para el sistema de ejemplo, puesto que para la clase C se han generado
seis mutantes, hay seis versiones mutantes, cuyas clases contienen
todas un fallo (Figura 7.16).
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 129

{Ai, B,, C i, D,}


{Ai, b 2, C2, D2}
{A3, b 3, C3, d 3}
{A4 , b 4, C4 , D,}
{A5, B,, C5, D2}
{Ai, b 2, C, d 3}

Figura 7.16. Seis versiones generadas con each choice: cada una contiene cuatro fallos

Un algoritmo de pair wise. En este caso, el algoritmo construye todas


las tablas de pares de clases mutantes. Posteriormente, deben generarse
suficientes versiones para visitar todos los pares. Para el sistema de
ejemplo, se construiran 6 tablas de pares: (A, B), (A, C), (A, D), (B,
C), (B, D) y (C, D). A continuacin, se generaran las versiones
mutantes, de manera que cada par de cada tabla se visite al menos en
una versin. En la Figura 7.17 se muestran, a modo de ejemplo, las
tablas de pares (A, B) y (A, D) y, a la derecha, todas las versiones que
se generan con esta estrategia. Ntese que se visitan todos los pares, no
solo los de las dos tablas mostradas, sino los de todas. Como tambin
se ve, cada versin mutante contiene cuatro fallos, pues todas las
clases incluidas contienen uno: mediante el campo Orden (etiqueta
Order en la Figura 7.18) se puede seleccionar el nmero de fallos que
debe incluirse en cada versin.

Pares de A, B Pares de A, D Versiones mutantes

(Ai, B i)(A4, B4) (A,, D,) {A1,B1,C1,D1} {A3,B4,C1,D2}


(A,, B2)(A5, B,) (A,, D2) {A1,B1,C6,D1} {A3,B4,C5,D1}
(A,, B3)(A5, B2) (A,, D3) {A1,B2,C2,D2} {A3,B4,C6,D1}
(A,, B4)(A5, B3) (A2, D,) {A1,B2,C5,D2} {A4,B1,C4,D2}
(A2, B i)(A5, B4) (A2, d 2) {A1,B3,C3,D3} {A4,B1,C5,D1}
(A2, b 2) (a 2, d 3) {A1,B4,C4,D1} {A4,B1,C6,D1}
(A2, B3) (a 3, d ,) {A2,B1,C2,D3} {A4,B2,C3,D1}
(A2, b 4) (a 3, d 2) {A2,B2,C1,D1} {A4,B3,C1,D3}
(A3, B,) (A3, d 3) {A2,B3,C4,D2} {A4,B4,C2,D3}
(A3,B 2) (a 4, D,) {A2,B3,C5,D3} {A5,B1,C3,D1}
130 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... O RA-MA

(A3, b 3) (A4 , D2) {A2,B3,C6,D3} {A5,B1,C4,D1}


(A3, b 4) (A,, D3) {A2,B4,C3,D1} {A5,B1,C5,D1}
(A4, B,) (A5, D,) {A3,B1,C3,D2} {A5,B2,C6,D2}
(A* B2) (A5, D2) {A3,B2,C4,D3} {A5,B3,C1,D3}
(A* B3) (A5, D3) {A3,B3,C2,D1} {A5,B4,C2,D1}

Figura 7.17. Tablas de pares de (A, B) y de (A, D) y todas las versiones mutantes generadas

La Figura 7.18 muestra tambin algunas restricciones que pueden


seleccionarse para la combinacin de las clases mutantes en versiones mutantes:
Do not joint mutants in the same class impide que, en la misma versin, se
introduzcan dos errores presentes en la misma clase: realmente. Bacterio puede
generar una sola versin con dos fallos en la clase A: {A2, B, C, Dj, donde A l2
representa una clase que contiene el fallo introducido en A y el fallo introducido
en A2- Las otras dos opciones {Do not join mutants o f the same operator y Do not
join mutants in the same method) impiden, respecticamente, que en una misma
versin haya dos errores artificiales procedentes del mismo operador de mutacin y
que en una misma versin se introduzca un mtodo con dos errores artificiales.

La figura tambin muestra la barra para Mutacin por muestreo {Mutant


sampling), que permite generar solo un porcentaje del nmero total de versiones,
que son seleccionadas aleatoriamente.

High order mutacin: |_j Do not join mutants of the same operator

0 Do not join mutants in the same class

0 Do not join mutants in the same method

@ One fault/version 0 Each choice 0 Pairwise

0 fach choice first-last

0 Random each choice

Order '* 0 <

Mutant sampling:

%Size 25%

( Mount versions )

Figura 7.18. Algoritmos y opciones para la combinacin de los mutantes de las clases en versiones
mutadas

1.4.6 Generacin de clases y versiones mutantes


Para este ejemplo, dejaremos las opciones de generacin como se muestran
en la Figura 7.18 (el Mutant sampling reducido al 25%, etc.) y los operadores que
indicbamos en la Figura 7.13. Tras pulsar el botn Get versions, Bacterio nos
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 131

permite seleccionar de manera ms fina las clases y mtodos que deseamos


mutar: en este caso (vase Figura 7.19), quitamos la muesca de seleccin al
paquete tests: las clases en este paquete son clases con casos de prueba y no deben
mutarse.
m JQ Ctaites gtfccttoB to t* rouWfed
4 Aif packages
'r i f sutokusotvef dominio
0 Casita
w 0 Ristras
0 <infrov
0 jnSudokuOgava/ang/btrmg:
0 Shower
0 Sudoku
0 Utilidades

*osa
0 sudokusoher.flui

( f o T ) ( Cancel )

Figura 7.19. Seleccin de las clases y mtodos que se desean mutar

Instantes despus de pulsar OK, Bacterio nos informa de que ha terminado


de aplicar el ltimo operador de clases mutantes (Figura 7.20).

f ~ C e t v e r sio n s ^ ) F in ish ed ICR

Figura 7.20. La generacin de clases mutantes ha terminado

Si el usuario lo desea, puede ver un resumen de los resultados de la


generacin de mutantes: el nmero total de mutantes (2199, como se ve en la
Figura 7.21) o el nmero de mutantes por operador.

f C O ______ _____________________ _ ______________ y___________ ____


T o ta l m u t a n t s
Total Mutants rot inc uoi dec swa aor nuf te* abs
2199 997 47 41 8 47 32 21 6 23 1 418

M u ta n ts

Mutant Name *.......... Class Method : O perator Extra Info


d e c ,s u d o k u s o lv e r,d o m m io .S u d o k u .2 6 _ 0 _ 1 1 2 su d o k u so lv e r.d o m in to .S u d o k u colum nasC ubiertasllID Z dec p a r a m e te r 2 *
d e c .s u d c k u s o lv e r.d o m in io .S u d o k u .2 7 _ G _ i 13 su d o k u so lv e r.d o m in io .S u d o k u c o lu m n a sC u b ie rta sflDZ dec p a r a m e te r 3
d e c .s u d o k u s o lv e r.d o m in io .S u d o k u .2 8 _ 0 _ 1 1 4 su d o k u so lv e r.d o m in io .S u d o k u co lu m n a sC u b ie rta s {IIIDZ dec p a r a m e te r 4 *
d e c .su d o k u so lv e r.d o m in io .S u d o k u .Z 9 _ G _ 1 1 5 su d o k u so lv e r.d o m in io .S u d o k u m a rea rP rohib idosPorFiaGDV dec p a ra m e te r 1
d e c .s u d o k u s o lv e r.d o m in io .$ u d o k u .2 J 3 _ 8 8 su d o k u so lv e r.d o m in io .S u d o k u hayC ertezalbZ dec p a r a m e te r 2 Si
mArrarProhihidnsPnirFiAillV.. d e c .......... n a ra m p tp r.2 ... ...jjsy

V e r s io n s

V e rs io n M u ta n t 1
veijtuu.*! tu t .su u u d k u su iv e i . u w n i w i x i i M . j T ^ r j n / "
v e rs io n s 4 2 ro r.su d o k u so lv e r.d o m in io .C a sflla .5 4 _ 4 _ 4 2 G
versfcm 543 ro r.s u d o k u so lv e r.d o m in io . C asilla.5 8 _ 3 _ 4 2 4
v e rs io n 5 4 4 ro r.s u d o k u so lv e r.d o m in io .C a s illa .7 _ 2 _ 3 7 3
v e rsio n S 4 5 uoi.su d o k u so lv er .dom m io.C asilla. 1 1 _ 0 _ 1 7 9 2
v e rs io n 5 4 6 u o i.s u d o k u s o lv e r.d o m in io .C a silla .l2 _ 0 _ 1 7 9 3

Figura 7.21. Resumen de resultados de la generacin de clases mutantes


132 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

A continuacin, podemos generar las versiones mediante el botn Mount


versions. Puesto que hemos elegido la opcin One fault/version, Bacterio genera
tantas versiones como mutantes. Puesto que tambin seleccionamos un 25% como
Mutant sampling, la herramienta genera 550 versiones mutantes que se seleccionan
al azar (Figura 7.22). Bacterio crea una carpeta vaca por cada versin, en la que
dejar los resultados correspondientes a esa versin

T o ta l m u ta n ts
Tot roe inc uoi dec swa aor nuf tex abs
2199 997 47 418 47 32 216 23 1 418

M u ta n ts

Mutant Na Class Method O perator Extra Info


d e c .s u d o ... sudokuso.. . colum nas.. . dec p a ra m e t...
d e c .s u d o ... sudoku so . colum nas . . dec p a ra m e t...
d e c .s u d o ... sudokuso.. . colum nas.. . dec p a ra m e t...
d e c . su d o ... sudokuso.. . m arcarP r... dec p a ra m e t...
d e c .s u d o ... sudokuso. . hayC erte dec p a ra m e t
d e c .su d o .. sudokuso . m arcarP r . dec p a ra m e t. .
d e c .s u d o sudokuso . m arcarP r dec p a ra m e t
d e c .su d o .. sudokuso.. . m arcarP r... dec p a ra m e t...
d e c .s u d o sudokuso m arc a rP r... dec p a ra m e t. .

M utant!
IW.iUUU&UWIVCI..U U IIIH !IU .C <l>llld.J Li t X /
versionS 42 ror.sudokusolver dom into.C asdia. 54_4_4 2 0
verston543 ror. sudokusolver .dom im o.Ca sdla. 5 8_3_4 24
versio n 5 4 4 ror sudokusolver dom irao.C asilia.7_2_373
versionS4S uoi. sudokusolver . dom fnio.Casilla. 1 i _ 0 _ i 792
versio n 5 4 6 uoi. sudokusolver .dominio. Casilla. 12_G_1793
iversion547 uoi.sudokusolver dom inio.C asdla. 1 9_0_ 1 8 0 0
v ersio n s 4 6 uoi.sudokusolver..domink>.CasHla.3_G_1784
versk>n549 uoi.sudokusolver .dominio. C asilla.4_G_l 785
versionSSO uoi. sudokusolver dom tnio.C asilla.9_G _1790

Figura 7.22. Ubicacin de las versiones mulantes

1A.1 Ejecucin de casos de prueba


En este momento disponemos de todo lo necesario para ejecutar los casos
de prueba contra los mutantes. Es decir, contamos con:

Versiones mutantes del sistema.

Algunos casos de prueba en la clase tests/Testl.class.

Para ejecutar los casos, elegimos la opcin Execution dentro de Mutation


en la barra de mens de la ventana principal, y se muestra la pantalla de la Figura
7.23.
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 133

MaSAito' functional testing


C o n fig u ra tio n M uU O on H elp tu p lo r a to r y T es tin g

M
inclass l L^ 1
_____l22d8 y toad *)

Available v e is ions : Reset f e s t C a se s j


Alive v e rsio n s Alive C overed versions Died versions Equivalent versions

C p lt* it O Console activate I * " " >wwAomfawca^tow KasultaJ

Figura 7.23. Ventana de ejecucin

En primer lugar, cargamos las versiones mutantes (mediante el botn


Load). Puesto que no hay versiones muertas (no hemos ejecutado todava ningn
caso de prueba), todas ellas aparecen en la lista etiquetada Alive versions (versiones
vivas) de la Figura 7.24. Obsrvese que las versiones que se cargan en la lista son
las ubicadas en el campo Desktop/versions del dilogo de configuracin (Figura
7.7).

Alive versions
(^Select all Unselect all >

Itarstont *'
/versionlO )
/version 100
/version 101
/versionl02 t

f c C V v, versions. SSO
Figura 7.24. Lista de versiones vivas

Se pueden seleccionar las versiones que se quieran ejecutar, que, en


nuestro caso, sern todas: para ello, pulsamos Select all y luego Execute mutants.
Bacterio muestra un pequeo dilogo para seleccionar los casos de prueba que se
ejecutarn (Figura 7.25), y que toma de la carpeta especificada en el campo Tests
cases folder especificado en la configuracin (Figura 7.7).
134 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

^ xx T e s t C a s e s s e le c tio n

3 All th e te s ts
* S t e s t s .T e s tI
3 testG o F o rw ard
3 testG oB ack

0 F ull T e s t s 0 E x e c u te f i r s t w ith J U n it

@ V e r s io n o r ie n t e d

O T e s t C a s e o r ie n te d OK ( C ancel

Figura 7.25. Seleccin de los casos de prueba que se ejecutarn

Dejamos las opciones como se muestran, pulsamos OK y comienza la


ejecucin del proceso, que se hace en dos pasos (Figura 7.26).

1. En el primero, Bacterio ejecuta los casos de prueba dos veces contra el


programa original. De este modo, Bacterio es capaz de detectar las
reas del sistema cuyo comportamiento o estado puede depender de
factores aleatorios, que no se considerarn a continuacin.
2. Luego, se lanza la ejecucin de los casos de prueba contra los
mutantes.
o - K illin g m u t a n t s

E x e c u ti n g m u t a n t v e r s i o n s

16%

( C ancel )

Figura 7.26. Bacterio, ejecutando casos de prueba y tratando de matar mutantes

7.5 ANLISIS DE RESULTADOS


Cuando ya se han ejecutado todos los casos de prueba, Bacterio muestra
los resultados en la ventana de la Figura 7.27\ versiones muertas, mutation score,
matriz de muertos (marcados con X) y heridos (los marcados con O; consideramos
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 135

que un muante est herido cuando un caso de prueba ha pasado por l pero no ha
conseguido matarlo), matriz de tiempos de ejecucin y alguna informacin
adicional.
m
Total killed m utants
versions mutants ror uoi Inc idee swa i aor
2 0 8 /5 SO 208/550 87/236 74/106 8/12 8/10 8/11 18/56
-
Percentage
versions mutants ror uoi Inc idee sva i aor
37.818 37.818 36.868 69.818 66.668 80.08 72.728 32.14
IS
Killing matrix
Version tests.Testl _te*tGoFemrard tests.Testl_tstCoBack
version249 X rj
version248 X 1
verstor247 O O *
version246 X ii;
Time execution matrix (milliseconds)
Version tests.Testl_testCoForward tests.Testl testCoBack
verskm249 831 nr
vetston248 168 i? i
versfcm247 231 242 W-
versk>n246 67
E xtra n fo m ato n

V ersions killed by tim e o u t: 3 T otal kills: 20S

V ersions killed norm ally an d by tim e o u t. 0 T otal Tim e o u ts : 3

V ersions co v ered b u t n o t kilted: 30 0

V ersions n o t co v ered a n d n o killed 43

( Previous p ag e ( N ext page ' ( Go to page: ) (0 to 55)

Figura 7.27. Resultados de la ejecucin de los casos de prueba

Al regresar a la ventana de ejecucin, Bacterio actualiza las listas de


versiones con los nuevos datos: ahora, informa de las versiones vivas, heridas y
muertas (Figura 7.28).
Available versions

Alive versions Alive Covered versions Died versions Equivalent versions


f Sate c ta tt ^ f yns# ee t H | ( Select All ) I UnseNtct Aft ) ( Select all ; Unselect ail ;

!/versiones 1 /versionl /versionl 15 m \


/versksnlO /versionl 66
|/version? 1 t
/versionlOO /versionl 89
I/v*rsion92
/version101 /versionl 90
I/version?3
[/versions I I/versionl 02 /versionl 91
*
live versions 42 Total covered versions 300 Total died versions ?08 Total equivalent versions 0

Figura 7.28. Resultados de la ejecucin. De izquierda a derecha: versiones vivas (alive), heridas
(alive covered) y muertas (died)

7.5.1 Presencia de azar


La ejecucin de algunos casos de prueba encuentra, a veces, la presencia de
azar en el sistema bajo prueba, lo que llevara a la obtencin de resultados cada vez
distintos y a tener la impresin equivocada de que mueren con facilidad todas las
136 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

versiones mutantes. Bacterio detecta esta aleatoriedad ejecutando dos veces los
casos de prueba contra el sistema original; entonces, deja de comparar, para
detectar los mutantes muertos, las porciones del sistema afectadas por el azar. Pero,
por otro lado, existen casos de prueba que pueden incluir valores aleatorios, que
tambin mataran fcilmente a todos los mutantes, sin que ello signifique que la
calidad del test suite sea alta. En estas situaciones. Bacterio calcula el riesgo de los
casos de prueba aleatorios e informa de ellos al usuario, preguntndole si desea
ejecutarlos en una ventana como la mostrada en la Figura 7.29.

'' A tte n tio n - R a n d o m n e s s f o u n d in t h t^ s e l e c te d t e s t

T h e n e x t t e s t c a s e s h a v e b e e n f o u n d w ith r a n d o m n e s s .

P le a s e , d e s e le c t t h e t e s t c a s e s th a t y o u d o n n o t w a n t t o e x e c u te
T h e r a n d o m n e s s in t e s t s c a n p r o d u c e v a ria tio n in t h e m u ta tio n s c o re , s o tw o e x e c t i o n s o f t h e s a m e
m u ta n t s w ith t h e s a m e t e s t s c a n p r o d u c e tw o d iff e re n t m u ta t io n s c o r e s . A ls o , r a n d o m l e s s c a n
p r o d u c e t h a t a t e s t k ills all t h e m u ta n t s .
<$,% r a n d o m ie s s . Low ris k .

All th e low risk tests


j~ te s ts .T e s tl
I testfUftrforo #.9S?6S1209S?feS43%

S% - 10% r a n d o m le s s . A c c e p ta b le ris k .

All the acce p ta b le risk tests

10% - 50% r a n d o m n e s s . H ig h ris k .

I Ail the a c ce p ta b le risk tests

> 5 0 % r a n d o m n e s s . N o a c c e p t a b le ris k .

0 AB th e a c ce p ta b le risk tests

CKD
Figura 7.29. Bacterio informa de la aleatoriedad encontrada en los casos de prueba

7.5.2 Enriquecimiento del test suite con nuevos casos de


prueba
Como observbamos en la Figura 7.27, nuestro test suite consigue un
mutation score del 37,81%, que es muy bajo. Por ello, debemos aadir nuevos
casos de prueba que descubran los fallos introducidos en las versiones que
permanecen vivas. En este ejemplo trataremos de matar las versiones llamadas
version91, version92, version93 y version94, que se mostraban en el lado izquierdo
de la Figura 7.28.
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 137

Para conseguir un caso de prueba que mate a la version91 (y,


probablemente, a otras versiones), hacemos doble clic en version91 para ver su
cdigo fuente y escribir el caso de prueba. Gracias a JODE (seccin 7.2.2),
Bacterio descompila el cdigo y lo muestra (Figura 7.30): el cdigo descompilado
puede no coincidir exactamente con el cdigo original escrito por el programador.
En el ejemplo de la figura, el cambio introducido est en la condicin c> 9 que, en
el mutante, ha sido sustituido por c<=9 \ Si este mutante fuese equivalente,
podramos marcarlo como tal mediante la muesca Mark as equivalent que aparece
en la parte inferior.

* S o u rc e c o m p a r is o n

O r i g in a l s o u r c e c o d e M u ta n t s o u r c e c o d e

p a c k a g e s u d o k u so fv er.g u i; p a c k a g e su d o k u so lv e r.g u t;
im p o rt ja v a .a w t.R e a a n g le . w npoft j a v a .a w t R ectan g le
im p o rt ja v a .a w t.e v e n tK e y A d a p te r; im p o rt jav a .a w t.e v e n t.K e y A d a p te r;
im p o rt java.aw t.ev en E K ey E v ertt; im p o rt jav a.aw t.ev em .K ey E v ertf

im p o rt ja v a x , sw ing J T e x tF ie Id: im p o rt jav ax .sw in g .JT ex tF ie Id;

p u b lic c la s s jTFC asilla e x te n d s JT extF ietd p u b lic c la s s JTFC asilla e x te n d s JT extF ieid
{ i
pu b lic JTFCasiBaO (
p u b lic JTFC aslllaO {
initialized; initialized;
) | >
p riv a te void initialized { p riv a te void initialized {
se tB o u n d sn e w R e c tan g le (0 , 0 , 2 4 , 25)); se tB o u n d s(n e w R e c tan g le (0 , 0 . 2 4 . 2 5
a d d K e y 5 te n e r(n e w K eyA dapter) { a d d K e y s te n e r tn e w K eyA dapterO {
final JTFC asilla ihisSO = JTFC asilla.this. final JTFC asilla thisSO = jT F C asilla.this;


s u p e r0 ; super e

p u b lic v o id key R e ea se d K e y E v e n t k e y e v en t) { p u b lic void keyR e le a s e d ik e y E v e n t k ey ev en t) I


dvisS O .validartkeyevenf.getK eyC harO ): f thfsSO .vaH darikeyevem .getK eyC hari)};

p u b lic void v a lid a rlc h a r c? {

s e tT e x tT ) ; s e tT e x tO :
if (getT extO .lengthO > 1) if g etT e x tj.le n g th O > 1)
setTextT*); s e tT e x tC ) ;
}
p u b lic String toStringO { p u b lic String toStringO I
r e tu r n g etT extf); r e tu rn getT extO ;
}

j M ark a s e q u i v a l e n t

Figura 7.30. Cdigo de la clase original de la versin mutada (izquierda) y cdigo


de la clase mutada

La sentencia en la que se ha introducido el cambio no deja colocar un


carcter en la casilla si este no est entre 0 y 9. En el mutante, no se deja colocar
entre 0 y 8. Un nuevo caso de prueba que coloque un 9 producir un resultado
distinto en el programa original y en el mutante, con lo que este se dar por muerto.
El nuevo caso de prueba lo aadimos a la clase tests/Testl.java y la recompilamos.
138 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Podemos reejecutar la clase tests/Testl; sin embargo, los casos ya ejecutados


(testGoForward y TestGoBack) no matarn ms mutantes de los que ya mataron,
por lo que solo ejecutaremos el nuevo (testFivelnput, Figura 7.31) y solo sobre las
versiones vivas (alive versions).
** F7 *est C ases s e le c tio r
&All iie tests
i tests.T estl
O testGoForward
_ j testGofUck

0 fu ll T ests (3E xecute first w ith JUnit


0 V ersion o rien ted
0 T est C ase orien ted ( OK ) C ancel }

Figura 7.31. Seleccionamos solamente el nuevo caso de prueba

Como podemos ver en la Figura 7.32, la version91 aparece ahora marcada


como muerta (en la matriz de muertos tiene una X). Adems, hemos conseguido el
efecto colateral de matar otras versiones, como la version92.

Total killed m u tan ts

5 /3 4 2 ....... 5/342 3/149 1/32 0 /4 0 /2 0 /3 0 /3 8 *1/7 0 /1 0 7

Percentage
versions mutants ro r uo< Inc dec swa aot nut abs
1.46% 1.46% 2.01% 3.12% 0.0% 0.0% 0.0% 0.0% 14.28% 0.0%

Killing matrix
Version rest* Test! tesrtivelnput
version95 O
ve(sior>94 X
version'll 0
version92 X
versions] X
Time execu tio n m atrix (m illiseconds)
Version tests Test l_t.tFivtnput
vers 0095 32 4
versions 4 73
versions 3 21 t
versions? 24
versions 3 20
Extra infom ation

V ersions killed by tim e o ut: 1 Total kills: 4


V ersions killed norm ally a n d by tim e out: 0 Total Time o u ts 1
V ersions coveted b ut n o t killed 4
Versions n o t c overed an d n o killed: 334

f Previous p ag e f N ext p a g e ^ C. to Pa9*

Figura 7.32. Nuevos resultados de la ejecucin

7.5.3 Testing exploratorio


Para las aplicaciones que disponen de interfaz grfica, el usuario puede
aplicar testing exploratorio: mientras el tester va ejecutando la aplicacin
interactuando con las ventanas, Bacterio almacena una traza de los eventos, que
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 139

luego puede ser reproducida y lanzada contra los mutantes. Cada escenario de
ejecucin, entonces, conforma de este modo un caso de prueba.

Los casos de prueba exploratorios no se pueden analizar con Cualifcacin


Funcional (.Functional Qualification), por lo que primero debemos alterar la
configuracin (Figura 7.10) y elegir, por ejemplo, Flexible Weak Mutation. Una
vez modificada la configuracin, seleccionamos Exploratory Testing -> Capture en
la ventana principal.

Hecho esto, pulsamos el botn Load de la ventana de ejecucin; Bacterio


carga entonces todas las clases del sistema en una lista desplegablc, seleccionamos
la clase de arranque (la que contenga la funcin main) y pulsamos Start Capturing
{Figura 7.33).
# | ES Mutation funciona*tcstmg
Configuration Mutation Help Exploratory Testing _______________ _____________________________________________

Main class: | suttokusolver/gui/JFSudoku c lass ( Load

Figura 7.33. Ventana de testing exploratorio

A continuacin, podemos establecer parmetros de ejecucin para la


mquina virtual de Java en un nuevo dilogo {Figura 7.34), que, para la aplicacin
de los sudokus que venimos utilizando como ejemplo, no son necesarios, por lo que
pulsamos directamente Run versin. Bacterio solicita entonces el nombre del
escenario de ejecucin que vamos a lanzar (lo llamaremos ExploratoryTestCasel),
se lanza la ejecucin de la aplicacin original y todos los eventos que vayamos
produciendo se van almacenando en la carpeta indicada en Captured tests folder de
la ventana de configuracin, que mostrbamos en la Figura 7.10.
140 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

^ E x e c u ti n g a v e r s i o n / o r i g i n a d

lava O ptions

A p p l i c a t io n A r g u m e n t s

f Run v e rs io n ;

Figura 7.34. Dilogo de configuracin de la mquina virtual

p p p Executm q a version ./original

Java O ptions

Figura 7.35. Almacenamiento de un caso de prueba exploratorio

Para lanzar el escenario de ejecucin contra los mutantes, seleccionamos el


botn de opcin Captured Test (Figura 7.23) y pulsamos Execute Mutants. El
proceso contina de forma similar a la ejecucin tradicional de casos de prueba.

7.5.4 Ejecucin en paralelo


Con el objeto de reducir los costes de la mutacin, Bacterio puede lanzar
en paralelo la ejecucin de los casos de prueba en mquinas diferentes (Figura
7.36):

El Local node es el que utiliza el tester para crear los mutantes, lanzar
la ejecucin y mostrar los resultados.
RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 141

El Facade node acta de fachada entre el nodo local y los nodos


remotos: recibe los casos de prueba y los mutantes del nodo local y los
distribuye, segn el algoritmo de distribucin elegido, a los nodos
remotos.

Cada Remote executor recibe mutantes y casos de prueba del nodo


fachada, los ejecuta y devuelve los resultados al nodo local tambin a
travs del nodo fachada.

ocalNod Facadede Reinteexecuternodes

Figura 7.36. Arquitectura fsica para la ejecucin en paralelo

Cada ejecutor remoto se ubica normalmente en una mquina diferente y se


arranca mediante el comando java -jar remoteExecutor.jar ip puerto
carpetaTemporal nmeroDeProcesadores, donde ip es la direccin IP del nodo
remoto, puerto es el puerto de escucha, carpetaTemporal hace referencia a una
carpeta vaca (en la que se almacenarn datos y resultados intermedios) y
nmeroDeProcesadores es el nmero de procesadores o de ncleos de
procesamiento del nodo.

Una vez que los nodos remotos estn en ejecucin, se lanza el nodo
fachada, contenido en el fichero facadeNode.jar, que muestra la interfaz que
aparece en la Figura 7.37. Los dos primeros parmetros se refieren,
respectivamente, a la direccin IP y al puerto de escucha de este nodo. El siguiente
parmetro se refiere al algoritmo de distribucin que se utilizar para repartir el
trabajo en los nodos remotos; la zona inferior se utiliza para dar de alta nodos
remotos en el nodo fachada. Respecto de los algoritmos de distribucin. Bacterio
implementa cinco:

1. PEDRO {parallel execution with dynamic ranking and ordering:


ejecucin paralela con ordenacin dinmica): distribuye las cargas de
trabajo dinmicamente, entregando en cada momento una cantidad de
trabajo diferente, dependiendo de los tiempos de ejecucin y de la
carga de los nodos remotos.
142 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

2. Distribute versions (distribucin de versiones): mediante este


algoritmo, cada nodo remoto ejecuta todos los casos de prueba contra
un subconjunto de versiones. El nmero de versiones que ejecuta cada
nodo es el nmero total de versiones dividido por el nmero de nodos
remotos.
3. Distribute test cases (distribucin de casos de prueba): mediante este
algoritmo, cada nodo remoto ejecuta un subconjunto de casos de
prueba contra todas las versiones. El nmero de casos de prueba que
ejecuta cada nodo es el nmero total dividido por el nmero de nodos
remotos.
4. Give versions on demand (entrega de versiones bajo demanda), este
algoritmo entrega todos los casos de prueba a cada nodo remoto. El
nodo remoto solicita una versin a la fachada y, cuando la recibe, la
ejecuta y le pide una nueva versin. Obviamente, cada versin es
ejecutada solamente en un nodo remoto.
5. Give test cases on demand (entrega de casos de prueba bajo demanda):
este algoritmo entrega todas las versiones a todos los nodos remotos y
un caso de prueba. Cuando el nodo remoto ha ejecutado el caso contra
todas las versiones, solicita un nuevo caso al nodo fachada y procede
con su ejecucin. Cada caso de prueba se enva nicamente a un nodo
remoto, de tal modo que el mismo caso no se ejecuta en dos nodos
remotos diferentes.
P a ra re ii E x e c u tio n S y s te m __
D i s tr i b u to r S e rv e r A d d r e s s

D i s tr i b u to r S e rv e r A d d r e s s IP D i s t r i b u t o r S e rv e r A d d r e s s P o rt

A lg o r ith m s

[PEDRO Algorithm - ft
D istribute versio n s - 1
D i s tr i b u ti o n A l g o r ith m s D istribute t e s t c a s e s - 2
Give v ersions o n d e m a n d - 3
Give te s t c a s e s on d e m a n d - A

P arallel N o d e s :
U n used a d d re s s e s U sed a d d re s s e s

{_ < R em ove ;

R e m o v e S e le c te d A d d r e s s e s R e m o v e S e le c te d A d d r e s s e s

IP A d d r e s s ..................................
A dd A d d r e s s
P o rt A d d r e s s

'v S ta rt D i s tr i b u to r S erv er

Figura 7.37. Interfaz de usuario del nodo fachada


RA-MA CAPTULO 7. HERRAMIENTA BACTERIO: MANUAL DE UTILIZACIN 143

Una vez que se han lanzado los nodos remotos y que en el nodo fachada se
ha seleccionado el algoritmo de distribucin y se han configurado adecuadamente
el resto de los parmetros, se pulsa Start Distributor Server y se comienza el
reparto del trabajo entre los nodos remotos. Cuando todos los nodos remotos han
terminado las ejecuciones que les han sido encomendadas, los resultados son
devueltos al nodo local (Figura 7.36), de modo que el tester pueda ver los
resultados de la ejecucin.
Captulo 8

AUTOEVALUACIN

Una vez estudiado el contenido de este libro, el lector debera haber


adquirido o enfatizado, deseablemente, una serie de conocimientos. En este
captulo se incluye un test de autoevaluacin de 24 preguntas. Si bien es
orientativo, se sugiere el aprobado con 16 o ms preguntas correctas, sin que resten
las preguntas respondidas errneamente.

En la seccin 8.2 se presentan las respuestas correctas y se comentan la


mayora de ellas.

8.1 PREGUNTAS

1/24

Un caso de prueba:

a) Debe encontrar tantos errores como sea posible.


b) Debe ser reproducible.
c) Debe poder ejecutarse tan rpido como sea posible.
d) Las respuestas A, B y C son correctas.
146 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

2/24

Cuando se sigue un proceso de pruebas que combina caja negra y caja


blanca, el proceso puede parar:

a) Cuando el test suite no encuentra ningn error.


b) Cuando se alcanza el umbral de cobertura deseado.
c) Cuando A y B son ciertas.
d) Cuando A o B son ciertas.

3/24

Suponga que estamos probando un sistema desarrollado por un tercero. Si


seguimos un proceso de pruebas que combina caja negra y caja blanca y
encontramos un error en el sistema no demasiado crtico, deberamos:

a) Aadir ms casos de prueba hasta que se alcance el umbral de


cobertura deseado y, entonces, informar de este y de otros errores al
desarrollador.
b) Corregir el error y reejecutar todas las pruebas.
c) Reejecutar todos los casos de prueba hasta que el error haya
desaparecido.
d) Informar del error al desarrollador y esperar a recibir una nueva
versin del sistema.

4/24

Cuando se aplica a un conjunto de parmetros un algoritmo que obtenga el


producto cartesiano de algunos conjuntos, produce el mismo resultado que:

a) Each choice.
b) Pairwise.
c) Sentencias.
d) All combinations.
RA-MA CAPITULO 8. AUTOEVALUACION 147

5/24

Disponemos de un conjunto de parmetros que, combinados, pueden


producir hasta 150 casos de prueba, numerados del 0 al 149. Qu ocho casos de
prueba se obtendran con la aplicacin del algoritmo del Peine (Comb)?

a) 0-18-36-54-72-90-108-126.
b) 0-18-37-56-75-93-112-149.
c) 0-24-49-83-98-121-147-149.

6/24

En general, la tcnica All combinations'.

a) No genera casos de prueba redundantes.


b) No cubre todos los pares.
c) Genera casos de prueba redundantes.
d) Cubre todos los pares.
e) Las respuestas A y B son correctas.
f) Las respuestas C y D son correctas.

7/24

Cul de las condiciones RIP no se necesita en mutacin dbil (weak


mutation)?

a) R (reachability, alcance).
b) I (infection, infeccin).
c) P {propagation, propagacin).

8/24

Considere la siguiente especificacin:


if ( (A && (B | | C) ) || !A)
x := z ;
endif
148 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... ORA-MA

Qu es ((A && (B || Q ) || !A)?

a) Una decisin.
b) Una condicin.
c) Un punto de prueba.
d) Una condicin/decisin modificada.

9/24

Considere la siguiente especificacin:


if ((A && (B || C) ) II !A)
X :=z ;

endif

Qu valores de (A, B, C) logran cobertura de decisiones?

a) (false, true, true), (false, true, false).


b) (true, true, true), (false, false, false).
c) (true, false, false), (true, true, true).

10/24

Considere la siguiente especificacin:


if ( (A && (B || C) ) || !A)
x: =z ;
endif

En cul de las siguientes combinaciones para (A, B, C) es A la variable


que determina que la salida sea cierta (true)?

a) (true, true, false).


b) (true, false, false).
c) (false, true, true).
d) Las respuestas A, B y C son correctas.
e) Las respuestas B y C son correctas.
f) Las respuestas A y C son correctas.
RA-MA CAPITULO 8. AUTOEVALUACION 149

11/24

Considere la siguiente especificacin:

Cul es el nmero mnimo casos de prueba que se requiere para cubrir


todas las transiciones?

a) 2.
b) 3.
c) 4.
d) 5.
150 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

12/24

Considere la siguiente especificacin:

Cul es el nmero mnimo casos de prueba que se requiere para cubrir


todos los pares de transiciones?

a) 4.
b) 6.
c) 7.
d) 8.
e) 9.
RA-MA CAPTULO 8. AUTOEVALUACIN 151

13/24

Considere que una clase Cuenta referida a una cuenta bancaria tiene las
siguientes operaciones: Cuenta (constructor), retirar, ingresar, transferir. Para
generar casos de prueba, el tester ha escrito la siguiente expresin regular:

Cuentaingresar(ingresar | retirar | transferir)*

Cuntas plantillas de prueba de longitud 4 se pueden generar?

a) 1.
b) 3.
c) 33= 27.
d) 9.
e) 52.

14/24

Considere la siguiente especificacin, que representa el mtodo retirar de


una clase Cuenta:
public void retirar(importe : double) throws ZeroException,
InsufficientBalanceException
begin
if (importe<=0)
throw new ZeroException ()
if (this.balancecimporte)
throw new InsufficientBalanceExceptionO;
this.saldo=this.saldo-importe;
end

Suponga un caso de prueba que maneja una cuenta con un saldo de 300 .
Cules de las siguientes son clases de equivalencia correctas para el importel

a) (-o, 300], (300, +o).


b) (-oo 300), [300, +o).
c) (-oo, 0], (0, 300), [300, +oo).
d) (-oo, 0], (0, 300], (300, +oo).
152 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

15/24

Para un cierto problema, se han encontrado las siguientes clases de


equivalencia para un parmetro entero:

[10,19], [20,100], [101,3000]

Si se aplica la variante ligera de la tcnica de valores lmite, cules son los


correspondientes valores para [20, 100]?

a) 19,20,21,99,100,101.
b) 19,21,99,101.
c) 19,20,100,101.
d) 20,21,99,100.

16/24

De entre las operaciones de una clase, cules son las ms adecuadas para
escribir el orculo de un caso de prueba?

a) Constructores.
b) Mtodos get.
c) Mtodos set.
d) En general, los mtodos que cambian el estado del objeto.

17/24

Cul es la etapa ms costosa del testing mediante mutacin:

a) La generacin de mutantes.
b) La ejecucin de los casos de prueba contra los mutantes.
c) El anlisis de resultados.
d) La mutacin de orden superior (high-order mutation) o mutacin de
orden N, siempre que N>1.
RA-MA CAPTULO 8. AUTOEVALUACIN 153

18/24

Considere la siguiente tabla, que muestra el cdigo original de una funcin


y el de un muante:

Original Mutante
if ((A && (B || C)) || !A) if ( (A && (B && C) ) II !A)
x: = z ; x: = z ;
endif endif

Cul de los siguientes casos de prueba (para A, B, C) mata al mutante?

a) (true, true, true).


b) (true, true, false).
c) (false, false, false).
d) Las respuestas A, B y C son correctas.

19/24

Considere la siguiente matriz de muertos para un programa con 10


mutantes y un test suite con 5 casos de prueba:

tcl tc2 tc3 tc4 tc5


mi X X
m2 X X
m3 X X X
m4 X X
m5 X
m6 X
m7 X X
m8 X
m9 X
mlO
154 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Cul de los siguientes sera el test suite reducido obtenido por un


algoritmo voraz?

a) (tcl, tc2, tc4, tc5).


b) (te 1, tc2, tc4).
c) (tc2, tc4, tc5).
d) (tc2, tc4).
e) El test suite no se puede reducir porque mlO est vivo.

20/24

Cul de los siguientes criterios de cobertura es ms adecuado para probar


una funcionalidad crtica?

a) Decisiones.
b) Condiciones.
c) Condiciones/decisiones.
d) Condicin/decisin modificada.

21/24

Se desea probar una funcin que toma los cuatro parmetros A, B, C y D.


Los valores de prueba que se han identificado son los siguientes:

A = (1, 2, 3), B = (1, 2), C = (a, b, d) y D = (true, false)

Se desea probar la funcin mediante cobertura pairwise, para lo que se han


obtenido los siguientes casos de prueba:

1 (1, 1, a, false}
2 {1, 2, d, true}
3 {1, 2, b, false}
4 (3, 1, d, false}
5 {3, 1, b, false}
6 {3, 2, a, true}
7 {2, 1, d, false}
8 {2, 1, b, true}
RA-MA CAPTULO 8. AUTOEVALUAC1N 155

Solo falta un caso para lograr la cobertura deseada. Cul es?

a) (2, 2, a, false).
b) (2, 2, d, false).
c) (2, 3, f, true).
d) (3, 1, d, true).

22/24

Considere la siguiente especificacin:


if (A && (B || C) )

Cul de los siguientes casos de prueba para A, B y C alcanza cobertura


tanto de condiciones como de decisiones?

a) (true, true, false), (true, false, true), (true, false, false).


b) (false, false, false), (true, false, true).
c) (true, true, true), (false, true, false), (false, false, true).

23/24

Considere la siguiente matriz de muertos para un programa con 10


mutantes y un test suite con 5 casos de prueba. Considere tambin que el mutante
mlO es funcionalmente equivalente.

tcl tc2 tc3 tc4 te 5


mi X X
m2 X X
m3 X X X
m4 X X
m5 X
m6 X
m7 X X
m8 X
m9
mlO
156 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Cul de las siguientes expresiones utilizaremos para calcular el mutation


score?

a) 8/10.
b) 8/9.
c) 10/10.
d) 8/8.
e) 9/9.

24/24

Considere la siguiente matriz de muertos para un programa con 10


mutantes y un test suite con 6 casos de prueba. Las celdas marcadas con X indican
que el muante est muerto, y las marcadas con O indican que la sentencia mutada
ha sido ejecutada por el caso de prueba, pero que ha permanecido vivo. Las celdas
vacias indican que la sentencia mutada no ha sido recorrida.

tcl tc2 tc3 tc4 tc5 tc


mi X
m2 X
m3 X
m4 X
m5 O O 0 O
m6 X X
m7 X 0
m8 0
m9 X
mlO

Cul de las siguientes afirmaciones es ms correcta?

a) Tc2 es un caso de prueba inefectivo.


b) Tc5 es un caso de prueba inefectivo.
c) Probablemente, m5 es un mutante equivalente.
d) Probablemente, mlO es un mutante equivalente.
e) Las respuestas A y D con ciertas.
RA-MA CAPTULO 8. AUTOEVALUACIN 157

f) Las respuestas B y C son ciertas.


g) Las respuestas A, B, C y D son ciertas.
h) Las respuestas A, B, C y D son falsas.

8.2 SOLUCIONES

1/24

D. Las respuestas A, B y C son correctas.

En efecto, ya que las pruebas tienen un carcter destructivo, los casos de


prueba deben encontrar tantos errores como sea posible (en la seccin 1.1 se afirma
que el objetivo de las pruebas debe ser maximizar el nmero de los errores
encontrados por un nmero finito y, deseablemente, pequeo, de casos de prueba;
en la capacidad de los casos de prueba para encontrar errores se basan, tambin, las
pruebas de mutacin).

Los casos de prueba deben ser tambin reproducibles, para que se pueda
obtener siempre el mismo resultado, de xito o de fallo, siempre que se ejecute.

Del mismo modo, debe poder ejecutarse tan rpido como sea posible, con
el objeto de minimizar el tiempo y los recursos dedicados al testing. Por ello, entre
otras cosas, se minimizan los test suites con algoritmos voraces o similares: para
conseguir test suites con menos casos de prueba que alcancen los mismos
resultados que el test suite original, respecto a algn criterio de cobertura (vase,
por ejemplo, la seccin 6.5).

2/24

C. Cuando A y B son ciertas.

La Figura 3.1 ilustra un posible proceso de pruebas con las caractersticas


indicadas en el enunciado: efectivamente, se termina de probar cuando se alcanza
la cobertura preestablecida sin que se encuentren errores en el sistema.

3/24

A. Aadir ms casos de prueba hasta que se alcance el umbral de cobertura


deseado y, entonces, informar de este y de otros errores al desarrollador.
158 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Si bien esto no se cita expresamente en el texto, una factora de pruebas


debera avanzar en la prueba de una release de un sistema y tomar nota de todos los
errores encontrados. A la finalizacin del ciclo de pruebas, informar de todos ellos
al desarrollador para que los corrija.

4/24

D. All combinations.

Como se explica detalladamente en la seccin 5.3.1, el producto cartesiano


de n conjuntos produce todas las combinaciones de los elementos de esos n
conjuntos.

5/24

B. (0-18-37-56-75-93-112-149).

El algoritmo Comb o del Peine (seccin 5.3.6) toma el primer caso de


prueba (el 0), el ltimo (149), el que est en la mitad (75), el que est entre el 0 y el
75, etc.

6/24

F. Las respuestas C y D son correctas.

All combinations produce todas las posibles combinaciones de valores, por


lo que habr, probablemente, casos de prueba que no incrementen la cobertura. Y,
obviamente, se cubren todos los pares.

7/24

C. P (propagation, propagacin).

En mutacin dbil no se requiere la condicin de propagacin (seccin


6.5.2), ya que los mutantes muertos se buscan inmediata o casi inmediatamente
despus de la instruccin mutada: por ello, sta debe ser alcanzada (reached) y se
debe producir un cambio de estado respecto del programa original en el mismo
lugar (infeccin).
RA-MA CAPTULO 8. AUTOEVALUACIN 159

8/24

A. Una decisin.

9/24

C. (true, false, false), (true, true, true).

Para conseguir cobertura de decisiones (seccin 3.4.2), se debe conseguir


que la decisin tome los valores true y false. En la siguiente tabla se muestran los
valores que toma la decisin con los dos casos de prueba de cada opcin de
respuesta. Como se observa, solo los valores de la opcin C hacen que la decisin
tome los valores true y false.

Opcin A B C (A && (B I | C) ) H !A Resultado


False True True (False && (True ) | True) ) || True
True =
= (False && True) || True =
= False || True = True
A)
False True False (False && (True || False) ) True
| True =
= (False && True) ) || True =
= False || True = True
True True True (True && (True | | True) ) || True
False =
= True || False = True
B)
False False False (False && (False ( | False) ) True
|| True =
= False | | True = True

True False False (True && (False | | False) ) False


| | False =
= (True && False) | | False =
C) = False || False = False
True True True (True && (True | | True) ) || True
False =
= True || False = True

10/24

F. Las respuestas A y C son correctas.


160 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

En la opcin A, el valor true de las condiciones A y B hace que sea true el


valor del fragmento (A && (B || C)), con lo que la condicin A est determinando
el resultado de la decisin completa.

En la opcin B la decisin vale false, resultado que no es aplicable al


enunciado de la pregunta.

En la opcin C, el hecho de que A sea false hace que se verifique como


true la condicin !A. La decisin, adems, vale true gracias tambin al valor de la
condicin B.

Por tanto, A determina la salida de la condicin como true para las


opciones A y C.

11/24

C. 4.

Se requieren 4 casos de prueba para llegar desde el nodo inicial hasta el


final:

Uno que haga A=true, B=false, C=false.


Uno que haga A=true, B=false, C=true.
Uno que haga A=true, B=true.
Uno que haga A=false.

12/24

A. 4.

Se requieren 4 casos de prueba.

13/24

D. 9.

Una expresin regular se puede expandir para generar, a partir de ella,


plantillas de prueba, que luego, mediante la asignacin de datos a los parmetros,
permiten obtener casos de prueba reales.
RA-MA CAPTULO 8. AUTOEVALUACIN 161

En el ejemplo del enunciado, todas las plantillas comenzarn por


Cuenta-ingresar y, posteriormente, se podrn generar 32 combinaciones: 3
elementos incluidos en la clausura transitiva tomados de dos en dos.

14/24

D. (-o, 0], (0, 300], (300, +oo).

De acuerdo con el cdigo, debemos comprobar importes menores iguales a


0, pues conducen a la excepcin ZeroException: por ello, descartamos las opciones
A y B.

Para decidir entre las otras dos, observemos que la


InsufficientBalanceException se lanza cuando el saldo es estrictamente menor que
el importe. Puesto que el saldo es, segn el enunciado, de 300 euros, el extremo
derecho del intervalo central no puede ser abierto, por lo que nos decantamos por la
opcin D.

15/24

C. 19, 20, 100, 101.

En la seccin 4.1 se describen las dos variantes de la tcnica de clases de


equivalencia. Se dice que En la variante ligera, por cada clase de equivalencia se
toman como valores de prueba los propios valores lmite de la clase y los valores
adyacentes de las clases de equivalencia adyacentes. Por tanto, para el elemento
20 de la clase [20, 100], tomaremos el 20 y el 19; para el 100, el 100 y el 101.

16/24

B. Mtodos get.

Los orculos (seccin 5.2) determinan si el resultado obtenido por el caso


de prueba se corresponde con el esperado. Para ello, interrogan al objeto resultante
para comprobar su estado, lo cual se consigue mediante la invocacin a mtodos de
acceso (get).

17/24

B. La ejecucin de los casos de prueba contra los mutantcs.


162 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

Efectivamente, los tiempos de generacin de imitantes son muy pequeos


en relacin con la ejecucin de los casos de prueba contra los, posiblemente, miles
de mutantes que se pueden generar para un programa mediano. El anlisis de
resultados puede llevar tambin mucho tiempo si se considera la identificacin de
los mutantes equivalentes.

Por otro lado, la respuesta que se ofrece como opcin D no tiene ningn
sentido en esta pregunta.

18/24

B. (true, true, false).

Con el caso mostrado en la opcin A, tanto el programa original como el


muante ofrecen una respuesta true, con lo que el muante vive.

Con el caso B, el original va a true porque: [ (true && (true || false))


| | false] = [(true && true) | | false] = true | | false = true. El imitante va
a false porque: [(true && (true && false)) || false] = [(true && false) ||
false] = false || false = false. El caso B, por tanto, mata al mutante.

Respecto a C, tanto el original como el mutante van a true porque A=false


y, entonces, la condicin !A vale true.

As pues, la respuesta correcta es la B.

19/24

D. (tc2, tc4).

Un algoritmo voraz toma, en primer lugar, el caso de prueba que mata ms


mutantes y lo aade al test suite reducido, por lo que se elegira en primer lugar el
caso tc4. A continuacin, el algoritmo eliminara de la lista de mutantes aquellos
que ya han sido muertos por tc4 y aadira al test suite reducido el siguiente caso
que mate ms mutantes, que, en este caso, es el tc2. Se eliminaran, entonces, los
mutantes matados por tc2. Observamos que nos queda simplemente mlO, mutante
al que no mata ningn caso de prueba, por lo que el test suite reducido se queda
con tc2 y tc4, siendo la D la respuesta correcta.

Los test suites mostrados en las opciones A, B y C tambin tienen menor


tamao que el original, pero no proceden de la aplicacin de un algoritmo voraz
como el que se ha comentado en el prrafo anterior.
RA-MA CAPTULO 8. AUTOEVALUACIN 163

La respuesta E, por otro lado, no es vlida porque, como se acaba de ver,


un test suite puede reducirse aunque no alcance un 100% de cobertura o no mate al
100% de los mutantes.

20/24

D. Condicin/decisin modificada.

21/24

C. 19, 20, 100, 101.

Como se ve en la tabla de pares que nos muestran, falta por visitar el par
(2, 2) de la tabla de los parmetros A y B. Por tanto, podemos descartar las
opciones C y D: la C porque el par (2, 3) no existe (el 3 no es un valor del segundo
parmetro); el (3, 1, d, true) porque vemos enseguida que visita tres pares ya
visitados: (3, 1), (3, d) y (1, d) por el caso 4; (3, true) por el caso 6; y (d, true) por
el caso 2.

Los pares visitados por B ya son visitados por los otros casos de prueba: en
el caso 7 se visitan los pares (2, d) de (A, C) y (2, false) de (A, D) y de (B, D); (2,
d) de (B, C) se visita en el caso 3.

De entre las opciones A y B nos quedamos con la A, que visita el par (2, a)
de la tabla (A, C) y el (2, 2) de (A, B).

22/24

C. 19, 20, 100, 101.

Para lograr cobertura de condiciones es preciso poner todas las condiciones


y todas las decisiones a true y a false.

En la opcin A, la condicin A no se pone a false.

En la opcin B, la condicin B vale false en los dos casos de prueba, con lo


que tampoco es vlida.

En la opcin C, las tres condiciones toman los valores true y false. La


decisin completa toma los siguientes valores:
164 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

(true && (true || true)) = true

(false && (true || false)) = false || true = true

(false && (false || true)) = false && true = false

La opcin C, por tanto, satisface ambos criterios y es la respuesta correcta.

23/24

B. 8/9.

El mutation score (Figura 6.2) es el nmero de mutantes muertos dividido


por el nmero total de mutantes no equivalentes. Puesto que mueren 8 mutantes y,
de entre los 10, hay uno equivalente, el mutation score es 8/9.

24/24

F. Las respuestas B y C son ciertas.

Un caso de prueba es inefectivo cuando no mata ningn muante. La


respuesta A, entonces, es falsa, porque tc2 mata al muante mi. La respuesta B es
cierta porque tc5 no consigue matar a ningn mutantc.

Respecto a la respuesta C, observemos en la matriz de muertos que hay


varios casos de prueba que recorren el mutantc m5 sin llegar a matarlo, por lo que,
probablemente, sea en efecto un mutante equivalente. No ocurre esto con mlO, que
no es recorrido por ningn caso de prueba.

Por tanto, son ciertas las respuestas B y C, con lo que la respuesta correcta
es la F.
INDICE ALFABETICO

Clases de equivalencia.................................. 49
A Clustering......................................................102
Adecuado para la mutacin.........................92 Cobertura...........................................26, 31, 42
AETG........................................................ 75,88 De sentencias............................................. 34
Algoritmo del peine.....................................86 U m bral.......................................................32
Algoritmos aleatorios..................................86 Cobertura de condiciones..............................36
All combinations........................................70,74 Cobertura de condiciones/decisiones.......... 37
Anlisis de cobertura...................................26 Cobertura de decisiones................................ 36
Anlisis de resultados..................................97 Cobertura de estados..................................... 43
Antirandom.................................................84 Cobertura de pares de transiciones...............44
Arcos...........................................................36 Cobertura de secuencia completa.................45
ASM.......................................................... 118 Cobertura de sentencias................................ 34
Automatic Efficient Test Generator............75 Cobertura de transiciones..............................43
Cobertura modificada de
condiciones/decisiones.............................39
B Cobertura mltiple de condiciones...............39
Cobertura pairwise.........................................88
Boundary values..........................................51
Combinacin.................................................. 74
Branches......................................................36
Compiler based............................................ 112
Bytecode........................................... 102,113
Compiler-integration....................................103
Condiciones................................................... 36
c Condiciones R1P.......................................... 103
Condiciones/decisiones................................. 37
Cada eleccin..............................................74 Conjetura de errores...................................... 52
Cada uso......................................................55 Conjunto de prueba....................................... 21
Caja blanca..................................................25 Criterios de cobertura.................................... 31
Caja negra...................................................23 U tilidad......................................................32
Caso de prueba..21, 49, 59, 61,69, 88, 92, 93 Para mquinas de estado......................... 42
Estructura...............................................59 Para valores de prueba.............................54
Exitoso....................................................22 Ctweb.............................................................. 86
Inefectivo................................................99 C U T ................................................................ 24
166 TCNICAS COMBINATORIAS Y DE MUTACIN PARA TESTING DE SISTEMAS... RA-MA

D J
Datos de prueba.................................... 21,93 JODE 119
Datos de salida............................................53
DCC............................................................37
Decision/Condition coverage......................37 L
Decisiones...................................................36 Lasttofirst 109
Defecto........................................................20
Differentoperators..................................... 109
Distancia Hamming.....................................84 M
Dominio de entrada.....................................49
Mquina de estados.........................66, 67, 68
DOOM2.................................................... 119
Mquinas de estado................................... 42,65
Matriz de muertos.................................... 100
E Matriz de mutantes muertos...................... 100
MC/DC........................................................39
Each choice.................................................74 Modelo de trabajo.......................................32
Each use..........................................55, 69, 74 Modified Condition/Decision Coverage.... 39
Efecto acoplamiento....................................97 Multiple Condition Coverage......................39
Ejecucin de casos de prueba......................97 Mutacin
Entidad-interrelacin...................................60 Proceso...................................................97
Equivalente Reduccin de costes...............................99
Mutante..................................................93 Mutacin de orden n ................................. 108
Error............................................................20 Mutacin de orden superior...................... 102
Error-guessing.............................................52 Mutacin selectiva.................................... 101
Esquema entidad-interrelacin....................60 Mutant schemata............................... 103, 113
Estado..........................................................66 Mutante.......................................................92
Vivo...................................................... 106
F Mutante equivalente....................................93
Mutante muerto...........................................92
Fallos artificiales.........................................92 Mutante vivo..............................................92,99
Fixtures........................................................63 Mutantes equivalentes.................................93
Flexible weak mutation............................. 106 Mutation adequate.......................................92
Mutation score................94, 97, 98, 100, 108
Mutation-adequate...................................102
G Myers, B......................................................23
Generacin de mutantes..............................97
N
H N-wise 56, 69
Hamming
Distancia.................................................84
Herramientas de mutacin......................... 111
o
High-order mutants................................... 102 Objetivo de las pruebas
Hiptesis del programador competente...... 97 Objetivo..................................................21
HOM (high-order mutants)....................... 102 Operadores de mutacin..............................94
Orculo........................................... 21,64, 65
Orden n ..................................................... 108
I
Integracin .27
RA-MA NDICE ALFABETICO 167

Setup........................................................... 63
P Strong mutation................................. 104, 112
Pairwise...............................55, 69, 74, 75, 88 SUT............................................................. 19
Pairwise with Restrictions, Order and
Weight................................................... 79 T
Pares de transiciones............................. 44, 69
Particiones de equivalencia........................49 Tabla de pares................ ....................... 81
Peine........................................................... 86 Teardown....................... ........................63
Pesos.......................................................... 81 Test case......................... ....................... 21
Postcondicin............................................. 66 Test data......................... ..................... 21
Problema del tringulo............................... 23 Test suite........................ 21,55, 92, 93,98
Proceso de pruebas......................................34 Test suite reducido......... .......................100
Proceso destructivo.....................................21 Testing exploratorio....... ........................25
Producto cartesiano......................... 71,72, 74 Time-to-market.............. ...................... 115
Programa original.................................. 92, 97 TMAP............................ ........................33
Programador competente............................97 Todas las combinaciones ........................70
PROW........................................................ 79 Todas las tupias.............. ........................56
Pruebas caja blanca.....................................25 Todos los pares.............. ........................55
Pruebas de caja negra................................. 23 Transicin...................... .........................66
Pruebas de integracin................................27 Tringulo........................ ......... 24, 34, 103
Pruebas de recuperacin............................. 28
Pruebas de rendimiento...............................28
Pruebas de resistencia................................ 28 U
Pruebas de seguridad...................................28 Umbral........................................................98
Pruebas de sistema......................................28 Umbral para la cobertura.............................32
Pruebas de unidad...................................... 27 Unidad de prueba........................................27
Pruebas estructurales.................................. 25
Pruebas exhaustivas.................................... 19
Pruebas funcionales.....................................25 V
Pruebas unitarias........................................ 27
PUT............................................................19 Valores de prueba.......................................54
Criterios de cobertura.............................54
Valores lmite.............................................. 51
R Veredicto..................................................... 21
Vivo.......................................................... 106
Ramas..........................................................36
Randommix...............................................109
Reachability.............................................. 103 VY
Reduccin de costes....................................99
R1P............................................................103 Weak mutation.......................................... 104
Web............................................................. 86

s
Secuencia completa .45
Tcnicas combinatorias y de mutacin
para testing de sistemas software
Las pruebas de software son un elemento fundamental para garantizar la calidad de
los sistemas que se construyen. Sin embargo, es frecuente que tanto los gestores como los
desarrolladores, presionados por los plazos de entrega, no las ejecuten con la suficiente
profundidad y no se detecten errores que, a la hora de pasar el sistema a produccin,
evidencien problemas con los usuarios.

En la literatura tcnica y en todos los planes de estudio de Informtica se incluyen


una serie de tcnicas de prueba bien conocidas (clases de equivalencia, valores lmite, etc.).
Adems de recordar estos conceptos, este libro describe con profundidad estrategias
combinatorias para testing, presentando ejercicios y dando al texto un enfoque muy prctico
y claro, con la finalidad de que sus contenidos puedan ser aplicados con facilidad.

En una segunda parte del libro se describen las pruebas mediante mutacin que,
durante aos, han sido objeto de investigacin pero que, ahora, se revelan ya como una
tcnica muy til aplicable a nivel industrial.

El libro resultar de utilidad tanto para gestores, desarrolladores y equipos de testers,


que podrn repasar y actualizar sus conocimientos, si bien es tambin especialmente
adecuado como texto para las asignaturas de ingeniera de software.

You might also like