En este artículo, veremos los fundamentos de pruebas del software de estructura de control y pruebas de caja-negra. Durante las primeras etapas de la prueba, es el ingeniero del software quien realiza todas las pruebas, sin embargo conforme progresa el proceso de prueba, los especialistas se van incorporando, una vez generado el código fuente, el software debe ser probado para descubrir y corregir el máximo de errores posibles antes de sus entrega al cliente.
Abstract
In this article, we will look at the basics of software testing for control structure and black-box testing. During the first stages of the test, it is the software engineer who performs all the tests, however as the testing process progresses, specialists are incorporated, once the source code is generated, the software must be tested to discover and correct The maximum of possible errors before their delivery to the client.
Para garantizar la calidad en la ejecución de un software, es muy importante realizar las pruebas respectivas a fin de certificar la fiabilidad del mismo, esto debe darse tan pronto como se tenga codificado el artefacto de cogido, el programador lo pone a prueba; denominando a esta etapa pruebas unitarias cuya finalidad es descartar ideas proyectadas sobre la (corrección) del software que se acaba de producir en el que se pueda destacar algún conflicto que apareciera en cuanto se descubra un error o falla en el mismo.
Segùn Beizer.B., (1990), describe eficientemente esta situación cuando plantea: Existe un mito que dice que si fuéramos realmente buenos programando, no existiría ningún error que buscar. Si tan sólo fuéramos realmente capaces de concentrarnos, si todo el mundo empleara técnicas de codificación estructuradas, el diseño descendente, las tablas de decisión, si los programas se escribieran en un lenguaje apropiado, si tuviéramos siempre la solución más adecuada, entonces no habría errores.
Se destilan mitos sobre la programación en la que se cree que nosotros somos malos en lo que hacemos y si hay errores es porque nosotros los hemos cometido y por ello deberíamos sentirnos culpables. De este criterio se desprende la importancia de diseñar las pruebas a los software recién desarrollados como un reconocimiento a nuestros fallos, asumiéndose de esta manera una dosis de culpabilidad.
Si se creyera que esta fase es tediosa en realidad se vuelve así, pero son en sí un justo castigo a cualquier error que pudiéramos haber cometido en la realización de este programa, para satisfacción y garantía ante el cliente.
Un procedimiento de prueba determinada como se debe de ejecutar uno o varios casos de prueba. Por ejemplo.- en un procedimiento de prueba puede ser dar una instrucción para un individuo sobre cómo debe realizar un caso de prueba manualmente. El cómo llevar a cabo un caso de prueba puede ser especificado por un procedimiento de prueba, a veces es útil reutilizar un procedimiento de prueba para algunos casos de prueba, así mismo, el reutilizar varios procedimientos de prueba para varios casos de prueba.
Objetivos de las pruebas
Segùn Myers., (1997), afirma que las pruebas del software establecen varias normas que pueden servir acertadamente como objetivos de las pruebas: 1) la prueba es el proceso de ejecución de un programa con la intención de descubrir un error, 2) un buen caso de prueba es aquel que tiene una alta probabilidad de mostrar un error no descubierto hasta entonces, 3) una prueba tiene éxito si descubre un error no detectado hasta entonces.
Sin duda los objetivos anteriormente mencionados suponen un cambio dramático de punto de vista. Quitan la idea que, normalmente, tener que una prueba tiene éxito si no descubren errores.
Componentes de Prueba
Por otra parte los componentes automatizan los procedimientos de prueba o parte de ellos en su conjunto, estos pueden ser desarrollados utilizando diferentes lenguajes como por ejemplo el lenguaje de guiones o el de programación.
Asimismo estas se utilizan para probar la fiabilidad de los componentes del software desarrollado y los dispositivos en el modelo de implementación proporcionando entradas que permiten la prueba, el controlar y así mismo el monitorear la ejecución de los elementos a probar e informar de los resultados de las pruebas.
Plan de Prueba
Tiene como propósito el dejar de forma explícita al alcance los enfoques, recursos requeridos, calendario, responsable y manejo de riesgos de un proceso de prueba. Se constituye por un conjunto pruebas, que debe reunir ciertas características base, entre las que citamos:
Dejar en claro que tipo de propiedades se quieren probar, y a la vez cómo se mide el resultado,
Especificar en qué consiste la prueba, y
Definir cuál es el resultado que se espera.
Como consecuencia de estas mismas ideas, podemos agruparlas diciendo que todo caso de prueba debe constar de 3 bloques de información:
El propósito de la prueba
Los pasos de ejecución de la prueba
El resultado que se espera
Al detallar cada uno de estos puntos, tenemos que cuidar que estos queden perfectamente documentados. Cuyo propósito es que este plan de pruebas numere el enfoque, recursos, esquema de actividades de pruebas, elementos a probar, características, personal responsable y así mismo los riesgos que pueden ocurrir durante se codifica la prueba.
Defecto de las Pruebas
Las anomalías que se presentan en el sistema son solamente uno de los errores más frecuentes que puede sufrir en la etapa de pruebas, un síntoma de fallo de software o un problema descubierto en una revisión puede dar paso a localizar cualquier problema que los desarrolladores necesiten registrar, controlar y resolver como error.
Prueba de Caja Blanca
Por otra parte Jones, (1981) nos dice que si bien es cierto la prueba de caja blanca, también denominada muchas veces prueba de caja de cristal, este es un método de diseño de casos de prueba que usa la estructura de control del diseño procedimental para obtener los casos de prueba. Mediante los métodos de prueba de caja blanca, el ingeniero del software puede obtener casos de prueba que garanticen que se ejercita por lo menos una vez todos los caminos independientes de cada módulo.
Los errores lógicos y las suposiciones incorrectas son inversamente proporcionales a la probabilidad de que se ejecute un camino del programa. Los errores tienden a introducirse en nuestro trabajo cuando diseñamos e implementamos funciones, condiciones o controles que se encuentran fuera de lo normal.
A menudo creemos que un camino lógico tiene pocas posibilidades de ejecutarse; al contrario de ello esto se puede ejecutar de forma normal. El flujo lógico de un programa a veces no es nada intuitivo, lo que significa que nuestras suposiciones sobre el flujo de control y los datos nos pueden llevar a tener errores de diseño que sólo se descubren cuando comienza la prueba del camino. Descartando así la posibilidad que el diseñador del software crea en su intuición y se centre mas en lo fundamental del programa de acuerdo a lo solicitado por el cliente o el objetivo propuesto.
Los errores tipográficos son aleatorios, ya que cuando se traduce un programa a código fuente en un lenguaje de programación, es muy probable que se den algunos errores de escritura. Muchos de estos errores serán descubiertos por los mecanismos de comprobación de sintaxis, pero otros permanecerán sin detectar hasta que comience la prueba.
Pruebas de la Estructura de Control
En cuanto a esta prueba se presentaran algunas variantes de la prueba de estructura de control. Estas variantes amplían la cobertura de la prueba y así mismo mejoran la calidad de la prueba blanca.
Prueba de condición
Según Rodriguez.T., (2012) cabe recalcar que este es un método de diseño de casos de prueba que instruye cada una de las condiciones lógicas contenida en cada prueba. Una condición simple es una variable lógica o una expresión relacional, posiblemente precedida con un operador NOT. Este método de prueba de condiciones esta centrado en cada una de las condiciones del programa.
Ventajas
Estas pruebas de condición tienen por lo general dos ventajas:
a. La cobertura de la prueba de una condición es sencilla
b. La cobertura de la prueba de condiciones de un programa da una orientación para generar pruebas adicionales del programa.
Propósito de Condiciones
Tal es el caso que el propósito de las pruebas de condiciones es detectar, no solo los errores en las condiciones de un programa, sino también errores en dicho programa.
Asimismo, si una estrategia de prueba es efectiva para detectar errores en una condición, entonces es probable que dicha estrategia también sea efectiva para detectar errores en el programa.
Prueba de flujo de datos
El escoger rutas de prueba de acuerdo a la localización de las definiciones y utilización de las variables del programa, vuelve más complejo el proceso y hay más variables que considerar; Se vuelve mucho más tardado al analizar sus roles dentro del flujo de datos, identificar rutas, y diseñar casos de pruebas. Las sentencias de un programa están relacionadas entre sí de acuerdo con las definiciones de las variables.
El enfoque de prueba de flujo de datos es efectivo para la protección contra errores. Sin embargo, los problemas de medida de la cobertura de la prueba y de selección de caminos de prueba para la prueba de flujo de datos son más difíciles que los correspondientes problemas para la prueba de condiciones. (Frankl & Weiss., 1993, pág. 292)
Pruebas de Bucle
Como se puede inferir las pruebas de bucles se convierten en la piedra angular de la inmensa mayoría de los algoritmos implementados en el software. Sin embargo, les prestamos normalmente poca atención cuando llevamos a cabo las pruebas del mismo.
Esta prueba de caja blanca se centra exclusivamente en la validez de las construcciones de bucles, en estas pruebas de bucles se pueden definir cuatro clases diferentes de bucles: bucles simples, bucles concatenados, bucles anidados y bucles no estructurados.
Ilustración 1 Clases de bucles
Fuente: Bezier, B. (1990)
Bucles simples: a los bucles simples se les debe aplicar el siguiente conjunto de pruebas, donde n es el número máximo de pasos permitidos por 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, y 5) Hacer n – 1, n y n+l pasos por el bucle.
Bucles anidados: si extendiéramos el enfoque de prueba de los bucles simples a los bucles anidados, el número de posibles pruebas aumentaría geométricamente a medida que aumenta el nivel de anidamiento. Así mismo Bézier sugiere un enfoque que ayuda a reducir el número de pruebas:
1) Comenzar por el bucle más interior. Establecer o configurar los demás bucles con 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 de los bucles externos en sus valores mínimos.
3) Progresar hacia fuera, llevando a cabo 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.
Bucles concatenados: estos bucles se pueden probar mediante el enfoque anteriormente definido para los bucles simples, mientras cada uno de los bucles sea independiente del resto. Sin embargo, si hay dos bucles concatenados y se usa el controlador del bucle 1 como valor inicial del bucle 2, entonces los bucles no son independientes.
Bucles no estructurados: siempre que sea posible, esta clase de bucles se deben rediseñar para que se ajusten a las construcciones de programación estructurada
Pruebas de Caja Negra
Las pruebas de caja negra, también denominada prueba de compartimiento, permiten obtener un conjunto de condiciones de entrada que ejerciten completamente todos los requisitos funcionales de un programa. En ellas se ignora la estructura de control, concentrándose en los requisitos funcionales del sistema y ejercitándolos, también permiten derivar casos de pruebas que buscan encontrar los siguientes tipos de errores: a) funciones incorrectas o faltantes, b) errores de interfaz, c) errores de estructuras de datos o en acceso a BD externas, d) errores de compartimiento o desempeño, y e) errores de inicialización o termino
Ilustración 2 La prueba de Caja Negra se centra principalmente en los requisitos funcionales del software.
Fuente: PRESSMAN, ROGER S.
Para preparar cada uno de los casos de pruebas hacen falta un número de datos que ayuden a la ejecución de estos casos y que permitan que el sistema se ejecute en todas sus variantes, pueden ser datos válidos o inválidos para el programa según lo que se desea es hallar es un error o probar una funcionalidad. Para desarrollar la prueba de caja negra existen varias técnicas, entre ellas están:
1. Técnica de la Partición de Equivalencia: esta técnica divide el campo de entrada en clases de datos que tienden a ejercitar determinadas funciones del software.
2. Técnica del Análisis de Valores Límites: esta Técnica prueba la habilidad del programa para manejar datos que se encuentran en los límites aceptables, y;
3. Técnica de Grafos de Causa-Efecto: es una técnica que permite al encargado de la prueba validar complejos conjuntos de acciones y condiciones.
Dentro del método de Caja Negra la técnica de la Partición de Equivalencia es una de las más efectivas pues permite examinar los valores válidos e inválidos de las entradas existentes en el software, 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 pruebas que descubran clases de errores, reduciendo así en número de clases de prueba que hay que desarrollar.
A partir de un caso de uso se pueden realizar pruebas de caja negra, obteniéndose varios casos de prueba que permiten:
a) Verificar el resultado de la interacción entre los actores y el sistema.
b) Comprobar que se satisfagan las precondiciones y poscondiciones del caso de uso, y;
c) Evidenciar que se siga una secuencia de acciones especificado por el caso de uso.
Partición Equivalente
Esta es una técnica de prueba de Caja-Negra que divide el dominio de entrada de un programa en clases de datos de los que se pueden derivar casos de prueba. El diseño de estos casos de prueba se basa en la evaluación de las clases de equivalencia para una condición de entrada, así mismo, una condición de entrada es un valor numérico, un rango de valores, un conjunto de valores relacionados o una condición lógica. Las clases de equivalencia se pueden definir con las siguientes directrices.-
Si un parámetro de entrada debe estar comprendido en un determinado rango, aparecen 3 clases de equivalencia, por debajo, en y por encima del rango.
Si una entrada requiere un valor concreto, aparecen 3 clases de equivalencia: por debajo, en y por encima del rango.
Si una entrada requiere un valor de entre los de un conjunto, aparecen 2 clases de equivalencia: en el conjunto o fuera de él.
Si una entrada es booleana, hay 2 clases: si o no.
Así mismos los criterios se aplican a las salidas esperadas: hay que intentar generar resultados en todas y cada una de las clases. No obstante aplicando estas directrices se ejecutan casos de pruebas para casa uno de los elementos de datos del campo de entrada a desarrollar. Estos se seleccionan de forma que ejerciten el mayor número de atributos de cada clase de equivalencia a la vez. Para aplicar esta técnica de prueba se deben tener en cuenta los siguientes pasos.-
Primero identificar cada una de las clases de equivalencia lo cual se lo hace tomando cada una de las condiciones de entrada y aplicándole las directrices anteriormente expuestas.
Luego de obtener las clases validas e inválidas definidas, se definen los casos de pruebas, pero para ello antes se debe haber asignado un identificador único a cada clase de equivalencia.
Por lo siguiente se definen los caso teniendo él cuenta lo siguiente: 1) escribir un nuevo caso que cubra tantas clases de equivalencia validas no cubiertas como sea posible hasta que casa una de las clases de equivalencia hayan sidas cubiertas por casos de pruebas, 2) escribir un nuevo caso de prueba que cubra una sola clase de equivalencia invalida hasta que todas las clases de equivalencia hayan sido cubiertas por casos de pruebas.
Clases de Equivalencia de Entrada
EC1. La variable de ENTRADA x es real y valida
EC2. La variable de entrada x no es real y valida
EC3. El valor de x >0.0 y es valido
EC4. El valor de x <0.0 y es valido
De acuerdo con la aplicación de esta técnica se obtiene un conjunto de pruebas que reduce el número de casos de pruebas y a la vez verificar la presencia o ausencia de errores que existen en una prueba.
Ventajas de las pruebas de Caja-Negra
Elimina la necesidad de las pruebas exhaustivas.
Es una guía para seleccionar el conjunto de datos de entrada para las pruebas, con alta probabilidad de detectar defectos.
Permite realizar una cobertura de un dominio de entradas grande con un subconjunto pequeño tomado de clase de equivalencia.
Técnica de Prueba Unitaria de Caja-Negra
Según Schach., (2006) menciona que las pruebas exhaustivas de caja-negra requieren por lo general miles y miles de millones de casos de pruebas, el arte de examinar es identificar un conjunto pequeño y manejable de casos de prueba que maximice las oportunidades de detectar un error mientras minimice las oportunidades de perder un caso de prueba habiendo detectado el mismo error en uno o más de las pruebas, una de las pruebas de equivalencia combinadas con el análisis de valor frontera.
Pruebas Funcionales
Según Howden., (1987) una de las maneras de las pruebas de caja negras es basar los datos de pruebas funcionales de un artefacto de código, estas identifican cada elemento de funcionalidad o cada función implementada en el artefacto de código, una vez identificadas todas las funciones del artefacto de código, se planean los datos de prueba para probar cada función de forma separada, después se llevan las pruebas funcionales un paso adelante.
Conclusión.-
Se concluye que las pruebas deberían de planificarse mucho antes de que se empiecen, por lo tanto se pueden definir múltiples casos de prueba para cada uno de los caso en dependencia de las condiciones de prueba que se tengan en cuenta antes de generar un cogido. Estas a medidas de que avanzan, desplazan su punto de mira en un intento de encontrar errores o fallas dentro del código.
El principal objetivo del diseño de casos de prueba es obtener un conjunto de pruebas que tengan mayor probabilidad de descubrir los defectos del software. Por otra parte, los desarrolladores de software experimentados dicen que la prueba nunca termina, simplemente se transfiere al cliente: Cada vez que el cliente usa el programa, lleva a cabo una prueba.
Beizer.B. (1990). Software Testing Techniques,2. #ed. Retrieved from http://zeus.inf.ucv.cl/~bcrawford/AULA_ICI444/17-Cap%EDtulo.pdf
Frankl, P., & Weiss., E. (1993, Octubre 10). Tecnicas de Pruebas de Software.
Howden. (1987). Prueba de Caja Negra. Ingenieria del Software.
Jones, T. (1981). Programming Productivity:. Retrieved from Computer Society Press,.
Myers., G. (1997). The Art of Software Testing Wiley. Pruebas del Sottware. Retrieved from http://zeus.inf.ucv.cl/~bcrawford/AULA_ICI444/17-Cap%EDtulo.pdf
Rodriguez.T., D. E. (2012, OCTUBRE 24). Pruebas de Software. Retrieved from http://www.tamps.cinvestav.mx/~ertello/swe/sesion15.pdf
Schach, S. R. (2006). Ingenieria del Software Clasica y Orientación a Objetos. Mexico: McGraw-Hill.
Autor:
Adrián Genaro Castro Sancan.
Estudiante del Sexto Semestre de la Carrera de Ingeniería en Computación y Redes. Ecuador.