MENU DESPLEGABLE

Pruebas de software


Definición

Las siguientes definiciones son algunas de las recogidas en el diccionario IEEE en relación a las pruebas [IEEE, 1990], que complementamos con otras más informales:
Pruebas: "una actividad en la cual un sistema o uno de sus componentes se ejecuta 2 en circunstancias previamente especificadas, los resultados se observan y registran y se realiza una evaluación de algún aspecto". Para Myers [MYERS, 1979], probar (o la prueba) es el "proceso de ejecutar un programa con el fin de encontrar errores".

El nombre "prueba", además de la actividad de probar, se puede utilizar para designar "un conjunto de casos y procedimientos de prueba" [IEEE, 1990].

Caso de prueba : "un conjunto de entradas, condiciones de ejecución y resultados esperados desarrollados para un objetivo particular como, por ejemplo, ejercitar un camino concreto de un programa o verificar el cumplimiento de un determinado requisito". "También se puede referir a la documentación en la que se describen las entradas, condiciones y salidas de un caso de prueba".

Defecto: "un defecto en el software como, por ejemplo, un proceso, una definición de datos o un paso de procesamiento incorrectos en un programa".

Fallo: "La incapacidad de un sistema o de alguno de sus componentes para realizar las funciones requeridas dentro de los requisitos de rendimiento especificados".

Conceptos fundamentales

Verificación:

  • Consiste en responder a la pregunta: ¿Estamos construyendo el producto correctamente? Dada la especificación que hemos tomado del usuario ¿estamos construyendo bien el código? 
  • ¿El resultado final del desarrollo software concuerda con la especificación (requisitos) del sistema? Hay que intentar asegurar que el desarrollo final coincide con dicha especificación

Validación:

  • ¿Estamos construyendo el producto correcto?
  • ¿El resultado final del desarrollo software se ajusta a lo que el usuario quería (sus necesidades)? En la mayoría de las ocasiones el producto desarrollado no casa con la ideas del cliente, normalmente porque a éste suele faltarle capacidad técnica de expresión.

¿Cómo llevar a cabo la verificación y validación? Métodos

  •  Pruebas del software (Dinámico): consisten en ejecutar comprobando que distintos valores de entrada producen los resultados deseados.
  • Métodos de inspección del software (Estático): se basan en la revisión de la documentación, requisitos, incluso código sin ejecutar nada. Esta tarea puede realizarse por un grupo de expertos por ejemplo.
    • Hay un tipo concreto de métodos estáticos llamados métodos formales. Éstos se basan en realizar una especificación llevada al extremo transformando el software a lenguaje matemático, donde no quedan ambigüedades y el código queda bien especificado.
    • Otra forma de inspección del software es comprobando el código mediante heurísticas con algún programa que la aplica (P. ej.- Findbugs).

Tipos de prueba (categorización)




  • En función de qué conocemos:
    • Pruebas de caja negra: no conocemos la implementación del código, sólo la interfaz. Tan sólo podemos probar dando distintos valores a las entradas y salidas.


    • Pruebas de caja blanca: conocemos el código (la implementación de éste) que se va a ejecutar y podemos definir las pruebas que cubran todos los posibles caminos del código.


  • Según el grado de automatización:
    • Pruebas manuales: son las que se hacen normalmente al programar o las que ejecuta una persona con la documentación generada durante la codificación (P. ej.- comprobar cómo se visualiza el contenido de una página web en dos navegadores diferentes).
    • Pruebas automáticas: se usa un determinado software para sistematizar las pruebas y obtener los resultados de las mismas (P. ej.- verificar un método de ordenación).

  • En función de qué se prueba:
    • Pruebas unitarias: se aplican a un componente del software. Podemos considerar como componente (elemento indivisible) a una función, una clase, una librería, etc. En nuestro caso, generalmente hablaremos de una clase como componente de software.
    • Pruebas de integración: consiste en construir el sistema a partir de los distintos componentes y probarlo con todos integrados. Estas pruebas deben realizarse progresivamente.
    • Pruebas funcionales: sobre el sistema funcionando se comprueba que cumple con la especificación (normalmente a través de los casos de uso).
    • Pruebas de rendimiento: los tres primeros tipos de pruebas de los que ya se ha hablado comprueban la eficacia del sistema. Las pruebas de rendimiento se basan en comprobar que el sistema puede soportar el volumen de carga definido en la especificación, es decir, hay que comprobar la eficiencia (P. ej.- Se ha montado una página web sobre un servidor y hay que probar qué capacidad tiene estado de aceptar peticiones).
    • Pruebas de aceptación: son las únicas pruebas que son realizadas por los usuarios, todas las anteriores las lleva a cabo el equipo de desarrollo. Podemos distinguir entre dos pruebas:
      • Pruebas alfa: las realiza el usuario en presencia de personal de desarrollo del proyecto haciendo uso de una máquina preparada para tal fin.
      • Pruebas beta: las realiza el usuario después de que el equipo de desarrollo les entregue una versión casi definitiva del producto.

