martes, 18 de marzo de 2014

Gestión ágil de requisitos o ¿cuál y cuánta documentación/especificación es suficiente?

En el 2005 Alan Davis, un reconocido gurú de la ingeniería de requisitos (en su enfoque tradicional), publicó su libro "JERM: Just Enough Requirements Management". Cuando por esos años este libro cayó en mis manos yo llevaba ya unos cinco años experimentando con métodos ágiles . El mensaje del libro, claramente reflejado en su título, fue para mí la confirmación respecto a que la ingeniería de requisitos ágil conlleva un cambio de chip importante, pero que también es más complejo que la ultra simplificación y entusiasmo asociado a especificar requisitos al estilo "Como [usuario] quiero [funcionalidad] para [beneficio]", ... sí me refiero a las Historias de Usuario :-).

La cuestión clave que nos gustaría poder responder es cómo y con cuánto detalle deben establecerse los requisitos. La respuesta obvia es "depende", pero se trata además de un "depende" a nivel de requisito, no de tipo, tamaño o cualquier otra clasificación global a nivel de sistema. Un requisito bien especificado es aquel que el cliente es capaz de validarlo y aquel que el equipo es capaz de entenderlo para implementarlo y probarlo. Según esto también deberíamos considerar la experiencia y conocimientos del equipo, lo cual en una situación favorable podría hacer que se necesite menos detalle en la especificación del requisito. Además, la complejidad o innovación asociada al requisito podría aconsejar hacer su implementación de forma incremental, así la especificación también podría hacerse incrementalmente. Finalmente, en cuanto a cómo especificar un requisito, disponemos de múltiples alternativas: texto narrativo, plantillas, diagramas (UML u de otro tipo), métodos formales, etc., cualquiera de estas alternativas puede ser útil, y por supuesto, también podrían usarse mezclas de ellas.

Según lo anterior, lo que incomoda es no tener una respuesta global, y tener que decidir ese "cómo y cuánto" de la especificación de cada requisito, uno por uno, y quizás con diferentes estrategias. Sin embargo, es precisamente así como se consigue la máxima eficacia y eficiencia; ajustando la estrategia a las necesidades de cada requisito.

Veamos un ejemplo muy sencillo. El siguiente formulario implementa la funcionalidad "Registro de nuevo usuario" en facebook. En términos de requisito clásico probablemente hubiésemos establecido este requisito como un Caso de Uso con el mismo nombre. Si bien la granuralidad típica de una Historia de Usuario tiende a ser más pequeña que la usual en Casos de Uso, aquí por tratarse de una funcionalidad ya de por sí "pequeña" podría también coincidir con una Historia de Usuario, al estilo, "Como [Usuario No Registrado] quiero [Registrarme en facebook] para [Disponer de un espacio en la red social]". Pero independiente de la granuralidad escogida, si nos centramos en lo importante, es decir, qué debería especificarse para poder llegar a una implementación final como la mostrada en este formulario de registro, ¿cuál sería la mínima especificación que podría validar un cliente y a la vez implementar y probar un equipo?.


Una situación extremamente positiva sería la siguiente. Si ya hubiésemos implementado esta funcionalidad en otro sistema, o si en nuestro contexto esta funcionalidad ya viene dada (por ejemplo como parte del framework de desarrollo) y coincide con las necesidades del cliente, es estos casos ni siquiera sería necesario especificar más que el nombre del requisito, probablemente el único trabajo adicional sería configurar dicha funcionalidad y/o integrarla.

Supongamos ahora una situación en la cual dicho formulario habría que desarrollarlo. ¿qué es lo mínimo que deberíamos acordar con el cliente y especificar para que el equipo puede implementarlo y probarlo?.

Ojo! que cuando digo "especificar", cabe la posibilidad que se trate simplemente de una conversación, es decir, que no esté plasmado en una ficha o documento.

Básicamente, para cualquier requisito como el del ejemplo sería conveniente conocer:
  • Lo elementos que se visualizarán y el formato de los valores mostrados (que no sean obvios)
  • Los valores por defecto que puedan necesitar los elementos de entrada de datos
  • Los elementos de entrada de datos que permiten valor nulo
  • Los elementos habilitados o deshabilitados según cierto estado del sistema
  • La lógica asociada a cada una de las interacciones posibles con la página o formulario
En el caso concreto del formulario de registro antes mostrado, en algún momento se llegaría a acordar/especificar aspectos tales como (me los he inventado :-)):
  • El formulario de registro incluye nombre, apellidos, email (introducido en dos campos), contraseña, fecha de nacimiento y sexo. (Además, se podría adjuntar un boceto ilustrando la disposición de los campos y etiquetas asociadas).
  • Ningún campo permite valor nulo.
  • Al lado de la fecha de nacimiento hay un enlace para acceder a la explicación de por qué se solicita esta información.
  • El sexo es un grupo de botones de radio, sin valor por defecto.
  • Sobre el botón de registro se muestra un texto que permite acceder a las Condiciones del registro, la Política de uso de datos  y al Uso de cookies.
  • La contraseña debe cumplir la política de contraseña segura (esta política se supone conocida)
  • La fecha se introduce con año, mes y día, en campos separados y como un alista de valores
  • Al salir de un campo, éste de verifica inmediatamente y en caso de no cumplir con las restricciones establecidas se indicará con un símbolo de exclamación y un mensaje explicativo. 
  • No se permite que el email coincida con uno ya registrado
  • El valor de los dos campos de email deben coincidir 
  • La fecha de nacimiento no puede ser mayor que la fecha actual ni más de 120 años atrás.
  • Al presionar el botón Registrar y cumpliéndose todas las restricciones del formulario se enviará un email con un enlace para activar la cuenta.
  • Si se realiza la activación de la cuenta, el usuario puede acceder a una cuenta nueva usando su email y contraseña. 
  • El enlace caduca después de un día, y en este caso el registro se cancela.
  • El formulario de registro se muestra en el idioma seleccionado por el usuario.  

