Validación y verificación de requisitos

  • Jordi Pradel Miquel

     Jordi Pradel Miquel

    Ingeniero de Informática por la Universidad Politécnica de Cataluña. Socio fundador e ingeniero de software en Agilogy, profesor en el Departamento de Ingeniería de Servicios y Sistemas de Información de la UPC, consultor de los Estudios de Informática y Multimedia en la Universitat Oberta de Catalunya y miembro del Grupo de Investigación de Ingeniería del Software para Sistemas de Información de la UPC, en el que ha publicado varios artículos de investigación en el campo de la ingeniería del software y de la aplicación a sistemas de información.

  • Jose Raya Martos

     Jose Raya Martos

    Ingeniero de Informática por la Universidad Politécnica de Cataluña. Compagina su actividad como ingeniero de software en Agilogy (empresa de la cual es socio fundador) con la de consultor en el Área de Ingeniería del Software en la UOC y la de profesor a tiempo parcial en el Departamento de Ingeniería de Servicios y Sistemas de Información de la UPC. A lo largo de los años ha trabajado en proyectos de sectores varios, como el financiero, la Administración pública o las telecomunicaciones, ejerciendo tareas técnicas y de gestión, lo que le ha dado una amplia perspectiva sobre el mundo del desarrollo de software y de su diversidad.

PID_00191252

Los textos e imágenes publicados en esta obra están sujetos –excepto que se indique lo contrario– a una licencia de Reconocimiento-Compartir igual (BY-SA) v.3.0 España de Creative Commons. Se puede modificar la obra, reproducirla, distribuirla o comunicarla públicamente siempre que se cite el autor y la fuente (FUOC. Fundació per a la Universitat Oberta de Catalunya), y siempre que la obra derivada quede sujeta a la misma licencia que el material original. La licencia completa se puede consultar en: https://creativecommons.org/licenses/by-sa/3.0/es/legalcode.ca

Introducción

La calidad de un producto de software empieza por la calidad de sus requisitos. Dado que los requisitos son la base para el resto del desarrollo, su calidad influirá de manera muy directa en la calidad del producto final.
La principal medida de la calidad de los requisitos es saber si el producto desarrollado satisface las expectativas de los clientes/usuarios para quienes lo desarrollamos. Para determinarlo, debemos dar respuesta a dos preguntas:
  • ¿Hemos seleccionado correctamente los requisitos?

  • ¿Hemos implementado correctamente los requisitos?

Denominamos validación de requisitos a comprobar la primera pregunta (comprobar que los requisitos son los que tienen que ser) y verificación de requisitos a comprobar la segunda (verificar que hemos implementado correctamente los requisitos).
La actividad de validación se puede llevar a cabo durante el desarrollo y suele tomar la forma de revisiones periódicas (por ejemplo, al principio de cada iteración) de los requisitos para que los diferentes stakeholders del proyecto validen que la selección de requisitos que hemos hecho es correcta. También aprovecharemos estas revisiones para detectar problemas en la especificación de requisitos (ambigüedades, inconsistencias, etc.).
La verificación, en cambio, requiere que el software ya esté desarrollado. En el caso del desarrollo incremental, también podemos llevarla a cabo durante el desarrollo (al final de cada incremento) y cumple un doble objetivo: verificar que la nueva funcionalidad está bien implementada y que la funcionalidad implementada anteriormente continúa comportándose de manera correcta.
En este módulo veremos algunas indicaciones sobre cómo llevar a cabo una validación de requisitos, así como los diferentes tipos de pruebas que podemos hacer para verificar los distintos tipos de requisitos y algunas herramientas para automatizar dichas pruebas.
Finalmente, veremos el proceso de desarrollo de software dirigido por las pruebas y, más concretamente, la variedad llamada BDD (del inglés behavior driven development, desarrollo dirigido por el comportamiento), que es un proceso de desarrollo incremental de software en el que las pruebas automatizadas guían todo el proceso de desarrollo.

Objetivos

Este módulo tiene dos objetivos principales: por un lado, que seáis capaces de validar la corrección y la calidad de un conjunto de requisitos. Por otro, que sepáis cómo se puede automatizar el proceso de verificación de requisitos (verificar que el software desarrollado cumple los requisitos). En concreto, deberéis ser capaces de:
  1. Saber cómo validar la corrección y la calidad de los requisitos.

  2. Saber elaborar un plan de pruebas para un proyecto, y

  3. Entender la técnica de especificación por ejemplos y el desarrollo guiado por las pruebas.

1.Validación de requisitos

La validación de requisitos es el proceso mediante el cual nos aseguramos de que los requisitos que hemos elegido para el producto que estamos desarrollando reflejan las expectativas de los stakeholders.
Durante la obtención y la selección de requisitos, los stakeholders comunican sus requisitos a los desarrolladores. Durante la validación de requisitos, lo que hacemos es que esta misma información viaje en dirección contraria (de los desarrolladores a los stakeholders), de modo que estos puedan validar que no se haya perdido información por el camino y que los requisitos comunicados se hayan entendido correctamente.
Si no lleváramos a cabo un proceso de validación de los requisitos, podríamos acabar construyendo un software que satisfaga a la perfección lo que se recogió como requisitos, lo que se entendió, pero que no satisfaga las necesidades reales de los stakeholders; es decir, que no satisfaga los requisitos reales, que no coincidirían con lo que se recogió, entendió y, quizás, documentó.
75593m5001.gif
La validación de requisitos nos permite asegurar que los desarrolladores han entendido correctamente los requisitos del producto de software que hay que desarrollar.
Además de detectar posibles errores en la comunicación, también debemos detectar errores en la obtención (requisitos no identificados o identificados de forma errónea) o en el proceso de selección (haber descartado requisitos candidatos que tendrían que estar en el producto o haber incluido requisitos que no tendrían que figurar).
La validación también sirve para asegurarnos de que hemos documentado correctamente los requisitos; es decir, que la especificación de requisitos que hemos hecho presenta todas las cualidades de una buena especificación y que la documentación se puede entender, es consistente, está completa y cumple los estándares adecuados.
Aun así, puesto que el problema que estamos tratando viene dado por la propia comunicación entre las personas, lo más habitual es que la validación de requisitos incluya un proceso manual de revisión en el que intervienen tanto los stakeholders como los desarrolladores.

1.1.Revisiones de requisitos

La forma más habitual de validar los requisitos es mediante las llamadas revisiones de requisitos.
Las revisiones de requisitos pueden presentar varios niveles de formalidad, desde revisiones informales, en las que, por ejemplo, se muestra un modelo de la interfaz a un usuario para que este dé su impresión, hasta procesos de revisión que involucren a todos los stakeholders del proyecto.
En una revisión de los requisitos, un grupo de personas lee y analiza la especificación buscando errores y problemas potenciales.
La composición del grupo de revisores resulta clave para la utilidad de la revisión. Cuanto más diverso sea el grupo de stakeholders que revisan la especificación, más amplia será la visión del dominio que tendrá el grupo y, por lo tanto, será más probable que se identifiquen los problemas.
Por ejemplo, si hacemos una revisión de requisitos donde no participa ningún experto del dominio, es muy probable que se nos pasen por alto los problemas relacionados con una mala comprensión del dominio.
Del mismo modo, si no contamos con ningún usuario final en el grupo de revisores, es muy probable que se nos pasen por alto los problemas relacionados con el día a día de la utilización del producto desarrollado.
Por otro lado, si intervienen muchas personas, hay que organizar muy bien el proceso de revisión para que resulte efectivo. En este caso, hay que seguir un proceso formal de revisión de requisitos.
En una revisión formal de requisitos, el proceso habitual que se sigue es el siguiente:
  • Se distribuye la especificación que debemos someter a revisión entre los distintos revisores con el fin de que lleven a cabo una revisión individual para identificar problemas potenciales.

  • Se recogen y se organizan las conclusiones de las revisiones individuales y se convoca una reunión de requisitos.

  • En la reunión de requisitos, los distintos revisores comentan los problemas que han identificado y se proponen las acciones que hay que llevar a cabo para mitigarlos.

Después de la reunión de requisitos, es preciso llevar a cabo todas las acciones acordadas, ya sean pequeños cambios en la documentación o cambios más importantes. En el supuesto de que tengamos establecido un proceso de gestión de cambios, es posible que estas acciones comporten la puesta en marcha de dicho proceso.
Las revisiones formales son mucho más costosas que las revisiones informales, pero, como contrapunto, suelen ser más completas e incluir más puntos de vista, por lo cual los dos tipos de revisión finalmente resultan complementarios.

1.2.Problemas habituales que hay que detectar

Los revisores deben comprobar que la especificación cumpla las cualidades de una buena especificación de requisitos: es decir, que sea correcta, inambigua, completa, consistente, ordenada, verificable, modificable y trazable.
Para comprobar que la especificación sea correcta (que todos los requisitos que figuran respondan a una necesidad real de un stakeholder), completa (que no deje sin cubrir ninguna necesidad de un stakeholder) y que esté bien ordenada, a los revisores les sirve de ayuda que la especificación indique con qué stakeholders se relaciona cada requisito.
Para comprobar que no sea ambigua (que contenga toda la información necesaria para entender los requisitos y que cada requisito tenga una única interpretación posible), los revisores deben detectar aquellos requisitos que consideran que hay que aclarar, así como aquellos para los cuales creen que falta información.
Por ejemplo, si decimos que, para vender un viaje, “El sistema de ventas de Viajes UOC tiene que cumplir las normativas vigentes”, estamos dando una información incompleta, ya que no estamos diciendo cuáles son las normativas que hay que cumplir.
De forma similar, si decimos que “El sistema de ventas de Viajes UOC tiene que permitir el pago de los viajes con los medios habituales”, hay que aclarar cuáles son tales medios de pago habituales.
Para comprobar que sea consistente (que no contenga ninguna contradicción), se debe comprobar si hay subconjuntos de requisitos que entran en conflicto entre sí.
En el caso de Viajes UOC, las agencias quieren tener un espacio propio dentro del sistema de ventas que les permita diferenciarse unas de otras, mientras que el departamento de marketing de Viajes UOC quiere unificar la imagen de marca de forma que el cliente final no necesite saber con qué agencia ha trabajado.
Por lo que respecta a la verificabilidad (asegurar que por cada requisito exista un proceso finito y de coste razonable para determinar si el software satisface o no el requisito) y realizabilidad (que todos los requisitos se puedan implementar), hay que tener en cuenta cómo se llevarán a cabo las pruebas para determinar si se cumplen o no los requisitos y qué son las limitaciones del proyecto de desarrollo.
Por ejemplo, en Viajes UOC podríamos tener un requisito que pidiera que el sistema se pueda usar por vía telefónica a través de una interfaz de voz en lenguaje natural y que la ratio de aciertos del sistema de reconocimiento del habla sea del 100%.
En este caso, es probable que no sea realista asumir que se puede llegar a un 100% de aciertos en el reconocimiento del habla y, por lo tanto, habrá que decidir si se rebaja esta expectativa o si se descarta la posibilidad de usar un sistema de reconocimiento del habla.
En cuanto a la modificabilidad de la especificación (que permita realizar cambios en la documentación con facilidad), esta tiene mucho que ver con la estructura y la redacción de la especificación: los revisores deberán comprobar que esté bien estructurada, que tenga una tabla de contenidos, índice, etc. También es interesante comprobar que contenga las redundancias mínimas necesarias, ya que estas dificultan la modificabilidad del documento al complicar a quien lo modifica mantener la coherencia.
Por lo que respecta a la trazabilidad (que cada requisito esté claramente identificado), es importante comprobar que las referencias cruzadas, tanto dentro de la propia especificación como hacia otros documentos, estén correctamente identificadas.

