jueves, 27 de noviembre de 2008

FASES DE PRUEBA

Una vez que los programas se han escrito, deben probarse. La fase de prueba puede ser muy tediosa y consumir parte del tiempo del desarrollo del programa. Los programadores son completamente responsables de probar sus programas. En los proyectos de desarrollo grandes, con frecuencia hay especialistas llamados ingenieros de pruebas quienes son responsables de probar el sistema como un todo, es decir, de hacer pruebas para comprobar que todos los programas trabajan en conjunto.
Hay dos tipos de pruebas: caja negra y caja blanca. La prueba de caja negra es realizada por el ingeniero de pruebas del sistema y por el usuario. Las pruebas de caja blanca son responsabilidad del programador.
TIPOS DE PRUEBAS
Pruebas de unidad: La prueba de unidad se centra en el módulo. Usando la descripción del diseño detallado como guía, se prueban los caminos de control importantes con el fin de descubrir errores dentro del ámbito del módulo. La prueba de unidad hace uso intensivo de las técnicas de prueba de caja blanca.
Prueba de integración: El objetivo es coger los módulos probados en la prueba de unidad y construir una estructura de programa que esté de acuerdo con lo que dicta el diseño.
Hay dos formas de integración:
  • Integración no incremental: Se combinan todos los módulos por anticipado y se prueba todo el programa en conjunto.
  • Integración incremental: El programa se construye y se prueba en pequeños segmentos.En la prueba de integración el foco de atención es el diseño y la construcción de la arquitectura del software.

Las técnicas que más prevalecen son las de diseño de casos de prueba de caja negra, aunque se pueden llevar a cabo unas pocas pruebas de caja blanca.

Prueba del sistema: Verifica que cada elemento encaja de forma adecuada y que se alcanza la funcionalidad y el rendimiento del sistema total. La prueba del sistema está constituida por una serie de pruebas diferentes cuyo propósito primordial es ejercitar profundamente el sistema basado en computadora.

Prueba de validación: Proporciona una seguridad final de que el software satisface todos los requerimientos funcionales y de rendimiento. Además, valida los requerimientos establecidos comparándolos con el sistema que ha sido construido. Durante la validación se usan exclusivamente técnicas de prueba de caja negra.

Prueba de recuperación: Fuerza un fallo del software y verifica que la recuperación se lleva a cabo apropiadamente.

Prueba de seguridad: Verificar los mecanismos de protección.

Prueba de resistencia: Enfrenta a los programas a situaciones anormales.

Prueba de rendimiento: Prueba el rendimiento del software en tiempo de ejecución.

Prueba de instalación: Se centra en asegurar que el sistema software desarrollado se puede instalar en diferentes configuraciones hardware y software y bajo condiciones excepciones, por ejemplo con espacio de disco insuficiente o continuas interrupciones.

Pruebas de regresión: Las pruebas de regresión son una estrategia de prueba en la cual las pruebas que se han ejecutado anteriormente se vuelven a realizar en la nueva versión modificada, para asegurar la calidad después de añadir la nueva funcionalidad.
El propósito de estas pruebas es asegurar que:

  • Los defectos identificados en la ejecución anterior de la prueba se ha corregido.
  • Los cambios realizados no han introducido nuevos defectos o reintroducido defectos anteriores.
  • La prueba de regresión puede implicar la re-ejecución de cualquier tipo de prueba. Normalmente, las pruebas de regresión se llevan a cabo durante cada iteración, ejecutando otra vez las pruebas de la iteración anterior.

Estrategias de pruebas del software:
Una estrategia de prueba del software integra las técnicas de diseño de casos de prueba en una serie de pasos bien planificados que llevan a la construcción correcta del software.
Las características generales son:

  • La prueba comienza en el nivel de módulo y trabaja “hacia afuera”.En diferentes puntos son adecuadas a la vez distintas técnicas de prueba.La prueba la realiza la persona que desarrolla el software y (para grandes proyectos) un grupo de pruebas independiente.
  • La prueba y la depuración son actividades diferentes.
  • Una estrategia de prueba para el software debe constar de pruebas de bajo nivel, así como de pruebas de alto nivel.

Más concretamente, los objetivos de la estrategia de prueba son:

  • Planificar las pruebas necesarias en cada iteración, incluyendo las pruebas de unidad, integración y las pruebas de sistema. Las pruebas de unidad y de integración son necesarias dentro de la iteración, mientras que las pruebas de sistema son necesarias sólo al final de la iteración.
  • Diseñar e implementar las pruebas creando los casos de prueba que especifican qué probar, cómo realizar las pruebas y creando, si es posible, componentes de prueba ejecutables para automatizar las pruebas.
  • Realizar diferentes pruebas y manejar los resultados de cada prueba sistemáticamente. Los productos de desarrollo de software en los que se detectan defectos son probadas de nuevo y posiblemente devueltas a otra etapa, como diseño o implementación, de forma que los defectos puedan ser arreglados.

