martes, 18 de septiembre de 2012

Testing de aplicaciones - Técnicas de prueba


Una estrategia de prueba del software integra los métodos de diseño de casos de pruebas en una serie de pasos bien planeada que desembocará en la eficaz construcción de la aplicación.

Cualquier estrategia de prueba debe incorporar la planeación de pruebas, el diseño de casos de pruebas, la ejecución de pruebas y la recolección y evaluación de los datos resultantes.

La prueba es un conjunto de actividades que se planean con anticipación y se realizan de manera sistemática. Por lo tanto, se debe definir un conjunto de pasos en que se puedan incluir técnicas y métodos específicos del diseño de casos de prueba.

Podríamos  decir  que  la  prueba  es  un  intento  sistemático  de  “romper”  un  programa  que pensamos que está funcionando bien.

El concepto de prueba incremental se aplica a cómo probamos características del programa.   La   prueba   debería   enfocarse   primero   a   las   partes   más   simples   y   más frecuentemente utilizadas. Solo una vez que estas funcionen correctamente, deberíamos pasar a probar otros componentes.

Algunas consideraciones

  • Probar mientras se escribe el código:  cuanto más temprano se encuentra un problema es mejor. 
  • Programar “a la defensiva”:  una técnica útil es agregar código para manejar las situaciones “que no pueden ocurrir”. 
  • Probar el código en sus límites
  • Verificar  los  errores  retornados:  se  deben  controlar  los  códigos  de  error  devueltos  por llamadas  a  funciones,  operaciones  de  entrada/salida,  etc.  

Características de las pruebas

  • Las pruebas solo pueden mostrar la presencia de defectos, no su ausencia    
  • Las pruebas serán exitosas si detectan errores  
  • Las pruebas siempre deben realizarse contra un resultado esperado y los resultados obtenidos se deben revisar minuciosamente     
  • La prueba finalizará cuando el proceso establece confianza en que el componente o sistema hace lo que se supone tiene que hacer, ya que nunca se podrá demostrar que un componente o sistema no tiene defectos.

Tipos y estrategias de prueba 

Fase
Tarea
Tipo de Preba
Estrategia de Prueba
Ejecutor
Diseño y desarrollo Prueba Unitaria Unitaria Caja negra
Caja Blanca
Desarrollador
Diseño y desarrollo Prueba periodica Funcional
Regrecion
Recupero
Seguridad
Normalmente caja negra Tester
Diseño y desarrollo Prueba de integracion Funcional
Stress
Volumen
Performance
Regrecion
Recupero
Seguridad
Interfaces con otros sistemas
Conversion de datos
Caja Negra Tester
Aceptcion Prueba de Aceptacion Aceptacion del usuario
Ambiente e instalacion
Stress
Volumen
Performance
Recupero
Seguridad
Interfaces con otros sistemas
Caja Negra Usurarios
Operaciones
Auditoria
Seguridad

Estrategia de caja negra 

Las pruebas de caja negra se desentienden completamente del comportamiento y estructura interna  del  programa.  También  son  llamadas  pruebas  conducidas  por  los  datos  o  pruebas conducidas por las entradas/salidas. 
Las condiciones y casos de prueba tendrán variaciones considerando, según corresponda: 

  • Partición de equivalencias: debido a que nunca se podrán probar todos los valores posibles de un atributo o campo, se seleccionan conjuntos de valores típicos, tales que cubran  un  extenso  abanico  de  casos  de  prueba.  Estas  pruebas  son  llamadas  por "partición  de  equivalencias”  o  “subdominios”.  La  prueba  se  realiza  tomando,  por ejemplo, un valor válido y dos inválidos del mismo tipo que la clase válida para cada subconjunto. 
  • Condiciones de borde: se ingresan valores para los casos extremos, y casos inválidos para los valores siguientes a los extremos. 
  • Otros tipos de datos: se prueban ingresos de otros tipos de datos (números en lugar de caracteres  alfabéticos,  fechas  en  lugar  de  números,  etc.).  Muchas  veces  dichas validaciones son resueltas por la herramienta utilizada para el desarrollo. 
  • Condiciones cruzadas: por ejemplo, no se pueden cargar los datos del cónyuge si la persona no está casada. La estructura del modelo de datos define también estas reglas cruzadas que deben ser probadas. 
  • Conjetura de errores (sospechas): se crean casos de prueba con mayor cantidad de variaciones,   para   componentes   considerados   de   riesgo,   debido   a   complejidad, circunstancias del desarrollo, programas modificados por varias personas, programa armado pegando pedazos de otros, etc. 
  • Transición-estado, o causa-efecto: se crean casos de prueba que ejerciten todas las combinaciones  de  acciones  /  cambios  de  estado  causados,  para  los  diagramas  de transición-estado que correspondan a los ciclos de vida de las entidades de interés. 