Otros conceptos relacionados con las pruebas de software

  • Completitud: nos da una idea del grado de fiabilidad de las pruebas y por consiguiente la fiabilidad del software. No es posible llegar al 100% puesto que nunca llegaremos a realizar todas las pruebas posibles al software, puesto que las pruebas tienen un coste (P. ej.- Bug del Excel).

  • Depuración: ejecución controlada del software que nos permite corregir un error (P. ej.- Usar el debugger de nuestra máquina).

  • Pruebas de regresión: consiste en volver a aplicar pruebas que se habían superado anteriormente (P. ej.- Pruebas de integración).

Pruebas unitarias automatizadas

¿Por qué pruebas unitarias?

  • Más exhaustivas: implica hacer pruebas por clase, función, etc., es decir, por la unidad mínima que se haya considerado.
  • Probar trozos de código sin esperar al resto.
  • Nos da más confianza para modificar código: se pierde el miedo a hacer modificaciones y volver inconsistente el sistema.
  • Mejora la API: podemos darnos cuenta de fallos en la interfaz de la clase en pasos prematuros, evitando así el coste que supone una modificación en fases más avanzadas.
  • Sirve como documentación de ejemplos de uso de la clase.
  • Engancha cuando ves que tu código pasa todas las pruebas.

¿Qué probamos?

  • Según el tipo de componente:
    • Funciones individuales o métodos de objeto: probar las entradas y las salidas y comprobar que los valores obtenidos son los esperados.
    • Clases de objetos:
      • Hacer pruebas aisladas de operaciones
      • Probar también las secuencias de las operaciones.
    • Componentes
      • Se tratan igual que una clase de objeto
      • Hay que tener en cuenta si son distribuidos, en este caso es recomendable pasarle al componente pruebas de estrés.
    • ¡No olvidar probar también el manejo de errores!

  • Según en qué aspecto nos centramos:
    • Pruebas unitarias de código aislado:
      • Independientes del resto del sistema.
      • En la práctica esto no es posible en la mayoría de ocasiones, puesto que las clases interactúan entre sí. Para esto lo que se hace es sustituir los componentes por otros "de mentira" (mocks), para evitar así las dependencias.
    • Pruebas unitarias de integración: se prueba cada componente, pero dentro del todo de la aplicación, no como elemento aislado

¿Cómo hacemos las pruebas unitarias?

  • Pruebas estructurales: son Pruebas de caja blanca (no nos centraremos en estas).

  • Pruebas de particiones: son pruebas de caja negra. Consisten en dividir las posibles entradas y salidas en conjuntos de características similares. Se identificarán los casos especiales y por ejemplo, los límites serán sometidos a pruebas siempre. Consejos a tener en cuenta a la hora de probar valores:
    • Probar siempre los límites.
    • Cuando tenemos listas, vectores, tablas:
      • Probar pistas de un solo valor y listas vacías.
      • Probar siempre distintos tamaños.
      • Comprobar primer elemento, el elemento central y el último elemento.
    • Pasar null en vez del objeto.

¿Dónde ejecutamos las pruebas unitarias?

    En java podemos usar JUnit para las pruebas unitarias y JMeter para pruebas de rendimiento. Para otros lenguajes existen herramientas similares.

¿Cuándo implementamos las pruebas unitarias?

  • De forma paralela a la codificación (clase - prueba).
  • Antes de la codificación siguiendo un desarrollo guiado por pruebas (punto siguiente).

Desarrollo guiado por pruebas (TDD - Test-Driven Development)

Se basa en la filosofía de únicamente escribir nuevo código cuando una prueba unitaria falle o para eliminar código duplicado. (Por ejemplo: Probar la interfaz de login antes de codificar las clases que interactúan con la BD).

(Se toman los módulos más importantes que compondrán el software, se programan y se integran. Se prueba que funcionen correctamente y entonces se cogen otros módulos y se comienza de nuevo el proceso).

Desarrollo habitual:

Test-Driven Development:

Refactorizar: reorganizar, limpiar el código, etc. sin alterar la funcionalidad de éste.

Programación ágil: esta metodología de trabajo consiste en irse centrando en los requisitos del sistema por orden de importancia: llevar a cabo las pruebas y la codificación partiendo de los requisitos más exigidos por el cliente, presentándole éstos según se han ido implementando, y a partir de ahí ir integrando requisitos en orden descendente de relevancia.

Ventajas del TDD:

  • Comprensión.
  • Documentación.
  • Evitar sobreingeniería.

Conclusiones

  • Nunca un producto software se ha terminado de probar. Hay que establecer un límite dependiendo de la trascendencia, costes, etc. del proyecto.
  • La superación de las pruebas no implica que no existan errores, sino que no se han detectado.
  • Las pruebas del software no garantizan la calidad de éste: las pruebas demuestran la calidad pero no la garantizan.


No hay comentarios:

Publicar un comentario