Para conseguir estos objetivos el flujo de trabajo de la etapa de Pruebas consta de las siguientes etapas:

  • Planificación de las pruebas.
  • Diseño de las pruebas.
  • Implementación de las pruebas.
  • Ejecución de las pruebas.
  • Evaluación de las pruebas.

Los productos de desarrollo del software fundamentales que se desarrollan en la etapa de Pruebas son:

  • Plan de Pruebas.
  • Casos de Prueba.
  • Informe de evaluación de Pruebas.
  • Modelo de Pruebas, que incluye Clases de Prueba, Entorno de Configuración de Pruebas,
  • Componentes de Prueba y los Datos de prueba.

Los participantes responsables de las realizar las actividades y los productos de desarrollo del software son:

  • Diseñador de pruebas: Es responsable de la planificación, diseño, implementación y evaluación de las pruebas. Esto conlleva generar el plan de pruebas y modelo de pruebas, implementar los casos de prueba y evaluar los resultados de las pruebas. Los diseñadores de prueba realmente no llevan a cabo las pruebas, sino que se dedican a la preparación y evaluación de las mismas.
  • Probador (Tester): Es responsable de desarrollar las pruebas de unidad, integración y sistema, lo que incluye ejecutar las pruebas, evaluar su ejecución, recuperar los errores y garantizar los resultados de las pruebas.

Durante la fase de Inicio puede hacerse parte de la planificación inicial de las pruebas cuando se define el ámbito del sistema. Sin embargo, las pruebas se llevan a cabo sobre todo cuando un producto de desarrollo software es sometido a pruebas de integración y de sistema. Esto quiere decir que la realización de pruebas se centra en las fases de Elaboración, cuando se prueba la línea base ejecutable de la arquitectura, y de construcción, cuando el grueso del sistema está implementado. Durante la fase de Transición el centro se desplaza hacia la corrección de defectos durante los primeros usos y a las pruebas de regresión.Debido a la naturaleza iterativa del esfuerzo de desarrollo, algunos de los casos de prueba que especifican cómo probar los primeros productos de desarrollo software pueden ser utilizadas también como casos de prueba de regresión que especifican cómo llevar a cabo las pruebas de regresión sobre los productos de desarrollo software siguientes. El número de pruebas de regresión necesarias crece por tanto de forma estable a lo largo de las iteraciones, lo que significa que las últimas iteraciones requerirán un gran esfuerzo en pruebas de regresión.
Es natural, por tanto, mantener el modelo de pruebas a lo largo del ciclo de vida del software completo, aunque el modelo de pruebas cambia constantemente debido a:

  • La eliminación de casos de prueba obsoletos.
  • El refinamiento de algunos casos de prueba en casos de prueba de regresión.
  • La creación de nuevos casos de prueba para cada nuevo producto de desarrollo de software.

PRUEBAS DE CAJA BLANCA

Mientras que las pruebas de caja negra suponen que no se sabe nada acerca del programa, las pruebas de caja blanca asumen que usted sabe todo acerca del programa. En este caso, el programa es como una casa de vidrio en la cual todo es visible.
Las pruebas de caja blanca son responsabilidad del programado4, quien sabe exactamente que sucede dentro del programa. Usted debe asegurare de que todas las instrucciones posibles y todas las situaciones posibles se hayan probado. ! Y esta no es una tarea simple!
La experiencia ayudara al programador a diseñar un buen plan de pruebas, pero algo que puede hacer desde el principio es adquirir el habito de escribir planes de prueba. Comenzara su plan de pruebas cuando este en la etapa de diseño. A medida que construya su diagrama de estructura, se preguntara a si mismo que situaciones necesita probar, especialmente las inusuales, y las anotara de inmediato, pues puede suceder que no las recuerde una hora mas tarde.
Cuando el programador escribe sus diagramas de flujo o pseudocódigo, debe revisarlos poniendo atención a los casos de prueba y tomar nota de los casos que necesita.
Al llegar el momento de construir sus casos de prueba, debe revisar sus notas y organizarlas en conjuntos lógicos. Excepto por programas tipo estudiante muy simples, un conjunto de datos de prueba no validara completamente un programa. Para proyectos de desarrollo a gran escala, tal vez sea necesario ejecutar 20, 30 o más casos de prueba. De nuevo, los anotara e incorporará a su plan de pruebas. Después de que se ha terminado el programa y este esta en producción, el programador necesitara nuevamente los planes de prueba cuando modifique el programa.

La prueba de la caja blanca es un método de diseño de casos de prueba que usa la estructura de control del diseño procedimental para deribar los casos de prueba. Mediante los métodos de prueba de la caja blanca el ingeniero del software puede derivar casos de prueba que:

  • Garanticen que se ejercitan al menos una vez todos los caminos independientes de cada módulo
  • Se ejercitan todas las decisiones lógicas en sus caras verdaderas y falsas
  • Se ejecutan todos los bucles en sus límites y con sus límites operacionales
  • Se ejercitan las estructuras de datos internas para asegurar su validez.

