jueves, 9 de mayo de 2013

Pruebas de caja negra


Recordando el objetivo de la prueba, debemos diseñar pruebas que tengan la mayor probabilidad de encontrar el mayor número de errores con la mínima cantidad de esfuerzo y tiempo.

Las pruebas de caja negra se refieren a las pruebas que se llevan a cabo sobre la interfaz del software. O sea, pretenden demostrar que las funciones del software son operativas, que la entrada se acepta de forma adecuada y que se produce una salida correcta, así como que la integridad de la información externa se mantiene. Una prueba de caja negra examina algunos aspectos del modelo fundamental del sistema sin tener mucho en cuentala estructura lógica interna del software.

Las pruebas de caja blanca se basan en el minucioso examen de los detalles procedimentales. Se comprueban los caminos lógicos del software proponiendo casos de prueba que ejerciten conjuntos específicos de condiciones y/o bucles.

A primera vista parecería que una prueba de caja blanca muy profunda nos llevaría a tener "programas 100 por ciento correctos", pero desgraciadamente, la prueba exhaustiva presenta ciertos problemas logísticos. Incluso para pequeños programas, el número de caminos lógicos posibles resulta ser enorme, con lo que no se pueden probar estos caminos en un tiempo razonable.

¿Por qué no gastamos, entonces, todas nuestras energías en las pruebas de caja negra? La respuesta se encuentra en la naturaleza misma de los defectos del software. A menudo creemos que un camino lógico tiene pocas posibilidades de ejecutarse cuando de hecho, se puede ejecutar muchas veces. Los errores de escritura son en su mayoría descubiertos por los mecanismos de comprobación de sintaxis, pero otros permanecerán indetectados hasta que comience la prueba, siendo igual de probable que exista un error tipográfico en un oscuro camino lógico que en un camino principal. La prueba de la caja negra, sin tener en cuenta cómo sea de completa, puede pasar por alto los tipos de errores que acabamos de señalar.

1.1- Prueba del camino básico.

El método del camino básico, propuesto por Tom McCabe, permite al diseñador de casos de prueba obtener una medida de la complejidad lógica de un diseño procedimental y usar esa medida como guía para la definición de un conjunto básico de caminos de ejecución. Los casos de prueba derivados del conjunto básico garantizan que durante la prueba se ejecuta por lo menos una vez cada sentencia de programa.

Cualquier representación del diseño procedimental se puede traducir a un grafo de flujo. La complejidad ciclomática de este grafo (como se definió en la clase anterior) define el número de caminos independientes del conjunto básico de un programa y nos da un límite superior para el número de pruebas que se deben realizar para asegurar que se ejecuta cada sentencia al menos una vez.

Un camino independiente es cualquier camino del programa que introduce por lo menos un nuevo conjunto de sentencias de procesamiento o una nueva condición.

En términos del grafo de flujo, un camino independiente se debe mover por lo menos por una arista que no haya sido recorrida anteriormente a la definición de un camino.

La complejidad se puede calcular de tres formas:
1.- El numero de regiones del grafo de flujo
2.- Aristas - Nodos + 2
3.-Nodos predicado + 1 (un nodo predicado es el que representa una condicional if o case, es decir, que de él salen varios caminos)
El valor de V(G) nos da el número de caminos linealmente independientes de la estructura de control del programa. Entonces se preparan los casos de prueba que forzarán la ejecución de cada camino del conjunto básico.

Ejemplo:
Diseñemos un algoritmo que sea capaz de procesar una situación de overflow cuando un conjunto de N pilas comparten un área de memoria común de M localizaciones enumeradas de L0 a Lm.

L0 L1 L2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LM

Entradas al programa:

N - Cantidad de pilas
b(j), t(j) J = 1, ..., N
i - Pila donde se va a efectuar una inserción
Si t(i) > b(i+1) ocurre overflow. Tres casos son posibles:
1.- ¿Existe espacio a la izquierda? Se decrementa j desde i hasta 1 hasta encontrar que t(j) <= b(j+1). Si se encuentra, se corren a la izquierda una posición todas las pilas desde la j+1 hasta la pila i. Posteriormente se procede a ejecutar la inserción abandonada.
2.- Si no existe espacio a la izquierda ¿existe a la derecha? Se incremente j desde i hasta M hasta encontrar que t(j) <= b(j+1). Si es así, se corren todas las pilas 1 posición a la derecha desde la i+1 hasta la j. Efectuar la inserción abandonada.
3.- Si no existe espacio a la derecha ni a la izquierda, el overflow no tiene solución.
Caminos:
1 2 9
1 3 4 5 7 9
1 3 4 6 8 7 9
1 3 4 6 9
Los casos de prueba deben explotar los caminos anteriores.