2.Verificación de requisitos

La verificación de los requisitos es el proceso mediante el cual comprobamos que el sistema desarrollado cumple sus requisitos.
75593m5002.gif
Esta verificación se lleva a cabo a través de diferentes pruebas del software, que son un conjunto de actividades en el que un sistema o componente es ejecutado bajo un conjunto de condiciones específicas, se registran los resultados y se hace una evaluación de alguno de los aspectos del sistema o componente, como por ejemplo su rendimiento, su usabilidad, su seguridad, etc.
En el contexto de la verificación de requisitos, las pruebas se utilizan para someter a examen el conjunto del sistema y verificar que satisface los requisitos y que está libre de errores.

2.1.Tipos de pruebas del software

El SWEBOK clasifica las pruebas del software en tres categorías, según el ámbito del sistema que hay que probar:
1) Pruebas unitarias: examinan un componente de manera aislada del resto de los componentes del sistema.
2) Pruebas de integración: examinan un subconjunto del sistema para verificar la interacción entre los componentes.
3) Pruebas de sistema: examinan todo el sistema (todos sus componentes a la vez).
Los tres tipos de pruebas son complementarios desde el punto de vista de los requisitos. Así, por ejemplo, podemos hacer pruebas unitarias que verifiquen parte de un requisito funcional o pruebas de sistema que verifiquen la funcionalidad completa o de requisitos no funcionales como, por ejemplo, los requisitos de rendimiento.
Otra clasificación que hace el SWEBOK es en función del objetivo de la prueba. En este caso, la clasificación es más extensa, pero en estos materiales nos centraremos solo en las pruebas directamente relacionadas con la verificación de requisitos:
  • Pruebas de aceptación: determinan si el comportamiento del sistema se adecua a los requisitos de los clientes (y, por lo tanto, si estos aceptarán o no el sistema desarrollado).

  • Pruebas de conformidad (también llamadas funcionales o de corrección): verifican que el software cumpla la especificación.

  • Pruebas de rendimiento: verifican que el sistema cumpla los requisitos de rendimiento como la capacidad, el volumen de los datos o los tiempos de respuesta.

  • Pruebas de estrés: ejercitan el sistema al límite de su capacidad (e incluso un poco más allá) para verificar su comportamiento en estas condiciones.

  • Pruebas de regresión: tras introducir modificaciones en el sistema, ejecutan de nuevo un conjunto de pruebas que el sistema ya superaba satisfactoriamente para verificar que las modificaciones no han causado efectos no deseados y que el sistema continúa superándolas.

La diferencia entre las pruebas de conformidad y las de aceptación es sutil: mientras que las pruebas de conformidad verifican los requisitos, las pruebas de aceptación también tienen en cuenta errores de validación. Puede pasar que el cliente, a pesar de que el producto desarrollado cumpla las especificaciones, decida no aceptarlo porque cree que le falta o le sobra alguna funcionalidad o bien porque no se cumple algún requisito no funcional.
Del mismo modo, las pruebas de rendimiento se diferencian de las pruebas de estrés en que, en el primer caso, la finalidad es verificar que el sistema se comporta de forma adecuada bajo las condiciones de carga esperadas, mientras que en el segundo caso se trata de ver cómo se comporta cuando se superan dichas condiciones. Sin embargo, los dos tipos de pruebas son similares, en el sentido de que en los dos se trata de simular un volumen de carga y observar el comportamiento del sistema.
Debemos tener en cuenta que esta categorización no es necesariamente excluyente: un mismo guión de pruebas nos puede servir como prueba de aceptación (si lo que queremos saber es si el cliente acepta el desarrollo o no), de conformidad (si nuestro objetivo es averiguar si el software cumple los requisitos) o de regresión (si queremos comprobar si el software todavía se comporta del mismo modo que en las versiones anteriores).
Por ejemplo, en Viajes UOC tenemos un requisito que dice que “Un cliente debe poder ver las opiniones sobre un hotel”. Podríamos tener un guión de pruebas que indicara qué tiene que hacer el cliente para ver tales opiniones y cómo se verifica que, efectivamente, se muestran dichas opiniones sobre el hotel.
La primera vez que escribimos el guión de pruebas, seguramente lo haremos como prueba de conformidad, a pesar de que, una vez superada la prueba de conformidad, pediremos al representante de los clientes que siga el guión de pruebas y nos indique si la funcionalidad implementada es correcta o no (prueba de aceptación). A partir de este momento, cada vez que alguien siga este guión para verificar que el sistema de ventas de Viajes UOC funciona correctamente, estará haciendo una prueba de regresión.

2.2.El Plan de pruebas

Todas estas pruebas se documentan en un artefacto llamado Plan de pruebas.
El Plan de pruebas documenta el alcance, enfoque, recursos necesarios, etc. de las diferentes pruebas del software.
El estándar IEEE-829 describe el contenido y la estructura recomendados para el plan de pruebas de un proyecto de desarrollo de software. Según este estándar, un plan de pruebas debe contener, entre otros elementos:
  • Identificador del Plan de pruebas.

  • Referencias a otros documentos, como por ejemplo la especificación de requisitos, la documentación de diseño del sistema o la documentación del método que se ha seguido para desarrollar el sistema.

  • Elementos de prueba, como cuál es el software, con las versiones exactas que probaremos, o qué subsistemas del software probaremos, y características que vamos a examinar (desde el punto de vista del usuario), asociadas a un nivel de riesgo.

  • Riesgos identificados en el software, como cuáles son las áreas en las que es más probable que tengamos problemas y, por lo tanto, que debemos examinar de forma más exhaustiva.

  • Características que no se probarán, indicando el motivo por el que no se hará dicha comprobación (bajo riesgo, no forman parte de la entrega actual, etc.).

  • Estrategia de pruebas:

    • ¿Qué herramientas se utilizarán?

    • ¿Qué métricas se recogerán? ¿En qué nivel se recogerá cada métrica?

    • ¿Cómo se gestionará la configuración? ¿Cuántas configuraciones diferentes se gestionarán?

    • ¿Qué software y hardware se utilizarán?

    • ¿Se harán pruebas de regresión? ¿Hasta qué punto?

  • Criterios de aceptación de la prueba (para cada prueba): ¿cómo se decidirá que la prueba se ha completado con éxito?

  • Criterios de cancelación de la prueba (para cada prueba): ¿cómo se decidirá si hay que suspender o cancelar una prueba?

  • Entregables: ¿qué se entregará como resultado de la ejecución de la prueba? (el documento del plan de pruebas, los casos de prueba, los logs de error, el informe de problemas, etc.).

  • Responsables de las pruebas y aprobaciones: ¿quién es el responsable de la ejecución de las pruebas? ¿Quién está autorizado a dar el proceso por finalizado y a aceptar el resultado de las pruebas?

  • Calendario.

2.3.Automatización de pruebas