En estas encrucijadas se puede exponer una pregunta razonable: ”¿Por qué gastar tiempo y energía probando y preocupándose de las minuciosidades lógicas cuando podríamos gastar mejor el esfuerzo asegurando que se han alcanzado los requerimientos del programa?”. La respuesta se encuentra en la naturaleza misma de los defectos del software.

  • 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 producirse en nuestro trabajo cuando diseñamos o implementamos funciones, condiciones o controles que se encuentran fuera de los normal. El procedimiento habitual tiende a hacer más comprensible, mientras que el procesamiento de “casos especiales” tiende a caer en el caos.

  • A menudo creemos que un camino lógico tiene pocas posibilidades de ejecutarse cuando, de hecho, se puede ejecutar de forma regular. El flujo lógico de un programa a veces no es nada intuitivo, lo que significa que nuestras suposiciones intuitivas sobre el flujo de control y los datos nos pueden llevar a tener errores de diseño que solo se descubren cuando comienza la prueba del camino.

  • Los errores tipográficos son aleatorios. Cuando se traduce un programa a código fuente de un lenguaje de programación, es muy probable que se den algunos errores de escritura. Muchos serán descubiertos por los mecanismos de comprobación de sintaxis, pero otros permanecerán indetectados hasta que comience la prueba. Es igual de probable que haya un error tipográfico en un oscuro camino lógico que en un camino principal.

Cada una de estas razones nos da un argumento para llevar a cabo las pruebas de caja blanca. La prueba de caja negra, sin tener en cuenta como sea de completa, puede pasarse los tipos de errores que acabamos de señalar. Como estableció Beizer: “Los errores se esconden en los rincones y se aglomeran en los límites”. Es mucho más fácil de descubrirlos con la prueba de caja blanca.

Pruebas del Camino Básico.
La prueba del camino básico es una técnica de prueba de la caja blanca propuesta inicialmente por Tom McCabe. El método del camino básico permite al diseñador de casos de prueba derivar una medida de complejidad lógica de un diseño procedural 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 del programa.

Notación de grafo de flujo
Antes de considerar el método del camino básico se debe introducir una sencilla notación para la representación del flujo de control, denominada grafo de flujo. El grafo de flujo representa el flujo de control lógico mediante la notación ilustrada en la figura 2.1. Cada construcción estructurada tiene un correspondiente símbolo en el grafo de flujo.


Para ilustrar el uso de un grafo de flujo, consideremos la representación del diseño procedural de la figura 2.2.


Fig 2.2


Aquí, se usa un diagrama de flujo para representar la estructura de control de un programa.
Cuando en un diseño procedural se encuentran condiciones compuestas, la generación del grafo de flujo se hace un poco mas complicada. Una condición compuesta se da cuando aparecen uno o mas operadores booleanos (OR, AND, NAND, NOR lógicos) en una sentencia condicional.

Prueba de Bucles
Los bucles son la piedra angular de la mayoría de los algoritmos implementados en software. Y por ello debemos prestarle normalmente un poco de atención cuando llevamos a cabo la prueba del software.
La prueba de bucles es una técnica de prueba de caja blanca que se centra exclusivamente en la validez de las construcciones de bucles. Se pueden definir cuatro clases diferentes de bucles: Bucles simples, Bucles concatenados, Bucles Anidados, y bucles no estructurado.
Además de un análisis del camino básico que aísle todos los caminos de un bucle, se recomienda un conjunto especial de pruebas adicionales para cada tipo de bucles. Estas pruebas buscan errores de inicialización, errores de indexación o de incremento y errores en los límites de los bucles.
Bucles Simples: A los bucles simples se les debe aplicar el siguiente conjunto de pruebas, donde n es el numero máximo de pasos permitidos por bucle.

  1. Saltar 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

Bucles Anidados: Si extendiéramos el enfoque de prueba de los bucles simples a los bucles anidados, el numero de posibles pruebas crecería geométricamente a medida que aumenta el nivel de anidamiento. Esto nos llevaría a un numero impracticable de pruebas. Beizer sugiere un enfoque que ayuda a reducir el número de pruebas:

  1. Comenzar en el bucle más interior. Disponer todos los demás bucles en sus valores mínimos.
  2. Llevar a cabo las pruebas de bucles simples con el bucle mas interno mientras se mantiene los bucles exteriores con los valores mínimos para sus parámetros de iteración. Añadir otras pruebas para los valores fuera de rango o para valores excluidos.
  3. Progresar hacia afuera, llevando a cabo las pruebas para el siguiente bicle, pero manteniendo todos los demás bucles exteriores en sus valores mínimos y los demás bucles anidados con valores “típicos”.
  4. Continuar hasta que se hayan probado todos los bucles.

Bucles Concatenados: los bucle concatenados se pueden probar mediante el enfoque anteriormente definido para los bucles simple, mientras que cada uno de los bucles sea independiente del resto. Por ejemplo, si hay dos bucles concatenados y se usa el contador del bucle 1 como valor inicial del bucle 2, entonces los bucles no son independientes. Cuando los bucles no son independientes, se recomienda usar el enfoque aplicado para los bucles anidados.

Bucles No Estructurados: Siempre que sea posible, esta clase de bucles se deben rediseñar para que se ajuste a las construcciones de la programación estructurada.