Estrategia de caja blanca


Se  definen  a  partir  del  conocimiento  de  la  estructura  interna  del programa. También son llamadas pruebas estructurales.  Para analizar la estructura del componente a probar, se representa el flujo de control del mismo a través de un diagrama de flujo. Se determina el conjunto básico de caminos independientes,  y se preparan los casos de pruebas  que forzarán la  ejecución de cada camino.

Debería usarse esta estrategia para componentes críticos y/o sospechosos. Las condiciones y casos de prueba tendrán variaciones considerando:

  • Cobertura de sentencias: cada línea de código debe ser ejecutada al menos una vez. 
  • Cobertura  de  decisión:  para  cada  decisión  debe  proveerse,  al  menos,  un  resultado verdadero y uno falso. 
  • Cobertura de condición: para cada condición en una decisión deben proveerse valores que ejerciten todos los casos posibles, al menos una vez. 
  • Cobertura de decisión / condición: combinación de las anteriores, todos los caminos posibles e independientes, según salidas de condiciones y decisiones, eliminando los casos redundantes o no posibles. 


Prueba Unitaria 

Se  realiza  sobre  una  unidad  de  código  claramente  definida,  es  llevada  a  cabo  por  los desarrolladores. Requiere un trabajo complejo y laborioso.   

Prueba Funcional 

Prueba que verifica los requerimientos funcionales del sistema. Comprueba que las partes de un  sistema  que  funcionan  bien  aisladamente  en  la  prueba  unitaria,  también  lo  hacen  en conjunto. 

Prueba de Stress 

Prueba   excediendo   los   límites   de   su   capacidad   de   procesamiento   y   de almacenamiento. Se utiliza cuando hay poco control sobre los usuarios u otros sistemas que interactúan con el nuestro.
Las entradas de datos generados automáticamente exigen a un programa de modo diferente que los datos ingresados por un usuario. 

Pruebas de Volumen y Performance 

Verifican que el sistema soporte los volúmenes máximos definidos en la cuantificación  de  requerimientos  para  la  capacidad  de  procesamiento  y  la  capacidad  de almacenamiento. 

Pruebas de Regresión  

Pruebas  orientadas  a  verificar  que,  luego  de  introducido  un  cambio  en  el  código,  la 
funcionalidad original no ha sido alterada. 

Prueba de Recupero 

Pruebas orientadas a verificar que el sistema se recupera correctamente ante situaciones que 
afectan o suspenden su ejecución (estos casos fueron tratados en la clase anterior). 

Automatización de las pruebas (test automation) 

Probar manualmente un programa es muy tedioso y a veces poco redituable. Un testing apropiado involucra cantidad de pruebas, cantidades de lotes de datos de entrada y muchas comparaciones de resultados. 

La forma más básica de automatización de las pruebas son los tests de regresión.  

Los mismos ejecutan una secuencia de pruebas que comparan la nueva versión de un programa  con  la  anterior.  La  intención  es  comprobar  que  el  comportamiento  no  ha cambiado excepto en las formas esperadas.