La ejecución de las pruebas de software es un proceso repetitivo (sobre todo en el caso de las pruebas de regresión) y, en muchas ocasiones, monótono. Por eso, es muy fácil que la persona encargada de la prueba cometa errores durante la ejecución del guión de pruebas o durante la verificación de los resultados.
En cambio, los programas informáticos son muy útiles para ejecutar tareas repetitivas una y otra vez, ya que garantizan que seguirán exactamente las mismas instrucciones en el mismo orden todas y cada una de las veces. Por este motivo, la automatización de las pruebas es muy importante para asegurar la calidad del software.
Pensad, por ejemplo, en un corrector ortográfico. A pesar de que es posible hacer una corrección manual de un texto, es relativamente fácil que, si tenemos que corregir un documento de cien páginas de forma manual, se nos pasen por alto algunas faltas de ortografía. En cambio, un corrector ortográfico nos asegura que, si detecta una falta de ortografía concreta, la detectará siempre, con independencia de la extensión del documento.
La automatización de las pruebas del software es fundamental para asegurar la consistencia y la repetibilidad de los resultados.
Tener pruebas automatizadas nos ayuda, por ejemplo, con las pruebas de regresión, ya que podemos ejecutar el mismo guión de pruebas una y otra vez con un coste relativamente bajo. Además, si antes ya hemos automatizado el guión de pruebas (por ejemplo, para las pruebas de aceptación), podremos aprovechar el mismo programa para ejecutar las pruebas de regresión.
Las pruebas automatizadas pueden ejecutarse con más frecuencia y, por lo tanto, nos ayudan a detectar problemas antes y a obtener un software de más calidad.
2.3.1.Proceso de pruebas automatizadas
Para estudiar cuál es el proceso de pruebas automatizadas, analizaremos primero cómo probaríamos un sistema manualmente. Para lo cual, a modo de ejemplo, tomaremos Viajes UOC como sistema y pensaremos cómo haríamos pruebas de aceptación de determinadas funcionalidades. Las pruebas manuales de aceptación, en su forma más básica, consistirían en que un stakeholder probara a mano el sistema desarrollado para decidir si satisface o no sus requisitos.
Suponemos que un agente está probando la funcionalidad de escribir una recomendación. Un agente tiene que poder escribir una recomendación sobre un destino y hotel; para lo cual, el agente tiene que poder, desde la pantalla que muestra los datos de un destino o los de un hotel, pulsar un botón "recomendar" y el sistema mostrará un formulario que estará en blanco si aquel agente no había escrito ninguna recomendación anterior o tendrá la información de la recomendación que había escrito, en caso contrario. El agente tiene que poder marcar la recomendación como positiva o negativa y escribir un comentario. El sistema tiene que comprobar que el comentario no esté en blanco (y dar un error si no es así). Finalmente, si no hay error, el sistema tiene que grabar la recomendación y devolver el número de recomendaciones total de aquel hotel o destino y el porcentaje de estas cuando son positivas.
Para probar esta funcionalidad, el agente tendría que hacer varias pruebas. En una, seguramente, escogería un hotel para el cual no hubiera escrito nunca una recomendación y escribiría una recomendación correcta; en otra probaría qué pasa cuando quiere escribir una recomendación de un hotel para el cual ya ha escrito una anterior; en una tercera quizás querría probar qué pasa si no escribe el comentario obligatorio de la recomendación; etc.
Centrándonos en la primera de las pruebas, lo primero que le haría falta es escoger un hotel para el cual el sistema no disponga de recomendaciones escritas por él. Para lo cual, el sistema tendría que tener ya ciertos hoteles registrados y el agente tendría que conocer cuáles son y de cuáles no ha escrito todavía recomendaciones. Entonces podría escoger un hotel y escribir una recomendación. Después comprobaría que el sistema devuelve el número total de recomendaciones y el porcentaje de recomendaciones positivas de forma correcta; para lo cual, de nuevo, necesitaría saber cuántas recomendaciones tenía el hotel inicialmente y cuántas de estas eran correctas. Finalmente, también querría comprobar que, efectivamente, se ha guardado la recomendación correctamente, no fuera caso que el sistema devolviera la información correcta pero, por algún error, la recomendación se perdiera.
Una vez visto cómo sería el proceso de pruebas manuales, podemos centrarnos en cómo lo podríamos automatizar. Como hemos visto, la ejecución de una prueba automatizada implica una serie de pasos que se tienen que automatizar. En concreto, hay que hacer lo siguiente:
1) Situar el sistema que se tiene que probar en un estado conocido que nos permita, al tercer paso, determinar si el resultado y estados finales obtenidos son los que se esperaban. Por otro lado, esto facilitará las pruebas repetibles, ya que podremos ejecutar el mismo guion una y otra vez y siempre serán desde un mismo estado inicial conocido, obteniendo así siempre el mismo resultado.
En nuestro ejemplo, si nos centramos en la primera prueba, de la cual hemos dado más detalles, habría que situar el sistema en un estado en el que haya un agente, un hotel; y el agente no haya escrito ninguna recomendación de aquel hotel. También podríamos añadir otros agentes (por ejemplo, cinco nuevos) y que, de estos, dos hayan escrito una recomendación positiva del hotel y tres más una negativa.
Para ello, como queremos que la prueba sea automatizada, escribiremos código que sitúe el sistema en esta situación de partida conocida; por ejemplo, podemos escribir una función que elimine todos los datos de la base de datos e inserte en ella los datos iniciales deseados: los agentes, el hotel y las recomendaciones.
2) Ejercitar la funcionalidad que se tiene que probar y recoger los resultados que el sistema devuelva.
En nuestro ejemplo necesitamos que la prueba automatizada pida al sistema escribir una recomendación del hotel, escoja el sentido (por ejemplo positivo) y el comentario (por ejemplo "muy buen hotel") y, finalmente, confirme la petición. También nos hará falta recoger el número de recomendaciones y el porcentaje de recomendaciones positivas que el sistema devuelva para poder usarlas más adelante.
3) Verificar el resultado obtenido, si lo hay, y el estado del sistema para comprobar que se corresponden con el resultado y estado resultante esperados.
En nuestro caso, habría que verificar que el sistema ha devuelto que ahora el hotel tiene 6 recomendaciones (las 5 que ya había y la nueva) y que el porcentaje de recomendaciones positivas que ha devuelto es del 50%. En cuanto al estado final resultante, habrá que verificar que ahora el agente tiene asociada una recomendación para este hotel, que esta recomendación es positiva y que el texto de la recomendación es "muy buen hotel".
2.3.2.Pruebas automatizadas de aceptación
Las pruebas automatizadas de aceptación nos permiten verificar los requisitos funcionales del producto en desarrollo. Una vez aceptada la funcionalidad, nos servirán como pruebas de regresión.
El ejemplo del apartado anterior era, justamente, de pruebas automatizadas de aceptación.
2.3.3.Pruebas automatizadas de carga
Uno de los problemas típicos de las pruebas de carga es simular el comportamiento de los usuarios del software de manera realista. Para hacerlo, existen herramientas especializadas que nos permiten modelizar la carga que queremos simular, de modo que, a partir de un guión de pruebas prefijado, ejecutan los diferentes pasos de manera realista simulando, en el caso de sistemas multiusuario, un número determinado de usuarios.
JMeter
Por ejemplo, JMeter es una herramienta de pruebas de carga automatizadas de sistemas principalmente web.
Como podéis ver en la captura de pantalla adjunta, JMeter permite definir un plan de pruebas en el que hay un guión de las pruebas o más de uno. Un guión (Thread Group, en la captura) muestra la lista de peticiones que se enviarán al sistema para simular un usuario.
JMeter utiliza hilos de ejecución concurrentes para simular varios usuarios. Para cada guión de un plan de pruebas, tenemos que indicar cuántos hilos de ejecución queremos que lo ejecuten (número de hilos), cuántas veces queremos que ejecute el guión cada usuario, etc.
De este modo, un plan de pruebas de JMeter es un conjunto de guiones (que representan usuarios que hacen distintos usos) que son ejecutados en paralelo por varios hilos de ejecución, lo que genera una carga realista sobre la aplicación sometida a prueba.
75593m5003.jpg
Otro problema habitual de las pruebas de carga (sobre todo si se trata de pruebas de estrés) viene dado por el software y el hardware necesarios para simular la carga. Tanto el software como el hardware deben ser lo más parecidos posible a sus entornos finales, lo cual puede comportar un gasto importante en adquirir licencias de software y hardware; una vez realizadas las pruebas, tales adquisiciones dejarán de ser útiles.
2.3.4.Datos de prueba
Hemos indicado que hay que situar el sistema en un estado conocido antes de ejecutar las pruebas, pero ¿de dónde obtenemos los datos para este estado conocido? Existen dos tipos de datos de pruebas: los reales y los sintéticos, y los dos son necesarios, ya que nos ayudarán a detectar problemas diferentes.
En el ejemplo del apartado 2.3.1. hemos usado datos sintéticos, puesto que hemos propuesto insertar hoteles, agentes y opiniones sin preocuparnos de que fueran reales. Otra opción hubiera sido usar datos reales: los de hoteles, agentes y opiniones reales.
Datos reales
Los datos reales provienen de un sistema real (un sistema existente, un sistema competidor o un prototipo del sistema real). Estos datos nos ayudan a descubrir cuáles son los datos “normales” para nuestro software y nos pueden ayudar a descubrir errores en la interpretación de los requisitos.
Sin embargo, hay que ir con cuidado con los datos de carácter personal, ya que están sometidos a una legislación especial que los protege y que, a menudo, nos impide distribuirlos libremente como parte del guión de pruebas.
Podemos tratar los datos para convertirlos en anónimos, a pesar de que este proceso resulta más difícil de lo que parece a priori. Así, por ejemplo, en el caso de los datos personales, podríamos pensar que estamos protegiendo lo suficiente la intimidad de las personas si cambiamos una referencia tan significativa como el nombre. Pues bien, según Latanya Sweeney, el código postal, el género y la fecha de nacimiento permiten identificar al 87% de la población de Estados Unidos.
Datos sintéticos
Los datos sintéticos, en cambio, son generados de forma artificial con un propósito concreto, por lo general cuando necesitamos:
  • Un volumen de datos muy grande (disponemos de datos reales pero necesitamos más).

  • Datos para probar los casos límite (fechas especiales como el 29 de febrero, registros muy grandes, direcciones con códigos postales extranjeros, etc.).

  • Datos con unas características muy concretas (por ejemplo, datos que son el peor caso en un algoritmo de ordenación, etc.).

3.Desarrollo guiado por las pruebas

El ciclo de vida tradicional de desarrollo de software nos dice que las pruebas se tienen que llevar a cabo una vez implementado el sistema. En la práctica, esto lleva a que, en muchos casos, debido a la presión por entregar el software lo antes posible, el esfuerzo dedicado a pruebas no sea suficiente y que, por lo tanto, el software no se verifique de forma adecuada.
El desarrollo guiado por las pruebas es una manera de desarrollar software que intenta solucionar este problema aplicando dos reglas muy sencillas:
  • Hay que escribir las pruebas antes de implementar el sistema.

  • Solo se tiene que implementar la funcionalidad necesaria para superar las pruebas.

De este modo conseguimos dos objetivos: asegurarnos de que se dedique a las pruebas el esfuerzo necesario (puesto que no podemos dejarlas para el final), al mismo tiempo que nos aseguramos de que todas las funcionalidades implementadas estén cubiertas por alguna prueba.
Dado que las pruebas se escriben antes de desarrollar el software, también nos pueden servir para especificarlo (en este caso, especificación formal, ya que las pruebas están escritas en un lenguaje interpretable por la máquina) y, por lo tanto, podemos automatizar el proceso de verificación del software.
Históricamente, el desarrollo guiado por las pruebas comenzó aplicado al contexto de las pruebas unitarias (llamado TDD, test driven development). De aquí pasó al contexto de las pruebas de aceptación (ATDD, acceptance test driven development), que finalmente dio lugar al conocido como desarrollo guiado por el comportamiento (BDD, behavior drive ndevelopment) o especificación por ejemplos (specification by examples).

3.1.El proceso del desarrollo guiado por las pruebas

