La información que se utiliza para diseñar las pruebas se coge de muchos sitios: modelos de diseño, interfaces
clasificadoras, gráficos de estado y código. En algún punto, esta información del documento de origen debe
transformarse en pruebas ejecutables:
-
entradas específicas proporcionadas al software que se está probando
-
una configuración de hardware y software particular
-
inicializadas en un estado conocido
-
se esperan resultados específicos
Es posible ir directamente de la información del documento de origen a las pruebas ejecutables, aunque a menudo resulta
útil añadir un paso intermedio. En este paso, lasideas de prueba se escriben en una Lista de ideas de prueba, que se
utiliza para crear pruebas ejecutables.
Una idea de prueba (a veces conocida como requisito de prueba) es una sentencia breve sobre una prueba que se podría realizar.
A modo de ejemplo sencillo, pensemos en una función que calcula una raíz cuadrada y le surgen varias ideas de prueba:
-
dar un número apenas inferior a cero como entrada
-
dar cero como entrada
-
probar un número que sea cuadrado perfecto, como 4 o 16 (¿el resultado es exactamente 2 o 4?)
Estas ideas podrían convertirse fácilmente en una prueba ejecutable con descripciones de entrada exactas y los
resultados esperados.
Esta forma intermedia menos específica tiene dos ventajas:
-
las ideas de prueba son más fáciles de revisar y comprender que las pruebas completas, el razonamiento que las
soporta es más sencillo
-
las ideas de prueba soportan pruebas más potentes, como se describe más adelante en la cabecera Diseño de pruebas con la lista
Todos los ejemplos de raíz cuadrada describen entradas, pero las ideas de prueba pueden describir cualquier de los
elementos de una prueba ejecutable. Por ejemplo, "imprimir en una LaserJet IIIp" describe un aspecto del entorno de prueba que se va a utilizar para una prueba, igual que
"prueba con base de datos llena"; sin embargo, estas últimas ideas de prueba están muy incompletas: ¿Imprimir
qué en la impresora? ¿Hacer qué con la base de datos llena? No obstante, aseguran que no se olvidan ideas
importantes; ideas que se describirán con más detalle en el diseño de pruebas.
A menudo, las ideas de prueba se basan en modelos de anomalía; nociones de qué anomalías son plausibles en software y
cómo se pueden descubrir estas anomalías. Considere, por ejemplo, los límites. Se puede presuponer, tranquilamente, que
la función de raíz cuadrada se puede implementar de forma similar a la siguiente:
doble raíz cuadrada(doble x) {
si (x < 0)
// error de señal
...
También es plausible que < se escriba incorrectamente como <=. Las personas cometen este error a
menudo, por lo que es aconsejable comprobarlo. La anomalía no se puede detectar si X tiene el valor 2, ya
que tanto la expresión incorrecta (x<=0) como la expresión correcta (x<0) tomarán la misma
ramificación de la sentencia if. De igual modo, si X tiene el valor -5 no se podrá encontrar la
anomalía. La única manera de detectarla es proporcionar a X el valor 0, que justifica la segunda idea de
prueba.
En este caso, el modelo de anomalía es explícito. En otros casos, es implícito. Por ejemplo, cuando un programa
manipula una estructura enlazada, es recomendable compararla con una estructura circular. Es posible que muchas
anomalías lleven a una estructura circular manejada incorrectamente. Para la prueba, no es necesario enumerarlas, basta
con saber que es bastante probable que se produzca una anomalía para que valga la pena ejecutar la prueba.
En los enlaces siguientes encontrará información sobre cómo obtener ideas de prueba de diferentes clases de modelos de
anomalía. Los dos primeros son modelos de anomalía explícitos; el último utiliza modelos implícitos.
Estos modelos de anomalía se pueden aplicar a muchos productos de trabajo diferentes. Por ejemplo, el primero describe
qué hacer con las expresiones booleanas. Estas expresiones se pueden encontrar en código, en condiciones de vigilancia,
en gráficos de estado y diagramas de secuencia, y en descripciones en lenguaje natural de los comportamientos del
método (como las que puede encontrar en una API publicada).
Ocasionalmente, también resulta útil tener directrices para productos de trabajo específicos. Consulte el apartado Directriz: Ideas de prueba para gráficos de estado y diagramas de actividad.
Una lista de ideas de prueba particular puede contener ideas de prueba de muchos modelos de anomalía, y estos modelos
de anomalía pueden derivarse de más un producto de trabajo.
Supongamos que está diseñando pruebas para un método que busca una cadena de caracteres en una recopilación secuencial.
En esta búsqueda, tiene la opción de seguir o ignorar el guión; la búsqueda devuelve el índice de la primera
coincidencia que se encuentre o -1 si no se encuentra ninguna coincidencia.
int Collection.find(String string,
Boolean ignoreCase);
A continuación, se proporcionan algunas ideas de prueba para este método:
-
se ha encontrado una coincidencia en la primera posición
-
se ha encontrado una coincidencia en la última posición
-
no se ha encontrado ninguna coincidencia
-
se han encontrado dos o más coincidencias en la recopilación
-
el guión se ha ignorado; se ha encontrado una coincidencia, que no lo sería si se hubiese seguido el guión
-
se ha seguido el guión; se ha encontrado una coincidencia exacta
-
se ha seguido el guión; se ha omitido una cadena de caracteres que, si se ignorase el guión, sería una coincidencia
Sería fácil implementar estas siete pruebas, una por cada idea de prueba. Sin embargo, se pueden combinar diferentes
ideas de prueba en una sola prueba. Por ejemplo, la prueba siguiente satisface las ideas de prueba 2, 6 y 7:
Configuración: recopilación inicializada en ["dawn", "Dawn"]
Invocación: collection.find("Dawn", false)
Resultado esperado: el valor de retorno es 1 (sería 0 si no se omitiese "dawn")
Cuanto menos específicas sean las ideas de prueba, más fácil es combinarlas.
Es posible satisfacer todas las ideas de prueba en tres pruebas. ¿Por qué son mejores tres pruebas que satisfagan siete
ideas de prueba que siete pruebas separadas?
-
Cuando se crean muchas pruebas simples, es frecuente crear la prueba N+1 copiando la prueba N y modificarla lo
justo para satisfacer la nueva idea de prueba. El resultado, especialmente en software más complejo, es que la
prueba N+1 probablemente ejercite el programa de la misma manera que la prueba N. Coge casi exactamente la misma
vía de acceso en el código.
Un número más pequeño de pruebas, que satisfagan varias ideas de prueba cada una, no admite un enfoque "copiar y
modificar". Todas las pruebas serán algo diferentes a la anterior, ejercitarán el código de maneras distintas y
tomarán vías de acceso distintas.
¿Por qué eso es mejor? Si la lista de ideas de prueba fuese completa, con una idea de prueba para cada anomalía
del programa, no importaría cómo se escribiesen las pruebas. Pero en la lista siempre faltan algunas ideas de
prueba que podrían detectar errores. Si todas las pruebas hacen cosas muy diferentes a la anterior, añadiendo una
variedad que aparentemente no es necesaria, aumentan las posibilidades de que una de las pruebas encuentre un error
de pura casualidad. En efecto, las pruebas más complejas y pequeñas aumentan la posibilidad de que la prueba
satisfaga una idea de prueba que no sabía que necesitaba.
-
A veces, cuando crea pruebas más complejas, se le ocurren ideas de prueba nuevas. Esto sucede con menos frecuencia
con las pruebas simples, porque gran parte de lo que está haciendo es exactamente igual a lo que hizo en la prueba
anterior, por lo que su mente se embota.
No obstante, existen motivos para no crear pruebas complejas.
-
Si cada prueba satisface una sola idea de prueba y la prueba de la idea 2 falla, sabrá inmediatamente la causa más
probable: el programa no maneja una coincidencia en la última posición. Si una prueba satisface las ideas 2, 6 y 7,
será más difícil aislar la anomalía.
-
Las pruebas complejas son más difíciles de comprender y mantener. La intención de la prueba es menos obvia.
-
Las pruebas complejas son más difíciles de crear. La construcción de una prueba que satisfaga cinco ideas de prueba
suele requerir más que tiempo que la construcción de cinco pruebas que satisfagan una idea cada una. Además,
resulta más fácil cometer errores, como pensar que cumple con las cinco ideas cuando sólo cumple con cuatro.
En la práctica, debe encontrar un equilibrio razonable entre complejidad y simplicidad. Por ejemplo, las primeras
pruebas a las que someta el software (normalmente, laspruebas aleatorias) deben ser simples, fáciles de comprender y de mantener y
estar diseñadas para detectar los problemas más obvios. Las pruebas posteriores deben ser más complejas, aunque no
tanto que no se puedan mantener.
Cuando haya terminado un conjunto de pruebas, es recomendable contrastarlas con los errores de diseño de pruebas
característicos que se describen en el apartado Concepto: Prueba de desarrollador.
Una lista de ideas de prueba es útil para las revisiones e inspecciones de los productos de trabajo de diseño. Por
ejemplo, observe esta parte de un modelo de diseño que muestra la asociación entre las clases Departamento y Empleado.
Figura 1: Asociación entre las clases de empleado y departamento
Las reglas para crear ideas de prueba desde un modelo de este tipo le piden que tenga en cuenta el guión si el
departamento tiene muchos empleados. Si observa un diseño y se pregunta "¿qué pasaría si, en este punto, el
departamento tuviese muchos empleados?", podría descubrir errores de análisis o diseño. Por ejemplo, podría darse
cuenta de que sólo se puede transferir un empleado a la vez entre departamentos. Esto puede ser un problema si la
empresa tiende a realizar reorganizaciones en las que es necesario transferir muchos empleados.
Estas anomalías, de casos donde se pasó por alto una posibilidad, se llaman anomalías de omisión. Al igual que
las propias anomalías, es probable que haya omitido pruebas que detecten estas anomalías en el esfuerzo de prueba. Por
ejemplo, consulte [GLA81], [OST84], [BAS87], [MAR00] y otros estudios que muestren con qué frecuencia se escapan las anomalías de
omisión al despliegue.
El rol de las pruebas en las actividades de diseño se trata en más profundidad en el apartado Concepto: Diseño de primera prueba.
La rastreabilidad es una cuestión de intercambios. ¿Su valor se merece
el coste del mantenimiento? Debe considerar esta cuestión durante la Tarea: Definir las necesidades de rastreabilidad y valoración.
Cuando la rastreabilidad es beneficiosa, es habitual rastrear las pruebas hasta los productos de trabajo que las
inspiraron. Por ejemplo, puede tener rastreabilidad entre una API y sus pruebas. Si la API cambia, sabrá qué pruebas
debe cambiar. Si el código (que implementa la API) cambia, sabrá qué pruebas debe ejecutar. Si le extraña una prueba,
puede buscar la API para la que se diseñó.
La lista de ideas de prueba añade otro nivel de rastreabilidad. Puede realizar un rastreo desde una prueba hasta las
ideas de prueba que satisface y, después, desde las ideas de prueba hasta el producto de trabajo original.
|