1.2- Prueba de condiciones.

La prueba de condiciones es un método de diseño de casos de prueba que ejercita las condiciones lógicas contenidas en el módulo de un programa. Se basa en el criterio de que si un conjunto de pruebas de un programa P es efectivo para detectar errores en las condiciones que se encuentran en P, es probable que el conjunto de pruebas sea también efctivo para detectar otros errores en el programa P.

Para una expresión relacional de la forma:
E1 E2
se requieren tres pruebas: el valor de E1 mayor, menor o igual que el de E2. La prueba que haga el valor de E1 mayor o menor que el de E2 debe hacer que la diferencia entre estos dos valores sea lo más pequeña posible.

Si la expresión es de la forma B1 & B2 donde B1 y B2 son variables lógicas, esta se cubre para B1 verdadero y B2 falso, B1 falso y B2 verdadero y ambos B1 y B2 verdadero.

Ver en el libro de Pressman págs. 642 a 643 ejemplos de expresiones complejas que incluyen expresiones lógicas y de comparación.

1.3- Prueba de bucles
Los bucles son la piedra angular de la mayoría de los algoritmos implementados en software. La prueba de bucles es una técnica de prueba de caja blanca que centra su punto de atención en la validez de las construcciones de bucles.

A) Bucles simples: Se les debe aplicar el siguiente conjunto de pruebas, donde n es el número máximo de pasos permitidos para el bucle:
1. Pasar por alto totalmente el bucle
2. Pasar una sola vez por el bucle
3. Pasar dos veces por el bucle
4. Hacer m pasos por el bucle con m < n
5. Hacer n-1, n y n+1 pasos por el bucle

B) Bucles anidados
1. Comenzar por el bucle más interior. Establecer los demás bucles en sus valores mínimos.
2. Llevar a cabo las pruebas de bucles simples para el bucle más interior, mientras se mantienen los parámetros de iteración (p. Ej. Contadores de bucles) de los bucles externos en sus valores mínimos. Añadir otras pruebas para valores fuera de rango o excluídos.
3. Progresar hacia fuera, llevando a cabos pruebas para el siguiente bucle, pero manteniendo todos los bucles externos en sus valores mínimos y los demás bucles anidados en sus valores "típicos".
4. Continuar hasta que se hayan probado todos los bucles.

C) Bucles concatenados: Se pueden probar mediante el enfoque anteriormente definido para los bucles simples, mientras cada uno de los bucles sea independiente del resto (si el contador del bucle 1 se usa como valor inicial del bucle 2 entonces los bucles no son independientes)

D) Bucles no estructurados: Esta clase de bucles se deben rediseñar para que se ajusten a las construcciones de la programación estructurada.

2.- Pruebas de caja negra

2.1- Partición Equivalente
La partición equivalente es un método de prueba de caja negra que divide el campo de entrada de un programa en clases de datos de los que se pueden derivar casos de prueba.. Un caso de prueba ideal descubre de forma inmediata una clase de errores, que de otro modo requerirían la ejecución de muchos casos antes de detectar el error genérico.

La partición equivalente se dirige a la definición de casos de prueba que descubran clases de errores, reduciendo así el número de casos de pruebaque hay que desarrollar.

El diseño de casos de preba para la partición equivalente se basa en una evaluación de las clases de equivalencia para una condición de entrada. Una clase de equivalencia representa un conjunto de estados válidos o inválidos para condiciones de de entrada.

1. Si una condición de entrada especifica un rango, se define una clase de equivalencia válida y dos inválidas
2. Si una condición de entrada requiere un valor específico, se define una clase de equivalencia válida y dos inválidas.
3. Si una condición de entrada especifica un miembro de un conjunto, se define una clase de equivalencia válida y una inválida.
4. Si una condición de entrada es lógica, se define una clase válida y una inválida.

Como ejemplo, consideremos los datos contenidos en una aplicación de automatización bancaria. Este software acepta datos en la siguiente forma:
Código de área: En blanco ó un número de 3 dígitos
Prefijo: Número de 3 dígitos que no comience por 0 ó 1
Sufijo: Número de 4 dígitos
Contraseña: Vvalor alfanumérico de 6 dígitos
Ordenes: "Comprobar", "Depositar","Pagar factura", etc.