El desarrollo guiado por las pruebas sigue un proceso en el que, a diferencia de otros procesos, primero se escriben las pruebas y después la implementación de la funcionalidad que habrá que probar.
Podemos ver el proceso descrito en la siguiente figura:
75593m5004.gif
Inicialmente, el desarrollador identifica la funcionalidad que quiere implementar y escribe una prueba que verifique un subconjunto de la funcionalidad. Esta prueba será la especificación que guiará al desarrollador durante la fase de implementación. En el supuesto de que la prueba sea una prueba de aceptación, deberá hablar con los stakeholders, expertos en el dominio, etc. para afinar los requisitos.
Cuando la prueba esté escrita, la ejecutará (hay que asegurarse de que la prueba falla, ya que si no falla cuando la funcionalidad no está implementada, esto significa que la prueba no está bien escrita) e implementará la funcionalidad necesaria para superarla. Una vez pasada la prueba, decidirá si hace falta reestructurar el código o no (con la tranquilidad que da una prueba de regresión, que le permite saber si la funcionalidad implementada continúa funcionando) y, una vez superadas de nuevo todas las pruebas, pasará al siguiente subconjunto de funcionalidad que hay que implementar.
Este proceso se va repitiendo hasta que los stakeholders y los expertos en pruebas consideren que la funcionalidad escogida ha sido totalmente implementada, momento a partir del cual se puede pasar a implementar la siguiente funcionalidad.
Una funcionalidad está completamente implementada cuando hemos probado todos los casos que se han considerado necesarios y el software ha superado todas las pruebas.
Las pruebas no solo sirven para verificar que el software funciona correctamente, sino que también son útiles como documentación, ya que están llenas de ejemplos de uso de dicho software.
Por ejemplo, supongamos que tenemos este juego de pruebas para un evaluador de expresiones:
public class ExpressionTest extends TestCase {
   public void testASingleNumberIsAnExpression() {
      assertEquals(2, evaluate("2"));
   }

   public void testInvalidCharactersAreRejected() {
      try {
         evaluate("2@2");
         fail ("Should have thrown an exception");
      }  catch (InvalidCharacterException e) {
         //Everything is ok
      }
   }
   ...
En este ejemplo, podemos observar que un número solo es una expresión correcta, así como de qué forma se notifica el caso de que haya un carácter incorrecto en la expresión.
El hecho de contar con pruebas de regresión automatizadas nos facilita la reestructuración del código (refactoring) y, por lo tanto, aumenta la mantenibilidad del software.
A diferencia de la documentación escrita, las pruebas automatizadas son muy fáciles de mantener al día, ya que podemos ejecutar un programa que nos verifique si todavía es cierto que el sistema se comporta tal y como especifican las pruebas.

3.2.Desarrollo guiado por el comportamiento

El desarrollo guiado por el comportamiento (en inglés behavior driven development, BDD) es una técnica de desarrollo de software guiado por las pruebas que promueve la colaboración entre desarrolladores, expertos en pruebas y personal no técnico mediante la utilización de un lenguaje común.
Esta técnica parte de la idea de que es interesante documentar los criterios de aceptación de un sistema (los criterios según los cuales se decidirá si lo desarrollado es lo que se quería o no) en el lenguaje de aquellas personas cuya opinión sea más necesaria (el de los stakeholders y los analistas de negocio).
Por este motivo, es importante que los criterios de aceptación estén documentados con el lenguaje que emplean en su día a día (el lenguaje natural), no con un lenguaje específico para esta tarea.
Esta es, precisamente, una de las principales diferencias del BDD con respecto a otros enfoques del desarrollo guiado por las pruebas: la creación de un lenguaje común para todas las personas implicadas en el desarrollo, desde los stakeholders y los analistas de negocio hasta los programadores.
75593m5005.gif
Podemos considerar una funcionalidad completamente implementada cuando hemos documentado todos los escenarios que se han considerado necesarios y el software los ha ejecutado todos de forma correcta.
A diferencia de otros escenarios de desarrollo guiado por las pruebas, el BDD enfatiza el lenguaje con el que se describen las pruebas y el hecho de que debe ser el mismo que utilizan los stakeholders. Por este motivo, a menudo se escriben con un lenguaje cercano al lenguaje natural. Para permitir su ejecución automatizada, los programadores se encargan de que un programa sea capaz de leer estas pruebas y ejecutarlas. Veamos un ejemplo.
Funcionalidad: Ver las opiniones sobre un hotel
Como cliente,
Quiero ver las opiniones sobre un hotel
Para poder decidir si voy o no
Escenarios:
Escenario 1: El hotel tiene opiniones
Suponiendo que el hotel existe
Y que hay registrada una opinión que dice “Es un lugar excelente” creada por Joan Salvat
Y que hay registrada una opinión que dice “No iría nunca” creada por la Maria Cases
Cuando el cliente pide ver las opiniones sobre el hotel
Entonces se muestran dos opiniones
Y una es la de Joan Salvat que dice “Es un lugar excelente”
Y la otra es la de Maria Cases que dice “No iría nunca”
Escenario 2: El hotel no existe
Suponiendo que no existe ningún hotel llamado “X”
Cuando el cliente pide ver las opiniones del hotel “X”
Entonces se muestra un mensaje explicando que no existe ningún hotel denominado “X”
Como podemos observar, cada funcionalidad se documenta como una serie de escenarios, cada uno de los cuales documenta un uso concreto del sistema, partiendo de un estado conocido así como de los resultados que se observan. Por este motivo, también se usa la expresión especificación por ejemplos como sinónimo de BDD (cada escenario es un ejemplo de utilización del sistema).
En este caso, a pesar de que se ha utilizado el lenguaje natural, se ha seguido una estructura muy concreta y muy fácil de transformar en instrucciones de código. Si volvemos a considerar el escenario de ejemplo, podemos observar cómo lo transformaríamos en código:
Escenario 1:
Suponiendo que el hotel existe
Hotel hotel = Hotel.crear(nombreCualquiera, ...)
Y que hay registrada una opinión que dice “Es un lugar excelente” creada por Joan Salvat
Usuario joanSalvat = Usuario.crear(“Joan”, “Salvat”)
Opinion opinionJoan = Opinion.crear(hotel, joanSalvat, “Es un lugar excelente”)
Y que hay registrada una opinión que dice “No iría nunca” creada por Maria Cases
Usuario mariaCases = Usuario.crear(“Maria”, “Cases”);
Opinion opinionMaria = Opinion.crear(hotel, mariaCases, “No iría nunca”)
Cuando el cliente pide ver las opiniones sobre el hotel
List<Opinion> opiniones = Sistema.verOpiniones(hotel.getIdentificador())
Entonces se muestran las dos opiniones
verificar(opiniones.size() == 2);
Y una es la de Joan Salvat que dice “Es un lugar excelente”
verificar(opiniones.exist(o | o.usuario.nombre = “Joan Salvat” and o.text=”Es un lugar excelente”))
Y la otra es la de Maria Cases que dice “No iría nunca”
verificar(opiniones.exist(o | o.usuario.nombre = “Maria Cases” and o.text=”No iría nunca”))
Podemos ver que el subconjunto del lenguaje natural que hemos utilizado se basa en dar cierta regularidad a las frases de modo que podamos escribir una expresión regular que extraiga, de la frase “Y una es la de Joan Salvat que dice “Es un lugar excelente””, los dos componentes que nos interesan (“Joan Salvat” y “Es un lugar excelente”).
Por otro lado, podemos ver que el escenario tiene la misma estructura de prueba automatizada que hemos descrito. En este sentido, hay tres tipos de pasos en el escenario:
  • los que indican cuál es el estado del sistema antes de ejecutar la prueba (que corresponden a instrucciones del tipo “Dar de alta”);

  • el que indica cuál es la operación de sistema que queremos ejecutar; y

  • los que indican qué verificaciones tenemos que hacer sobre el resultado para aceptar la funcionalidad (que corresponden a instrucciones del tipo “Verificar”).

La estructura “Suponiendo que (x) cuando hacemos (y) entonces (z)” es típica de la descripción de escenarios en BDD y se corresponde con el proceso de pruebas automatizadas que hemos descrito anteriormente: situamos el sistema en un estado conocido (x), ejercitamos la funcionalidad (y) y verificamos que el estado del sistema es (z).
3.2.1.El proceso de BDD
El proceso de BDD consiste en desarrollar el software funcionalidad a funcionalidad (es un proceso incremental) y, más concretamente, escenario a escenario.
75593m5006z.gif
Los programadores, los expertos en el dominio, los expertos en pruebas y el responsable del producto se reúnen para discutir una funcionalidad (por lo general, una historia de usuario). En el caso de seguir un proceso iterativo, esta reunión tiene lugar al inicio de la iteración.
Entre todos, descomponen la funcionalidad hasta llegar a obtener un conjunto de escenarios. El responsable del producto es quien tiene que decidir cuándo se ha conseguido un conjunto de escenarios suficiente para la iteración actual y dar por finalizada la reunión.
Sin embargo, antes de llevar a cabo cualquier implementación, el experto de pruebas refina los escenarios añadiendo algunos nuevos si hace falta (por ejemplo, casos límite que no se tuvieron en cuenta durante la reunión inicial). A partir de esta serie de escenarios descritos, los desarrolladores implementan el código de apoyo para ejecutarlos y, a continuación, la funcionalidad necesaria para ejecutarlos con éxito.
Una vez finalizada la implementación, los desarrolladores pueden mostrar su funcionamiento al resto de las personas implicadas y los expertos en pruebas pueden efectuar las pruebas manuales que consideren necesarias.
Mediante el BDD desarrollamos las pruebas (la documentación de los escenarios y el código necesario para ejecutarlos) antes que la funcionalidad, y lo hacemos en lenguaje natural (escenarios). Además, las pruebas se pueden ejecutar de manera automatizada.

3.3.Herramientas para la automatización de las pruebas de aceptación

Como hemos visto, con el BDD describimos los escenarios de cada funcionalidad en un formato que los stakeholders y los analistas de negocio pueden entender, pero todo esto no sería mejor que un documento textual tradicional si no contáramos con la posibilidad de ejecutar de manera automatizada una prueba de aceptación basada en esta descripción.
La utilización de una herramienta de automatización de pruebas de aceptación es lo que distingue el BDD de los enfoques no formales de especificación.
A continuación presentamos dos familias de herramientas y veremos cómo podemos especificar escenarios en los dos casos.
3.3.1.Herramientas basadas en tablas
Una de las primeras herramientas para la ejecución de pruebas de aceptación fue Fit (framework for integratedtesting), creada por Ward Cunningham a principios de los años 2000.
Fit emplea documentos HTML con tablas donde se describen escenarios formados por diferentes combinaciones de entradas al sistema y las salidas esperadas en cada caso. A continuación, ved un ejemplo.
Cálculo básico del salario
Cada semana, los trabajadores que cobran por horas cobran un precio fijo por hora las primeras 40 horas y, a partir de aquí, cobran 1,5 veces el precio/hora por el resto de las horas en días laborables. Las horas trabajadas en festivo se pagan a 2 veces el precio/hora.
A continuación, tenemos algunos ejemplos:
Nominas.CompensacionSemanal

HorasLaborables

HorasFestivos

PrecioHora

Pagar()

40

0

20 €

800 €

45

0

20 €

950 €

48

8

20 €

1.360 €

Como podemos ver, una prueba de Fit tiene un título, una descripción, un nombre (en el ejemplo, Nominas.CompensacionSemanal) y una tabla de valores. De hecho, para la ejecución de la prueba solo nos interesa el nombre de la prueba y la tabla y, por lo tanto, la descripción solo es para ayudar a quien lea la prueba a entender su finalidad.
En la tabla, las primeras columnas indican los valores que se usarán como entrada y/o estado inicial del sistema. Las otras columnas indican cuáles son los resultados que el sistema tendría que devolver y/o el estado final en el que tendría que acabar.
En nuestro ejemplo, HorasLaborables, HorasFestivos y PrecioHora son datos de entrada de una función para calcular cuánto hay que pagar a un trabajador que ha hecho estas horas. La columna Pagar() indica el resultado esperado, el valor que se espera que esta función devuelva.
La tabla tiene tantas filas como combinaciones de entradas se quieran probar. Por lo tanto, cada fila indica, para una determinada combinación de datos de entrada, los resultados esperados.
Para automatizar las pruebas de Fit, desarrolladores deben escribir un pequeño programa que, dados los datos de las columnas de entrada para una fila (en nuestro ejemplo, HorasLaborables, HorasFestivos y PrecioHora ), ejecutan la función que hay que probar y devuelven los datos de las otras columnas de la fila (en nuestro ejemplo, Pagar()):
public class CompensacionSemanal {

