miércoles, 14 de diciembre de 2011

Gestión "Ágil" de Requisitos

Esta es la tan recurrida imagen usada para explicar la motivación de la Ingeniería de Requisitos. Es simplemente una exageración de lo que puede ocurrir en términos de degradación de una especificación cuando es transferida y manipulada secuencialmente entre diferentes participantes en un proyecto. En el contexto del desarrollo de un producto software esto tiene mayor probabilidad de ocurrir mientras más secuencial sea el proceso de desarrollo, mientras más personas distintas intervengan en la cadena de producción y mientras menos puntos de validación se establezcan (validación se refiere a comprobar que el producto satisface las expectativas del cliente, es decir, cumple con los requisitos acordados con el cliente).

La solución de la Ingeniería de Requisitos clásica está centrada en la especificación y validación temprana del producto. Por temprana me refiero a antes de programar :-). Esta validación tiene así un gran inconveniente, el cliente no validará respecto de un producto construido sino que lo más real o cercano que tendrá serán prototipos. Esto es así porque la Ingeniería de Requisitos tradicional en general asume un proceso en cascada, en el cual las actividades de análisis o especificación de requisitos coinciden con un período del proyecto, lo cual se delata cuando se denomina "Fase" de Análisis o similar.

La situación es bastante diferente cuando el modelo de proceso es iterativo e incremental, modelo en el cual se basan todas las propuestas metodológica modernas (sean ágiles o tradicionales). Sin embargo, se suele asociar a las metodologías tradicionales con un modelo de proceso en cascada porque desafortunadamente en muchos casos se aplican de esta forma. En un proceso iterativo e incremental el trabajo de desarrollo se divide ítems los cuales se agrupan en iteraciones (sprints), cuyo resultado es un incremento del producto que incluye cambios respecto de la versión previa. La actividad de especificación de requisitos está presente en cada uno de los ítems de trabajo, y  convenientemente se podría realizar en cualquier momento antes de pasar el ítem a una iteración para ser implementado. La especificación de requisitos no se debería concentrar en un período del proyecto, es decir, no habría una "fase de Especificación de Requisitos", sino más bien la actividad Especificación de Requisitos se realiza continuamente preparando ítems antes de que se implementen en una iteración. Así pues, los ítems que se incluyen en una iteración deberían estar idealmente ya definidos (especificados sus requisitos). Pues bien estos ítems en métodos ágiles corresponden usualmente con las denominadas Historias de Usuario. Aunque la literatura respecto de Historias de Usuario está un tanto sesgada respecto de asociar una Historia de Usuario con un "Nuevo Requisito", lo cierto que en el contexto de una iteración las Historias de Usuario también pueden representar "Mejoras" o incluso "Correcciones de fallos" en requisitos ya implementados.

El reconocer dichos diferentes tipos de Historias de Usuario ("Nuevo Requisito", "Mejora" o "Corrección de fallo") nos lleva directamente a entrar en "Gestión de Requisitos". La especificación de requisitos no es estática, va evolucionando en la medida que el comportamiento del producto lo hace. Es en este punto en el cual los métodos ágiles "renuncian" a la gestión de los requisitos una vez implementados en el producto. Con esto me refiero a que una vez que una Historia de Usuario (del tipo que sea) se implementa en una iteración, simplemente se tira a la papelera su especificación, o si se guarda, es sólo por una cuestión de registro histórico. Es decir, el comportamiento asociado a un requisito implementado y posteriormente mejorado o corregido debe averiguarse yendo directamente al código y la base de datos. No me consta que en alguno de métodos ágiles más populares se proponga almacenar y gestionar las Historias de Usuario ya implementadas con el propósito de servir de especificación actual del comportamiento del producto, puesto que de ser así debería realizarse algún tipo de síntesis de todas las Historias de Usuario asociadas a un requisito, desde su origen hasta la actualidad, pasando por todas sus mejoras y correcciones (no solo tener una colección de pos-it :-) ).

El tener que acudir al código y base de datos para conocer el comportamiento actual del producto podría no ser un gran problema si todo el equipo se desenvuelve a nivel de programación, pero muchas veces esto no ocurre. Además, el mismo cliente querría saber con precisión el comportamiento del producto. Ojo que dicha precisión no suele ser ofrecida por un Manual de Usuario, porque un manual debe orientar a un usuario para sacarle provecho al producto, no es su propósito describir en detalle la lógica asociada a cada funcionalidad del producto. Sin embargo, en mi opinión el disponer de una especificación de requisitos actualizada y más abstracta que la implementación se hace más necesaria aún cuando la envergadura o complejidad del producto es significativa, cuando difícilmente un miembro del equipo es capaz de conocer toda la funcionalidad del producto ni puede fácilmente investigar en código el impacto de los cambios.