Las condiciones de entrada relacionadas con cada elemento de la aplicación bancaria se pueden especificar como:
Código de área: Condición de entrada lógica - el código de área puede estar o no presente
Condición de entrada rango - valores definidos entre 200 y 999
Prefijo: Condición de entrada rango - valor especificado > 200
Sufijo: Condición de entrada valor- longitud de 4 dígitos
Contraseña: Condición de entrada lógica - la palabra clave puede estar o no presente
Condición de entrada valor - cadena de seis caracteres
Orden: Condición de entrada conjunto, contenida en las órdenes listadas anteriormente.

Los casos de prueba se seleccionan de manera que se ejercite el mayor número de atributos de cada clase de equivalencia a la vez.
2.2 - Análisis de valores límite (AVL)
Esta técnica complementa a la de partición equivalente. En lugar de seleccionar cualquier elemento de una clase de equivalencia, el AVL lleva a la elección de casos de prueba "en los bordes" de la clase. En lugar de centrarse solamente en las condiciones de entrada, el AVL deriva casos de prueba también para el campo de salida.
1. Si una condición de entrada especifica un rango delimitado por los valores a y b, se deben diseñar casos de prueba para los valores a y b y para valores justo por debajo y justo por encima de a y b, respectivamente.

2. Si una condición de entrada especifica un número de valores, se deben desarrollar casos de prueba que ejerciten los valores máximo y mínimo. También se deben probar los valores justo por debajo del máximo y del mínimo.

3. Aplicar las directrices 1 y 2 a las condiciones de salida. Por ej. supongamos que se requiere una tabla como salida deun programa, entonces se deben diseñar casos de prueba que creen un informe de salida que produzca el máximo ( y el mínimo) número permitido de entradas en la tabla.
4. Si las estructuras de datos internas tienen límites preestablecidos ( p. Ej. Un arreglo de 100 entradas) hay que asegurarse de diseñar un caso de prueba que ejercite la estructura de datos en sus límites.

3.- Pruebas de integración.

La prueba de integración se realiza posteriormente a las pruebas de unidad y su foco de atención es el diseño y la construcción de la arquitectura del software. Después de la integración viene la validación y por último la prueba del sistema, ésta última consiste en probar el software junto con los otros elementos de la empresa o entidad, como la gente, departamentos, la base de datos, etc.

Las pruebas de integración pueden ser descendentes o ascendentes o en sandwich, pero estas tienen sentido con ese nombre en los sistemas hechos en lenguajes estructurados, en los que el diagrama de la estructura de módulos del sistema permite definir un tipo dado de integración. En los orientados a objeto, otra vez cobra importancia el concepto de caso de uso, pues éste guía a la prueba en cuanto a los requisitos que deben satisfacer un determinado número de clases de programación que tienen que interactuar entre sí gobernadas por alguna clase de control del caso de uso.

4.- Pruebas de validación

La validación se logra cuando el software funciona de acuerdo a las expectativas del cliente.

La validación seconsigue mediante una serie de pruebas de la caja negra que demuestran la conformidad con los requisitos. Si aparecen deficiencias, hay que negociar con el cliente un método para resolverlas.

La prueba alfa es conducida por un cliente en el lugar de desarrollo. Se usa el software de manera natural, con el encargado de desarrollo "mirando por encima del hombro" del usuario" y registrando errores y problemas de uso. Las pruebas alfa se llevan a cabo en un entrono controlado.

La prueba beta se lleva a cabo en uno o más lugares de clientes por los usuarios finales del software. A diferencia de la prueba alfa, el encargado de desarrollo, normalmente, no está presente. La prueba beta es una aplicación "en vivo" del software en un entrono que no puede ser controlado por el equipo de desarrollo. El cliente registra todos los problemas (reales o imaginarios) que encuentra y los informa a intervalos regulares. Como resultado, el equipo de desarrollo lleva a cabo modificaciones y así prepara una versión del producto para toda la base de clientes.

Fuentes:
http://www.angelfire.com/empire2/ivansanes/bywbox.htm
http://html.rincondelvago.com/metodos-de-prueba-caja-de-pandora.html
http://www.slideshare.net/LGasperin/estrategias-de-pruebas-de-software
http://200.69.103.48/comunidad/grupos/arquisoft/fileadmin/Estudiantes/Pruebas/HTML%20-%20Pruebas%20de%20software/node28.html

No hay comentarios:

Publicar un comentario