   public int HorasLaborables;
   public int HorasFestivos;
   public Importe PrecioHora;

   public Importe Pagar () {
      return Sistema.pagar(HorasLaborables, HorasFestivos, 
      PrecioHora);
   }
}
Fit lee el documento HTML, ejecuta la prueba y genera un nuevo documento donde modifica la tabla para indicar el resultado de las pruebas:
75593m5007.gif
Sin embargo, uno de los problemas que presenta Fit es que hay que escribir el código HTML manualmente y con el formato adecuado, lo cual hace difícil mantener la documentación. Para hacer frente a este hecho, se creó Fitnesse, que combina la facilidad de edición de una wiki con el modelo de pruebas de aceptación de Fit.
Con Fitnesse, los casos de pruebas se escriben con sintaxis de wiki, que, a priori, es más sencilla que el código HTML. Así pues, el escenario anterior se puede describir de la siguiente forma:

|Nominas.CompensacionSemanal|

|horasLaborables

|horasFestivos

|precioHora

|pagar()

|

|40

|0

|20 €

|800 €

|

|45

|0

|20 €

|950 €

|

|48

|8

|20 €

|1360 €

|

La mecánica es la misma: creamos una tabla con los datos de los ejemplos; creamos una clase que reciba dichos datos, ejecute cualquier funcionalidad del sistema y nos devuelva un valor, y comprobamos si el valor devuelto coincide con el valor esperado.
Una alternativa a Fit/Fitnesse es Concordion, que se creó con el objetivo de centrarse en la legibilidad de los casos de prueba. Concordion, al igual que Fit, parte de la creación manual de documentos HTML.
3.3.2.Herramientas basadas en escenarios
Existen otras herramientas que dan una mayor prioridad a la descripción en forma de escenario que a la tabla en sí, como es el caso de Cucumber. De hecho, el escenario que hemos visto descrito al principio del subapartado 3.2 sigue este formato.
El escenario anterior, si lo queremos implementar con Cucumber, se reescribe como:

#language: es
Característica: CompensacionSemanal
Cada semana, los trabajadores que cobran por horas cobran un precio fijo por hora las primeras 40 horas y, a partir de aquí, cobran 1,5 veces el precio/hora por el resto de las horas en días laborables. Las horas trabajadas en festivo se pagan a 2 veces el precio/hora.

Esquema del escenario: Calcular la compensación semanal

Suponiendo que un trabajador ha hecho <horas_laborables> en una semana
Y que ha trabajado <horas_festivos> horas en festivos
Y que el precio por hora es <precio_hora>
Cuando calculamos la compensación semanal
Entonces el resultado es <compensacion>

Ejemplos:

|horas_laborables

|horas_festivos

|precio_hora

|compensacion

|

|40

|0

|20 €

|800 €

|

|45

|0

|20 €

|950 €

|

|48

|8

|20 €

|1360 €

|

Como se puede ver, aunque se escribe diferente la idea de prueba es la misma: describir la prueba en un formato fácil de entender por parte de los clientes (recordemos que la idea original es que sean ellos quienes escriban las pruebas) y fácil de interpretar por un programa que nos diga si el sistema cumple lo especificado o no.
En cuanto a los cambios formales, podemos ver que el esquema del escenario da una descripción en lenguaje natural del mismo escenario; en la descripción hay una serie de parámetros (indicados entre los símbolos < y >). Este esquema funciona como una plantilla, cuyos valores los proporciona la tabla de ejemplos. La tabla, por lo tanto, tiene que tener tantas columnas como parámetros tiene la plantilla, con los mismos nombres. Cada fila de la columna se puede leer, pues, usando el esquema del escenario y sustituyendo los parámetros por el valor indicado en aquella fila:
Así, en el ejemplo, la primera fila se puede leer, sustituyendo los parámetros de la plantilla por sus valores, como:
Suponiendo que un trabajador ha hecho 40 horas laborables en una semana
Y que ha trabajado 0 horas en festivos
Y que el precio hora es 20 €
Cuando calculamos la compensación semanal
Entonces el resultado es 800 €
En Cucumber, para automatizar la prueba, los desarrolladores tienen que escribir el software que permitirá ejecutar la prueba de forma automatizada. Este software tiene operaciones de tipo SuponiendoQue, que identifican las expresiones en lenguaje natural mediante expresiones regulares (en el ejemplo, que está escrito en el lenguaje Ruby, las expresiones regulares van entre barras), identifican los parámetros y guardan los valores. También tiene operaciones de tipo Cuando, que ejecutan la funcionalidad a probar. Finalmente, tiene operaciones de tipo Entonces, que comprueban los resultados obtenidos. Veamos un ejemplo:
#encoding: utf-8
    begin require 'rspec/expectations';rescueLoadError;require 'spec/expectations';end
    require 'cucumber/formatter/unicode'
    $:.unshift(File.dirname(__FILE__) + '/../../lib')
    require 'compensacion_semanal'
    Before do
       @sistema = CompensacionSemanal.new
    end
    SuponiendoQue /un trabajador ha hecho (\d)+ horas laborables en una semana/ do | hl |
       @hores_laborables = hl
    end
    SuponiendoQue /ha trabajado (\d)+ horas en festivos / do | hf |
            @hores_festius = hf
    end
    SuponiendoQue /el precio por hora es (\d)+/ do | ph |
            @precio_hora = ph
    end
    Cuando /calculamos la compensación semanal/ do
            @resultat = @sistema.compensacion_setmanal
                (@hores_laborables, @hores_festius, @preu_hora)
    end
    Entonces /el resultado es (\d)+/ do | result |
       @resultado.should == result
    end
Como podemos apreciar, el código de la prueba depende en gran parte del lenguaje natural utilizado en la definición de las expresiones y, por este motivo, una de las tareas que las herramientas como Cucumber nos facilitan es la generación de este código (sobre todo de las expresiones regulares).
Siempre que nos mantengamos en un subconjunto pequeño del lenguaje natural, este enfoque nos permite obtener lo mejor de los dos mundos: la capacidad de automatización, coherencia y la inambigüedad de los lenguajes formales y la expresividad del lenguaje natural.

4.Caso práctico

Para el caso práctico, consideraremos la parte de pruebas automatizadas que permitirán verificar los requisitos una vez implementado el sistema Viajes UOC. En concreto, veremos un ejemplo de plan de pruebas de aceptación y uno de pruebas de carga.
No trataremos la validación de requisitos, ya que, para saber si los requisitos son válidos o no, necesitamos un dominio real con el que comparar.

4.1.Pruebas automatizadas de aceptación

Partiremos del siguiente caso de uso:
Caso de uso: Introducir una recomendación sobre un hotel.
Actor principal: Agente de viajes.
Ámbito: Sistema informático de ventas de Viajes UOC.
Nivel de objetivo: Usuario.
Stakeholders e intereses:
Agente de viajes: quiere hacer la recomendación.
Cliente: querrá leer la recomendación.
Precondición: El agente de viajes tiene que haberse identificado al sistema.
Garantías mínimas: -
Garantías en caso de éxito: El sistema guardará la recomendación para mostrarla en el futuro.
Escenario principal de éxito:
1) El agente de viajes busca el hotel sobre el que quiere escribir una recomendación y, como resultado, el sistema muestra la ficha de detalle del hotel.
2) El agente de viajes escribe su recomendación (que puede ser positiva o negativa).
3) El sistema guarda la recomendación asociada al agente de viajes y al hotel.
Extensiones:
1a. El agente de viajes no encuentra el hotel.
1a1. El caso de uso finaliza.
3a. El agente de viajes ya había hecho una recomendación sobre ese hotel.
3a1. El sistema avisa al usuario de que se perderá la recomendación anterior.
3a2. Si el agente de viajes confirma que quiere sobrescribirla, el sistema guarda la recomendación asociada al agente de viajes y al hotel.
El caso de uso incluido “buscar el hotel” tendrá su propia prueba de aceptación y, por lo tanto, no es preciso que lo consideremos en nuestro caso.
4.1.1.Plan de pruebas
Para el plan de pruebas nos basamos en la estructura propuesta por el estándar IEEE-829:
Plan de pruebas de aceptación “Introducir una recomendación sobre un hotel”
Referencias: Modelo de casos de uso.
Elementos de prueba: Software de Viajes UOC, funcionalidad “Introducir una recomendación sobre un hotel”.
Riesgos: Ninguno.
Características que no se probarán: Buscar el hotel puesto que esta característica tiene su propio plan de pruebas.
Herramientas que se utilizarán:
Cucumber (automatización de pruebas de aceptación).
Métricas que se recogerán:
Solo se recogerá si la prueba se ha ejecutado correctamente o no.
Configuración:
  • Se creará un conjunto de escenarios de pruebas para Cucumber.

  • Se utilizarán datos sintéticos que se generarán dentro del propio escenario.