¿Vale la pena acordar/especificar todo este detalle?. 

Esta funcionalidad es sencilla (comparada con otros requisitos de un sistema), además es una funcionalidad que no aporta valor al usuario (aunque es imprescindible), es decir, no está relacionada con la esencia de la aplicación (en este caso las funcionalidades que apoyan la interacción entre usuarios de la red social). Desde este punto de vista, este requisito debería ser discriminado en cuanto a prioridad de implementación y esfuerzo invertido. Podríamos, por ejemplo, ofrecer una propuesta ya hecha y confirmarla esperando refinamientos de manera informal (mediante conversación). Sin embargo, desde una perspectiva de pruebas, el detalle mostrado es exactamente el necesario a nivel de pruebas de aceptación (pruebas para demostrar que el sistema desde la perspectiva del usuario cumple con el comportamiento esperado). De hecho, si a cada una de las sentencias de la lista anterior le añadimos el prefijo "Comprobar que" tendríamos ya enunciadas las pruebas de aceptación de dicha funcionalidad.

Las especificaciones del software cambian, "todo producto software exitoso tendrá mantenimiento". Este es otro desafío que debe considerarse. En un extremo podríamos resignarnos a que, por ejemplo, si dicha especificación existe y se entrega con la primera versión puesta en producción, posteriormente no se actualiza. En este caso para el mantenimiento se irá directamente al código y BD para conocer el funcionamiento. En otro extremo, podríamos mantener siempre actualizada la documentación para ayudar al mantenimiento del sistema (con el esfuerzo que esto puede suponer), especialmente si el mantenimiento es intenso y la documentación, valga la redundancia, la forman documentos narrativos, de por sí no fáciles de modificar sin caer en inconsistencias. Las pruebas de aceptación constituyen una solución intermedia pues por un lado pueden describir en detalle el comportamiento del sistema, y por otro son más fáciles de gestionar que texto narrativo extenso o plantillas. Básicamente hacer mantenimiento de una documentación basada en pruebas de aceptación consiste en añadir, modificar o eliminar pruebas de aceptación. 

Aún siendo nuestro ejemplo un caso muy sencillo, nos ofrece pistas interesantes respecto de la especificación de requisitos, ellas son:
  • Al comienzo, la especificación podría ser informal, permitiendo comenzar la implementación, pero su posterior verificación mediante pruebas necesitará un mayor detalle, el cual podría aun no estar explícitamente escrito, pero que obviamente el encargado de testear lo agradecería :-). Un inconveniente a tener en cuenta en este caso es que quien realice la implementación podría no contar explícita y detalladamente con las pruebas que deberá cumplir su implementación, con lo cual estaremos asumiendo el riesgo asociado a que se produzca re-trabajo.  
  • La especificación mínima se corresponde con las pruebas de aceptación que comprobarán que el sistema se comporta según lo esperado (desde la perspectiva del usuario). Además, que la especificación se base esencialmente en pruebas de aceptación es rentable, se aprovecha para la implementación (cuando se definen antes), pero también en el momento de hacer el testeo de aceptación, pues ya están enunciadas y acordadas con el cliente.
  • La intensidad, el nivel de detalle, debe ser adaptable a las necesidades del requisito, y debe también considerar la experiencia del equipo de desarrollo.
  • Las pruebas de aceptación pueden ser una forma de documentación especialmente adecuada para sistemas con mantenimiento intenso y en los cuales se quiere mantener actualizada dicha documentación.  
Seguro que alguien estará pensando que estas reflexiones están en la línea de los enfoques ATDD (Acceptance Test Driven Development) y BDD (Behavior-Driven Development), ambos basados en pruebas de aceptación automatizadas. Sí, me parecen enfoques interesantes y coincidentes con la motivación de este post, sin embargo, no comparto el hecho que las pruebas necesariamente deban automatizarse, ni menos de forma tan temprana cuando recién se están generando los requisitos. Tampoco comparto el hecho que "a golpe" de pruebas de aceptación se vaya estableciendo la implementación, me parece más adecuado que esto se haga por áreas, por conjuntos de pruebas de aceptación. Finalmente, no he visto en dichos enfoques mecanismos adecuados para gestionar grandes volúmenes de pruebas de aceptación y que faciliten por ejemplo su organización, su localización, su no duplicación, etc.

En Extreme Programming (XP) las pruebas de aceptación son protagonistas (existen como artefacto y el rol Tester es el encargado de acordarlas con el cliente), cada Historia de Usuario debería tener asociadas sus pruebas de aceptación, sin embargo, en XP no se aportan mayores pautas respecto de cómo establecerlas, ni mecanismos para gestionarlas. Por otra parte, ni Scrum, ni Kanban, ni Lean Development entran en aspectos asociados a la especificación de requisitos o pruebas de aceptación.

Desde hace años hemos venido desarrollando un enfoque propio, enmarcado en el ámbito de métodos ágiles, denominado Test-Driven Requirement Engineering (TDRE), el cual se detalla en un artículo que publicamos en las JISBD en el 2010. Además, nuestra herramienta TUNE-UP Process ofrece soporte específico para TDRE. En el siguiente enlace hay algunos ejemplos de pruebas de aceptación gestionadas por TUNE-UP Process.


No hay comentarios:

Publicar un comentario