Podríais pensar que después de lo comentado voy a apostar por gestión de requisitos "clásica", pues no! :-), ya que tampoco la gestión de requisitos clásica (en mi opinión) aborda de forma satisfactoria la evolución de la especificación de requisitos. Preguntadle a quienes utilizan Casos de Uso y Matrices de Trazabilidad si consiguen de manera efectiva y eficiente (a un costo razonable) mantener actualizadas sus especificaciones de requisitos :-). Si respondieran que están satisfechos sospecharía que no utilizan un proceso iterativo e incremental, o que tienen la suerte de desarrollar software en un contexto donde no hay cambios en los requisitos durante la construcción del producto, o donde el producto no tiene mantenimiento. Dicho contexto no creo que exista, al menos para un producto que tiene usuarios aprovechándolo.

Llegados a este punto no os voy a dejar sin una propuesta de solución :-), que sea factible y coherente con los métodos ágiles. En nuestro caso, desde que comenzamos a experimentar y aplicar métodos ágiles nos dimos cuenta del potencial que tenían las Pruebas de Aceptación (PAs) como especificación de requisitos, XP ya proponía derivar PAs para cada Historia de Usuario y utilizarlas como criterio de éxito de su implementación. En realidad la idea ya existía y es en sí el concepto de PA de toda la vida :-). Después de ver cómo en la medida que queríamos ser precisos en la descripción de una Historia de Usuario en su texto comenzaba a incluirse la lógica que debería derivarse posteriormente en términos de PAs. Así, resultó evidente que en lugar de hacer descripciones "novelescas" para Historias de Usuario era mejor escribir ese detalle directamente como PAs. De esta forma, para cada ítem de trabajo en una iteración, sea del tipo que sea (nuevo requisito, mejora o corrección), establecemos una descripción muy breve (y opcional), hacemos bocetos de interfaz cuando corresponde y básicamente nos centramos en definir PAs (incluso a veces, y puntualmente, utilizamos modelos). Con esta estrategia estamos "matando dos pájaros de un tiro", conseguimos un adecuado nivel de precisión en la definición de la Historia de Usuario y evitamos que posteriormente se tenga que hacer una interpretación adicional para extraer las PAs para poder realizar dichas pruebas. Pero esto solo es una parte, pues además teníamos que facilitar la gestión de los requisitos ante los cambios. En nuestro enfoque donde los requisitos están basados en PAs, para cada producto se establece una  estructura de grafo cuyos nodos representan requisitos, siendo cada uno de ellos un contenedor de PAs que definen el comportamiento del requisito. Así pues la gestión de requisitos se integra en el desarrollo iterativo e incremental de forma natural de la siguiente forma: cada ítem (Historia de Usuario) de una iteración se define como un cambio en la estructura de requisitos, con lo cual cada ítem puede implicar añadir, eliminar o modificar nodos, y correspondientemente añadir, modificar o eliminar PAs en dichos nodos. A nuestro enfoque lo denominados Test-Driven Requirement Engineering (TDRE) y está descrito en detalle en un artículo que publicamos en las JISBD en el 2010. El resto de la historia y los detalles corresponden a cómo hemos hecho realidad esta propuesta ofreciendo un soporte para ella en nuestra herramienta TUNE-UP Process. En el siguiente enlace puedes ver algunos ejemplos de pruebas de aceptación gestionadas en el contexto de un producto software como esencia de la especificación de requisitos.

En resumen, en mi opinión la única forma viable de gestionar los requisitos en un producto que está en continuo cambio (por estarse desarrollando iterativamente o por estar en mantenimiento) es que dicha gestión de requisitos esté totalmente integrada en la gestión del producto (en su planificación y desarrollo iterativo e incremental). Además, identificar y definir progresivamente las PAs de un cambio como parte esencial de la correspondiente especificación de requisitos resulta más rentable que invertir esfuerzo en otras formas de especificación detallada, pues de partida nos ahorra el esfuerzo de derivar PAs desde esas otras especificaciones.

Lectura recomendada: un post relacionado con este ¿Cuál y cuánta documentación/especificación es suficiente?.


Patricio Letelier

linkedin.com/in/letelier
agilismoatwork.blogspot.com
www.tuneupprocess.com




1 comentario:

  1. Letelier como siempre soy fan de tus post.
    Llevo un tiempo desarrollando una propuesta metodológica que busca mezclar de todo un poco que pueda ser útil y más que nada flexibilizar sin perder el enfoque de calidad, muchas de las prácticas las tomé de tu lista de prácticas ágiles a la carta.

    En estos dos artículos dejo claro como coincido contigo y planteo dos especificaciones de requisitos.

    1. Sería la historia de usuario que nos permite interactuar con el usuario y clientes: https://metodologiadac.blogspot.com/2017/03/plantilla-de-especificacion-de.html
    2. Sería la especificación o caso de uso detallado para el equipo de desarrollo: https://metodologiadac.blogspot.com/2017/03/plantilla-de-especificacion-de-requisitos2.html

    Esta segunda especificación sirve a la vez para hacer pruebas funcionales y para implementar por lo que está dirigida a programadores y tester.

    Además de que la memoria histórica de las historias de usuario (Almacenadas en el documento ERS) se lleva en la línea base de cada versión liberada.

    Me quedo con lo de las PAs pues no lo he incluido aun y voy a tener en cuenta tus planteamientos.

    ResponderEliminar