Software y hardware que se utilizarán:
Se utilizará un entorno similar al de producción a pesar de que dicha similitud no es una prioridad.
Criterio de aceptación:
La prueba se ha completado con éxito si se ejecutan todos los guiones satisfactoriamente.
Criterio de cancelación:
Ninguno. Se ejecutarán todos los escenarios con independencia de que los otros tengan éxito o no.
Entregables:
Informe de ejecución de la prueba con el resultado detallado por escenarios.
4.1.2.Escenarios de pruebas
Para la redacción de los escenarios de pruebas, utilizaremos el formato que hemos visto en el subapartado 3.2 (BDD).
Funcionalidad: Introducir una recomendación sobre un hotel
Como agente de viajes,
Quiero introducir una recomendación sobre un hotel
Para que mis clientes estén bien asesorados
Escenarios:
Escenario 1: Es la primera recomendación
Suponiendo que existe el hotel Ritz
Y que existe un agente de viajes llamado Joan
Cuando el agente Joan escribe una recomendación positiva “Está muy bien” sobre el hotel Ritz
Entonces hay una recomendación positiva “Está muy bien” del agente “Joan” sobre el hotel Ritz
Escenario 2: Ya había hecho una recomendación y confirma que quiere sobrescribirla
Suponiendo que existe el hotel Ritz
Y que existe un agente de viajes llamado Joan
Y que el agente Joan ha hecho una recomendación positiva “Está muy bien” sobre el hotel Ritz
Cuando el agente Joan escribe una recomendación positiva “Volvería” sobre el hotel Ritz y la confirma
Entonces hay una recomendación positiva “Volvería” del agente “Joan” sobre el hotel Ritz
Escenario 3: Ya había hecho una recomendación pero no confirma que quiere sobrescribirla
Suponiendo que existe el hotel Ritz
Y que existe un agente de viajes llamado Joan
Y que el agente Joan ha hecho una recomendación positiva “Está muy bien” sobre el hotel Ritz
Cuando el agente Joan escribe una recomendación positiva “Volvería” sobre el hotel Ritz
Y no la confirma
Entonces hay una recomendación positiva “Está muy bien” del agente “Joan” sobre el hotel Ritz

4.2.Pruebas de carga

En este caso, supongamos que nos han pedido que aseguremos que la plataforma de Viajes UOC es capaz de soportar un volumen de mil usuarios conectados a la vez al sistema haciendo buscas sobre hoteles.
Un posible plan de pruebas que podríamos preparar en este caso sería:
Plan de pruebas de carga para 1.000 usuarios simultáneos
Referencias: documento de descripción de cargas esperadas, documento de arquitectura de hardware de producción.
Elementos de pruebas: software de Viajes UOC, funcionalidades de busca de hoteles, consulta de los detalles de un hotel.
Riesgos: principalmente, que la carga real posterior no se asemeje a la carga modelada en las pruebas.
Características que no se probarán: las otras funcionalidades no incluidas explícitamente ni tampoco ningún otro aspecto que no sea la carga soportada. En particular, se comprobará que las respuestas recibidas durante las pruebas no son de error, pero no que se devuelvan los datos correctos, puesto que no se quieren hacer pruebas funcionales.
Herramientas que se utilizarán:
  • Se utilizará JMeter para simular un gran número de usuarios concurrentes. Habrá que definir un script de pruebas o más y definir el número de clientes que queremos que ejecuten cada script de pruebas.

  • Se usarán las herramientas de monitorización que sean necesarias por lo que respecta a consumo de hardware (CPU, memoria, entrada/salida, red, etc.)

Métricas que se recogerán:
  • En los nodos clientes de las pruebas, tiempos de respuesta, respuesta de error sí/no, número de peticiones realizadas por segundo de cada tipo y resto de métricas que recoja el software de pruebas utilizado.

  • En todos los nodos, porcentaje de CPU usado, porcentaje de memoria física usada, tamaño de memoria de intercambio empleado, ancho de banda de red utilizado (de subida y de bajada), though put de entrada/salida a disco usado.

Configuración:
  • Se creará un script de pruebas para simular un usuario que se conecta a Viajes UOC, hace un par de buscas y consulta los detalles de un hotel. En este script, el usuario tardará más o menos cinco segundos después de hacer una petición antes de hacer la siguiente.

  • Se usarán datos de pruebas sintéticos (a falta de datos reales) para llenar la base de datos con volúmenes parecidos a los indicados en el documento de cargas esperadas.

  • Se harán varias etapas de pruebas:

    • Se simulará un usuario para comprobar que el entorno de pruebas funciona correctamente y que todo está a punto.

    • Se simulará un número de usuarios creciente desde diez hasta alcanzar los mil usuarios concurrentes, incrementando el número de usuarios a razón de diez usuarios adicionales por segundo. Por lo tanto, en cien segundos se llegará a los mil usuarios. Una vez alcanzados los mil usuarios, se continuará la prueba durante cinco minutos. Cada usuario repetirá indefinidamente el escenario hasta que finalice la prueba.

Software y hardware que se utilizarán:
  • Se utilizará un entorno idéntico al descrito en el documento de arquitectura de hardware de producción para ejecutar el software de Viajes UOC.

  • Además, se usarán diez nodos pequeños de nuestro proveedor de hardware como servicio en la nube para ejecutar las pruebas (actuarán como clientes, simulando, cada uno, una décima parte de los clientes totales).

  • En los nodos clientes se utilizará JMeter para simular la carga ejercida por los usuarios.

Criterio de aceptación:
  • Durante la segunda etapa se llega a los mil usuarios concurrentes, que ejecutan sus escenarios durante un minuto y, en global, un 98% de las respuestas tienen que ser correctas y con un tiempo de respuesta inferior a cinco segundos.

Criterio de cancelación:
  • Si la primera ronda de pruebas no resulta con el 100% de las respuestas correctas y con tiempo de respuesta inferior a dos segundos.

  • En cualquier momento, si el porcentaje de respuestas correctas y con tiempo de respuesta inferior a cinco según está por debajo del 90%, puesto que entendemos que el sistema ya no se recuperará.

Resumen

En este módulo hemos estudiado que la validación de requisitos es el proceso mediante el cual nos aseguramos de que los requisitos que hemos elegido para el producto que estamos desarrollando reflejen las expectativas de los stakeholders. Por lo tanto, nos permite asegurar que los desarrolladores han entendido correctamente los requisitos del software en desarrollo. También nos servirá para asegurarnos de que la documentación de dichos requisitos se entiende, es consistente, está completa y cumple los estándares adecuados.
La validación de requisitos no se puede automatizar y, por eso, se acostumbra a llevar a cabo mediante las llamadas revisiones de requisitos, donde un grupo de personas se reúne y busca errores y problemas en las especificaciones.
Por otro lado, también hemos tratado la verificación de requisitos, que es el proceso mediante el cual comprobamos que el sistema desarrollado cumple los requisitos requeridos. A diferencia de la validación, este proceso si es automatizable.
El plan de pruebas es el documento que recoge las pruebas que ejecutaremos para verificar que el software cumple los requisitos. También es importante tener en cuenta los diferentes tipos de pruebas, puesto que cada uno nos permite conseguir un objetivo diferente y, por lo tanto, será necesario que dicho plan de pruebas incluya pruebas de varias clases.
Finalmente, hemos analizado el desarrollo guiado por las pruebas y, más concretamente, la variedad del desarrollo guiado por el comportamiento (BDD), que es una forma de desarrollar software en el que las pruebas suponen el elemento central del proceso. El objetivo de esta técnica es asegurarse de que hay pruebas automatizadas para todos los requisitos del software. Hemos visto cómo funcionan algunas herramientas de automatización de las pruebas y cómo podemos describir los diferentes escenarios de pruebas en un formato compatible con dichas herramientas.

Actividades

1. Supongamos que disponemos de la siguiente documentación de casos de uso de CrowdArt (una plataforma de mecenazgo de proyectos artísticos).
Caso de uso:
El artista pide dar de alta un proyecto y el sistema graba todos los datos de dicho proyecto. Algunos ejemplos de estos datos son el nombre, el importe, quizás una foto (y está por ver si consideramos vídeos y/o archivos de audio o no).
Suponiendo que la descripción sea correcta (es decir, la necesidad real existe y es tal y como se ha descrito), ¿qué problemas veis en la documentación del caso de uso planteado?
2. Supongamos que disponemos de la siguiente documentación de casos de uso de CrowdArt.
Caso de uso: Hacer una promesa de financiación.
Actor principal: Mecenas.
Escenario principal:
El mecenas puede buscar proyectos en CrowdArt (ved caso de uso “Buscar proyectos”) y, cuando decide hacer una aportación a un proyecto, el sistema le pide los datos de la tarjeta de crédito que nos obliga a aportar la entidad financiera con la que trabaja CrowdArt: el número de la tarjeta, el nombre del titular, el mes de caducidad y el código de seguridad. Con esta información, el sistema procede a retener el saldo correspondiente a la aportación elegida mientras dure el proceso de financiación del proyecto (cuarenta días desde el inicio). Una vez retenido el saldo, la promesa de financiación del proyecto por parte del mecenas quedará grabada.
Escenarios alternativos:
Si el sistema de autorización de crédito indica que no se ha podido retener el saldo en la tarjeta, entonces la promesa de financiación no quedará grabada.
a) Diseñad un plan de pruebas de aceptación para la funcionalidad descrita.
b) Haced una descripción de escenarios para una prueba automatizada de aceptación de esta funcionalidad según el formato que aparece en el subapartado 3.2.
3. Suponed que queremos hacer pruebas de carga y de estrés para CrowdArt. Disponemos de un documento que describe las condiciones de carga esperadas en momentos punta (un total de quinientos mil usuarios registrados, dos mil usuarios concurrentes, una petición cada tres segundos por usuario conectado de media, etc.) y de otro que documenta la arquitectura de hardware que se utilizará en producción y que se quiere validar (un balanceador de carga, cuatro nodos de proceso web con unas características que ahora no son relevantes, dos nodos de base de datos, etc.). Centrándonos en la busca y consulta de proyectos y en las promesas de financiación:
a) Diseñad un plan de pruebas de carga. Haced las presuposiciones que creáis necesarias pero proponed un plan de pruebas realista. No es necesario que defináis los entregables ni a los responsables de las pruebas.
b) ¿Qué cambiaríais si el plan de pruebas fuera de estrés en lugar de ser de carga? Razonadlo brevemente.

Ejercicios de autoevaluación

1. ¿En qué consiste la validación de requisitos?

2. Indicad un ejemplo de error que se podría detectar mediante la validación de requisitos.

3. ¿Qué actividad nos permite detectar que una especificación de requisitos satisface las propiedades que son deseables en ella?

4. ¿Qué técnica nos puede ayudar a validar requisitos si disponemos de un grupo de personas para llevarla a cabo? ¿En qué consiste?

5. ¿En qué consiste la verificación de requisitos?

6. ¿Qué actividad nos permite detectar que un software no satisface un requisito que es importante para un stakeholder y que se documentó correctamente como requisito?

7. Imaginad que hemos entregado un software a un cliente y después detectamos que un requisito de un stakeholder no se satisface de forma correcta. ¿Qué técnicas nos habrían podido ayudar a detectar el problema? ¿En qué casos nos podría ayudar cada técnica?

8. ¿Cuáles son los tres ámbitos que se ha explicado que pueden cubrir las pruebas de software? ¿Cómo se denominan las pruebas que emplea cada ámbito?

9. ¿Cuáles son los objetivos que se ha explicado que pueden perseguir las pruebas de software? ¿Cómo se denominan las pruebas destinadas a satisfacer cada objetivo?

10. ¿Cuáles son las grandes ventajas de la automatización de las pruebas?

11. ¿Cuáles son los pasos del proceso de pruebas automatizadas?

12. ¿Qué ventajas e inconvenientes tiene utilizar datos de pruebas reales?

13. En TDD, ¿cuándo se considera que una funcionalidad está completamente implementada?

14. ¿Cómo aumenta el TDD la mantenibilidad del software?

15. ¿Qué tareas hay que llevar a cabo para escribir las pruebas en el BDD?

Solucionario

Actividades
1. De entrada, no podemos saber si está completa o no, ya que no se indican los stakeholders relacionados. Por ejemplo, no podemos saber si se ha tenido en cuenta al moderador de CrowdArt a la hora de describir cómo debe ser la funcionalidad de alta de proyecto (por ejemplo, no sabemos si hay un máximo o un mínimo de importe, etc.).
También es ambigua, ya que, por ejemplo, no indica con exactitud cuáles son los datos que se tienen que guardar sobre un proyecto.
Por lo que respecta a la verificabilidad, tampoco es sencillo prever cómo podremos determinar si se ha implementado correctamente o no por el motivo anterior (es demasiado ambigua).
Finalmente, dado que el caso de uso carece de identificador, será muy difícil mantener la trazabilidad, ya que no podremos hacer referencia a él desde otros documentos o desde otros apartados del mismo documento.
2.
a) Plan de pruebas de aceptación “Hacer una promesa de financiación”
Referencias: Modelo de casos de uso.
Elementos de pruebas: Software de CrowdArt, funcionalidad “Hacer una promesa de financiación”.
Riesgos: Interacción con el sistema de autorización de crédito (se tendrá que simular).
Características que no se probarán: Límites de tamaño en campos como el nombre, casos donde la busca no encuentra proyectos (riesgo bajo).
Herramientas que se utilizarán:
Cucumber (automatización de pruebas de aceptación).
Métricas que se recogerán:
Solo se recogerá si la prueba se ha ejecutado correctamente o no.
Configuración:
  • Se creará un conjunto de escenarios de pruebas para Cucumber.

  • Se utilizarán datos sintéticos que se generarán dentro del propio escenario.

Software y hardware que se utilizarán:
Se utilizará un entorno similar al de producción a pesar de que dicha similitud no es una prioridad.
Criterio de aceptación:
La prueba se ha completado con éxito si se ejecutan todos los guiones de forma satisfactoria.
Criterio de cancelación:
Ninguno. Se ejecutarán todos los guiones con independencia de que los otros tengan éxito o no.
Entregables:
Informe de ejecución de la prueba con el resultado detallado por escenarios.
b)
Funcionalidad: Hacer una promesa de financiación
Como mecenas,
Quiero hacer una promesa de financiación
Para apoyar un proyecto artístico que considero interesante
Escenarios:
Escenario 1: Se añade el usuario como mecenas si se puede retener el saldo
Suponiendo que existe un proyecto con una recompensa de importe 50 €
Y que existe un usuario que tiene una tarjeta de crédito válida
Cuando el usuario hace una promesa de financiación por la recompensa anterior
Entonces se han retenido 50 € en el saldo de la tarjeta
Y el usuario forma parte de la lista de mecenas del proyecto que han aportado 50 €
Escenario 2: No se añade el usuario como mecenas si no se puede retener el saldo
Suponiendo que existe un proyecto con una recompensa de importe 50 €
Y que existe un usuario que tiene una tarjeta de crédito no válida
Cuando el usuario hace una promesa de financiación por la recompensa anterior
Entonces no se ha retenido ningún importe en la tarjeta
Y el usuario no forma parte de la lista de mecenas del proyecto
3.
a) Plan de pruebas de carga
Referencias: Documento de descripción de cargas esperadas, documento de arquitectura de hardware de producción.
Elementos de pruebas: Software de CrowdArt, funcionalidades de busca de proyectos, consulta de los detalles de un proyecto y promesa de financiación.
Riesgos: Principalmente, que la carga real posterior no se asemeje a la carga modelada en las pruebas.
Características que no se probarán: Las otras funcionalidades no incluidas explícitamente ni tampoco ningún otro aspecto que no sea la carga soportada. En particular, se comprobará que las respuestas recibidas durante las pruebas no son de error, pero no se comprobará que se devuelvan los datos correctos, puesto que no se quieren hacer pruebas funcionales.
Herramientas que se utilizarán:
  • Se usará JMeter para simular un gran número de usuarios concurrentes. Habrá que definir un script de pruebas o más y definir el número de clientes que queremos que ejecuten cada script de pruebas.

  • Se emplearán las herramientas de monitorización que sean necesarias por lo que respecta a consumo de hardware (CPU, memoria, entrada/salida, red, etc.)

Métricas que se recogerán:
  • En los nodos clientes de las pruebas, tiempos de respuesta, respuesta de error sí/no, número de peticiones realizadas por segundo de cada tipo y el resto de las métricas que recoja el software de pruebas utilizado.

  • En todos los nodos, porcentaje de CPU utilizado, porcentaje de memoria física empleada, tamaño de memoria de intercambio usado, ancho de banda de red utilizado (de subida y de bajada), through put de entrada/salida a disco usado.

Configuración:
  • Se creará un script de pruebas para simular un usuario que se conecta a CrowdArt, hace un par de buscas y consulta los detalles de un par de proyectos. En este script el usuario tardará más o menos tres segundos después de hacer una petición antes de hacer la siguiente.

  • Se creará otro script de pruebas para un usuario que hace más o menos lo mismo pero que finalmente decide hacer una promesa de financiación.

  • Se configurará que el 20% de los usuarios simulados ejecuten el script de pruebas B y el 80% ejecuten el A, dando por supuesto que estos porcentajes serán representativos de la carga real, puesto que no disponemos de esta información.

  • Se utilizarán datos de pruebas sintéticos (a falta de datos reales) para llenar la base de datos con volúmenes parecidos a los indicados en el documento de cargas esperadas.

  • Se seguirán varias etapas de pruebas:

    • Se simularán diez usuarios, uno en cada nodo de pruebas, que ejecutarán el mismo guión diez veces cada uno. El objetivo es comprobar que el entorno de pruebas funciona correctamente y que todo está a punto.

    • Se simulará un número de usuarios creciente desde diez hasta alcanzar los dos mil usuarios concurrentes, incrementando el número de usuarios a razón de diez usuarios adicionales cada segundo. Por lo tanto, en doscientos segundos se llegará a los dos mil usuarios. Una vez alcanzados los dos mil usuarios, se continuará la prueba durante un minuto. Cada usuario repetirá indefinidamente el mismo escenario y la proporción de usuarios que ejecuta cada escenario será la indicada.

Software y hardware que se utilizará:
  • Se empleará un entorno idéntico al descrito en el documento de arquitectura de hardware de producción para correr el software de CrowdArt.

  • Además, se emplearán diez nodos pequeños de nuestro proveedor de hardware como servicio en la nube para correr las pruebas (actuarán como clientes, simulando, cada uno, una décima parte de los clientes totales).

  • En los nodos clientes se utilizará JMeter para simular la carga ejercida por los usuarios.

Criterio de aceptación:
  • Durante la segunda etapa, se alcanzan los dos mil usuarios concurrentes, que ejecutan sus escenarios durante un minuto y, en global, un 98% de las respuestas tienen que ser correctas y con un tiempo de respuesta inferior a cinco segundos.

Criterio de cancelación:
  • Si la primera ronda de pruebas no resulta con el 100% de las respuestas correctas y con tiempo de respuesta inferior a dos segundos.

  • En cualquier momento, si el porcentaje de respuestas correctas y con tiempo de respuesta inferior a cinco segundos está por debajo del 90%, puesto que entendemos que el sistema ya no se recuperará.

b) Si se tratara de un plan de pruebas de estrés, habría que ejercitar el sistema en su límite. En nuestro caso, si no sabemos el límite, deberíamos encontrarlo y sobrepasarlo para ver cuál es y cómo se comporta el sistema cuando lo alcanza.
Para conseguir nuestro objetivo, podríamos cambiar la configuración para crear una única etapa de pruebas en la que el número de clientes crezca de forma indefinida. Se podría empezar por una cantidad inicial de dos mil clientes (que el sistema debería soportar sin problemas) y después hacerlos crecer paulatinamente (por ejemplo, a razón de cinco más cada segundo) para ver en qué punto el sistema decae.
El criterio de aceptación podría ser que, una vez caído el sistema, si se reduce su carga a un valor que este soporte (como por ejemplo, a doscientos usuarios concurrentes), el sistema vuelva a dar un 95% de respuestas correctas y con menos de cinco segundos de tiempo de respuesta antes de diez minutos, aunque se pierdan peticiones de los momentos en que la carga era superior a la soportada. Para ello, una vez encontrado el punto de caída del sistema, sería necesaria una tercera etapa, en la que la carga, después de alcanzar este punto y mantenerlo un rato, se reduce a doscientos usuarios concurrentes.
El criterio de cancelación sería que, en la tercera etapa, una vez reducida la carga, después de diez minutos el sistema continuase sin dar un 95% de respuestas correctas con un tiempo de respuesta de cinco segundos o menos.
Ejercicios de autoevaluación
1. La validación de requisitos consiste en asegurarnos de que los requisitos que hemos elegido para el producto que estamos desarrollando reflejan las expectativas de los stakeholders. Véase el apartado 1.
2. Un caso de error que podríamos detectar durante la validación de requisitos podría ser que un requisito que se ha documentado en realidad no fuera tal; es decir, que no fuera una propiedad deseada por ningún stakeholder, por ejemplo, porque los desarrolladores no han entendido qué quiere realmente el stakeholder. Véase el apartado 1.
3. La validación de requisitos. Véase el apartado 1.
4. La revisión de requisitos. Véase el subapartado 1.1. para una descripción completa de la técnica.
5. La verificación de los requisitos es el proceso mediante el cual verificamos que el sistema desarrollado cumple sus requisitos. Véase el apartado 2.
6. La verificación de requisitos. Véase el apartado 2.
7. Si el requisito no estaba correctamente identificado y documentado, la validación de requisitos nos habría permitido detectarlo. En cambio, si el requisito estaba correctamente identificado y documentado pero el software no lo satisfacía, la verificación de requisitos nos habría sido útil. Véanse los apartados 1 y 2.
8. El de componente (pruebas unitarias), el de un subconjunto del sistema (pruebas de integración) y el del sistema en su totalidad (pruebas de sistema). Véase el apartado 2.
9. Determinar si el comportamiento del sistema se adecua a los requisitos de los clientes (pruebas de aceptación), si el software satisface la especificación de requisitos documentada (pruebas de conformidad), si el sistema cumple los requisitos de rendimiento (pruebas de rendimiento), cómo se comporta el sistema en situaciones de carga extremas (pruebas de estrés) y determinar si el sistema continúa comportándose como lo hacía en pruebas anteriores después de efectuar cambios (pruebas de regresión). Véase el apartado 2.
10. La automatización de las pruebas del software resulta fundamental para poder asegurar la consistencia y la repetibilidad de los resultados. Véase el subapartado 2.2.
11. 1) Situar el sistema sometido aprueba en un estado conocido.
2) Ejercitar la funcionalidad que hay que probar.
3) Verificar el estado del sistema para comprobar que se corresponde con el estado esperado.
Véase el subapartado 2.2.1.

12. Los datos de pruebas reales tienen la ventaja de que nos ayudan a descubrir los datos “normales” para nuestro software. Como inconvenientes, podemos listar que hay que obtenerlos de un sistema competidor o de un prototipo (lo cual no siempre resulta posible) y que pueden contener datos de carácter personal que dificulten su libre uso. Véase el subapartado 2.2.4.
13. Cuando hemos probado todos los casos que se han considerado necesarios y el software ha superado todas las pruebas. Ved el subapartado 3.1.1.
14. Aportando pruebas de regresión automatizadas que facilitan la reestructuración del código. Ved el subapartado 3.1.1.
15. Hay que describir los escenarios en un lenguaje cercano al lenguaje natural, escribir el código de apoyo necesario para hacerlos ejecutables y refinarlos añadiendo, si es preciso, nuevos escenarios para contemplar casos que los stakeholders no tuvieron en cuenta. Ved el subapartado 3.2.2.

Glosario

acceptance test driven development m
Véase desarrollo dirigido por las pruebas de aceptación.
artefacto m
Objeto producido por el trabajo del ser humano. En el contexto de la ingeniería del software, cada uno de los documentos, modelos, programas, etc., que se generan como resultado del trabajo del ingeniero.
ATDD m
Véase desarrollo dirigido por las pruebas de aceptación.
BDD m
Véase desarrollo dirigido por el comportamiento.
behaviour driven development m
Véase desarrollo dirigido por el comportamiento.
completitud f
Propiedad de una especificación de requisitos por la cual enumera todos los requisitos de todos los stakeholders, define el comportamiento del sistema para todo tipo de entradas de datos y situaciones y, finalmente, etiqueta y referencia todas las tablas, figuras y diagramas del documento.
consistencia f
Propiedad de una especificación de requisitos por la cual ningún subconjunto de los requisitos enumerados entra en conflicto.
corrección f
Propiedad de una especificación de requisitos por la cual todos los requisitos que documenta son realmente requisitos, es decir, por la cual todos los requisitos enumerados son realmente necesidades que el sistema debe satisfacer.
criterio de aceptación m
Descripción de las condiciones por las cuales se decidirá si cierto requisito, por lo general una historia de usuario, se considera como satisfecho o no.
desarrollo dirigido por el comportamiento m
Técnica de desarrollo de software consistente en escribir a priori las pruebas de aceptación en un lenguaje que los stakeholders puedan entender pero que a la vez permita la automatización de las pruebas. Solo cuando se dispone de una prueba para una funcionalidad, se pasa a implementar dicha funcionalidad y, después, se utiliza la prueba para verificar la implementación.
en behaviour driven development
sigla BDD
desarrollo dirigido por las pruebas m
Técnica de desarrollo de software que se vale de las pruebas automatizadas como elemento central del proceso de desarrollo.
en test driven development
sigla TDD
desarrollo dirigido por las pruebas de aceptación m
Técnica de desarrollo de software consistente en aplicar la filosofía de TDD a las pruebas de aceptación: se escriben las pruebas de aceptación antes de implementar la funcionalidad del sistema y se usan para comprobar que lo implementado es correcto.
en acceptance test driven development
sigla ATDD
especificación f
Documentación del conjunto de requisitos que tiene que satisfacer el software.
inambigüedad f
Propiedad de una especificación de requisitos por la cual cada requisito enumerado tiene una única interpretación posible.
métrica f
Medida cuantitativa de cualquier propiedad del software, las pruebas o las especificaciones.
modificabilidad f
Propiedad de una especificación de requisitos por la cual la estructura y la redacción del documento permiten hacer cambios de manera fácil y consistente.
plan de pruebas m
Documento sobre el alcance, el enfoque y los recursos que se dedicarán a hacer las pruebas a lo largo del desarrollo de un proyecto.
prueba de aceptación f
Prueba cuyo objetivo es determinar si el sistema se adecua a los requisitos de los clientes y, por lo tanto, si estos aceptarán o no el sistema desarrollado. Por definición, pues, es una prueba de sistema.
prueba de conformidad f
Prueba cuyo objetivo es determinar si el objeto que se prueba cumple la especificación que tenemoso no.
prueba de corrección f
Prueba de conformidad.
prueba de estrés f
Prueba cuyo objetivo es ejercitar el sistema en el límite de su capacidad e incluso más allá para verificar su comportamiento bajo estas condiciones.
prueba de integración f
Prueba cuyo ámbito es un subconjunto del sistema. Se usa para verificar la integración entre varios componentes, seguramente ya probados de forma unitaria.
prueba de regresión f
Prueba cuyo objetivo es verificar que las modificaciones efectuadas en un sistema desde que se ejecutaron ciertas pruebas no han causado efectos no deseados y que el sistema continúa superando tales pruebas.
prueba de rendimiento f
Prueba cuyo objetivo es verificar que el sistema cumple los requisitos de rendimiento, como por ejemplo capacidad, volúmenes de datos o tiempos de respuesta.
prueba de sistema f
Prueba cuyo ámbito es el conjunto del sistema. Se puede considerar como una prueba de integración, pero con todos los componentes que forman el sistema ya integrados.
prueba funcional f
Prueba de conformidad.
prueba unitaria f
Prueba cuyo ámbito es el componente. Se prueba un componente de manera aislada del resto de los componentes del sistema.
refactoring m
Técnica disciplinada para reestructurar una base de código alterando la estructura interna sin cambiar el comportamiento externo; se usa para mejorar los atributos no funcionales del software.
requisito m
Condición exigida o necesaria para algo. En el campo de la ingeniería del software, necesidad o restricción que afecta a un producto de software que define las soluciones que son adecuadas (lo cumplen) y las que no (no lo cumplen) según esta necesidad o restricción. Una solución será adecuada si satisface todos los requisitos del sistema.
revisión f
Actividad llevada a cabo por un grupo de personas consistente en leer y analizar una especificación de requisitos buscando errores y problemas potenciales.
stakeholder m y f
Persona o entidad con un interés sobre el producto que estamos desarrollando.
TDD m
Véase desarrollo dirigido por las pruebas.
test driven development m
Véase desarrollo dirigido por las pruebas.
trazabilidad f
Propiedad de una especificación de requisitos por la cual cada requisito enumerado está claramente identificado y facilita la referencia en los artefactos desarrollados a lo largo del proyecto, ya sean otros documentos, el software, las pruebas, etc.
validación f
Proceso mediante el cual se comprueba que los requisitos seleccionados representan efectivamente las necesidades de los stakeholders y, por lo tanto, son los requisitos correctos.
verificabilidad f
Propiedad de una especificación de requisitos por la cual para cada requisito que enumera hay un proceso finito y de coste efectivo con el fin de determinar si el software satisface el requisito o no.
verificación f
Proceso mediante el cual se comprueba que el sistema desarrollado cumple sus requisitos.

Bibliografía

Bibliografía principal
Varios autores (2004). SWEBOK. Software engineering body of knowledgeguide. IEEE ComputerSociety. [En línea, última visita: febrero 2012].
Esta obra recoge el corpus de conocimiento (es decir, aquellas ideas que son ampliamente aceptadas en la industria) de la ingeniería del software. Se puede consultar en la dirección <https://www.computer.org/portal/web/swebok/htmlformat>.
Adzic, Gojko (2011). Specification by example: How successful teams deliver the right software. ManningPublications.
IEEE-SAStandardsBoard (1998). I EEE Std 830-1998 –Standard for software test documentation. IEEE ComputerSociety.
Bibliografía complementaria
Hunt, Andrew; Thomas, David (1999). Thepragmaticprogrammer: Fromjourneyman to master. Addison-Wesley Profesional.
Wynne, Matt; Hellesøy, Aslak (2011). The Cucumber Book – Behaviour-driven development for testers and developers. ThePragmatic Bookshelf.
Referencias bibliográficas
Adolph, Steve; Bramble, Paul; Cockburn, Alistair; Pols, Andy (2003). Patterns for Effective Use Cases. Addison Wesley.
Adzic, Gojko (2010). Anatomy of a Good Acceptance Test. [En línea: última visita: febrero 2012]. <https://gojko.net/2010/06/16/anatomy-of-a-good-acceptance-test/>
Fowler, Martin; Beck, Kent (1999). Refactoring: Improving the design of existing code. Addison-Wesley Profesional.
North, Dan (2006). Introducing BDD. [En línea: última visita: febrero 2012]. <https://dannorth.net/introducing-bdd/>
Varios autores (n.d.). Directriz: Effective Requirement Reviews. [En línea, última visita: febrero 2012]. <https://epf.eclipse.org/wikis/openupsp/openup_basic/guidances/guidelines/effective_req_reviews,_E-dPIL-GEdqb7N6KIeDL8Q.html>