jueves, julio 12, 2007

Usando Confluence wiki para documentar en forma agil


Gestionar los requisitos de un proyecto no es tarea fácil. ¿Pero no es fácil por la complejidad de obtenerlos o la de documentarlos? Son dos caras de una misma moneda y en definitiva la buena gestión de ambas tareas hará que el proyecto salga adelante con éxito o no.
Para obtenerlos hay muchas metodologías, tantas como gustos. Quizás RUP sea la mas conocida en proyectos grandes y las variantes de Agile para proyectos mas pequeños. Pero cualquiera sea la metodología elegida del proyecto, y por lo tanto de como gestionar los requisitos, las herramientas para documentar son un poco mas que penosas.
El rey de las herramientas de requisitos, RequisitePro es una arcaica mezcla de MS Word y aplicación propietaria, junto con una herramienta de reportes (SODA) en MS Word. Nada ágil por cierto. Quizás con el nuevo desarrollo Jazz todo mejore para Rational, pero para eso faltan no menos de 2 años. ¿Que nos queda entonces para documentar los requisitos? Quizás Enterprise Arquitect sea bueno para esto, pero sigue siendo un cliente pesado.
¡Bienvenidos a la web entonces! Quizás el actual sistema de documentación distribuído mas popular de estos días sea la wikipedia, por que no documentar entonces un proyecto en un wiki? El primer pensamiento en contra es por lo "desestructurada" que suele ser la información guardada en un wiki, pero alguas herramientas nos permiten agregar control sobre los formularios de entrada y edición de datos. XWiki es un ejemplo de ello, pero el ejemplo que nos ocupa hoy está desarrollado con Confluence y una serie de plugins disponibles para esta plataforma.

Paso 1. Crear plantilla de doucmento Cliente.
primero crearemos una plantilla para contener los datos de los clientes, de los cuales, por simplicidad, solo guardaremos el nombre. Para ello deberemos ir a "Browse Space/Advanced/Templates/Add New Space Template" y agregar el siguiente código bajo el nombre "Client":



| Nombre: | {page-info:title} |

{report-table}
{content-reporter:spaces=@self|type=page|scope=@self > children}
{text-sort:content:title|order=ascending}
{text-filter:data:FormName|include=Project}
{content-reporter}
{report-column:title=Nombre}{report-info:content:title|link=true}{report-column}
{report-column:title=Project Leader}{report-info:data:ProjectLeader|link=true}{report-column}
{report-column:title=Start Date}{report-info:data:StartDate|link=true}{report-column}
{report-column:title=End Date}{report-info:data:EndDate|link=true}{report-column}
{report-column:title=Status}{report-info:data:Status|link=true}{report-column}
{report-table}
(+) {add-page:template=Project|live=true}Agregar proyecto{add-page}

{set-data:FormName|hidden=true}Client{set-data}


En esta plantilla vemos una tabla con el título del documento, un reporte de proyectos y un link para agregar un nuevo proyecto. Por último el tag {set-data}, del plugin Scaffolding, nos permite identificar este documento con la propiedad "FormName=Client", lo que nos facilitará los reportes de clientes que querramos hacer.

Paso 2. Crear documento raíz.
Luego necesitamos una página en algún lugar de nuestro wiki, que contenga el listado de clientes. Para el listado utilizaremos el plugin Reporting:



{report-table}
{content-reporter:spaces=@self|type=page|scope=Clients > children}
{text-sort:content:title|order=ascending}
{content-reporter}
{report-column:title=Nombre}{report-info:content:title|link=true}{report-column}
{report-table}

(+) {add-page:template=Client|live=true}Agregar cliente{add-page}


Al final de la página se puede ver el tag {add-page} para crear documentos de tipo cliente mediante una plantilla previamente creada. Luego de salvar la página con el título "Clients", podemos agregar un cliente:

Paso 3. Agregar un cliente.


Lo que nos presentará un documento a crear en base a la plantilla "Client":



Que luego de salvarlo tendrá la siguiente apariencia:



Paso 4. Crear plantilla de proyecto
Análogamente, para crear un proyecto deberemos crear primero una plantilla, con título "Project":

| Nombre: | {page-info:title} |
| Cliente: | {report-link:content:parent > content:url}{report-info:key=content:parent}{report-link} |
| Codigo JIRA | {text-data:JiraCode|content=text|width=100px}{text-data} |
| Project Leader: | {list-data:ProjectLeader|required=true}
{user-options:groups=confluence-users}
{list-data} |
| Team Members: | {list-data:TeamMembers|type=check|multiple=true}
{user-options:confluence-users}
{list-data} |
| Start Date: | {date-data:StartDate|format=dd-MMM-yyyy}today{date-data} |
| End Date: | {date-data:EndDate|format=dd-MMM-yyyy}{date-data} |
| Status: | {list-data:Status}
{list-option}Unstarted{list-option}
{list-option}In progress{list-option}
{list-option}Awaiting approval{list-option}
{list-option}Completed{list-option}
{list-data} |

[Requerimientos|Requirements]
[Casos de Uso|UseCases]
[Iteraciones|Iterations]
[Actas de Reunión|MeetingMinutes]
[Informes de estado de proyecto|StatusReports]

{set-data:FormName|hidden=true}Project{set-data}


Esta plantilla tiene los datos propios del proyecto, incluyendo su project leader, participantes, fecha de inicio y fin y estado. Al final también hay links a los documentos que harán de padres de los requisitos, las iteraciones y todos los demás documentos que nuestra metodología requiera.

Paso 5. Crear un proyecto.
Luego de creada la plantilla de proyecto podremos crear proyectos, mediante el link en el formulario correspondiente al cliente:



Lo cual nos preguntará el título del proyecto, y luego los datos que especifica la plantilla correspondiente:



Que una vez salvada tendrá la siguiente apariencia:



Paso 6. El listado de requierimientos.
Queda como ejercicio resolver que cada proyecto contenga su propia lista de requerimientos, ya que como ven en la plantilla de proyecto el link a los requerimientos es a una página genérica, llamada "Requirements": [Requerimientos|Requirements]. La mejor posibilidad es utilizar un "space" para cada proyecto.
Pero vamos con el diseño de la plantilla de la citada página padre "Requirements":

h3.Requerimientos Funcionales

{report-table}
{content-reporter:type=page|scope=@self > children}
{text-sort:data:Date|order=ascending}
{text-filter:data:FormName|include=Requirement}
{text-filter:data:Type|include=Funcional}
{content-reporter}
{report-column:title=Título}{report-info:content:title|link=true}{report-column}
{report-column:title=Estado}{report-info:data:State}{report-column}
{report-column:title=Prioridad}{report-info:data:Priority}{report-column}
{report-column:title=Dueño}{report-info:data:Owner}{report-column}
{report-column:title=Creado}{report-info:content:creation date}{report-column}
{report-column:title=Creado por}{report-info:content:creator}{report-column}
{report-table}

h3.Requerimientos No Funcionales
{report-table}
{content-reporter:type=page|scope=@self > children}
{text-sort:data:Date|order=ascending}
{text-filter:data:FormName|include=Requirement}
{text-filter:data:Type|include=No Funcional}
{content-reporter}
{report-column:title=Título}{report-info:content:title|link=true}{report-column}
{report-column:title=Estado}{report-info:data:State}{report-column}
{report-column:title=Prioridad}{report-info:data:Priority}{report-column}
{report-column:title=Dueño}{report-info:data:Owner}{report-column}
{report-column:title=Creado}{report-info:content:creation date}{report-column}
{report-column:title=Creado por}{report-info:content:creator}{report-column}
{report-table}

(+) {add-page:template=Requirement|live=true}Agregar requerimiento{add-page}


Se ha dividido la página en requerimientos funcionales y no funcionales, pero eso es a gusto del consumidor. Lo que hay que saber es que esta página lista los documentos de tipo "Requirement", creados a su vez con la plantilla "Requirement":

Paso 7. El formulario de requirimientos:

{section}
{column:width=300px}

*Detalles*
{table:width=300px}

{table-row}
{table-cell}
Tipo:
{table-cell}
{table-cell}
{list-data:Type|required=true}
{list-option}Funcional{list-option}
{list-option}No Funcional{list-option}
{list-data}
{table-cell}
{table-row}
{table-row}
{table-cell:width=100px}
Prioridad:
{table-cell}
{table-cell:width=200px}
{list-data:Priority}
{list-option}Sin asignar{list-option}
{list-option}Alta{list-option}
{list-option}Media{list-option}
{list-option}Baja{list-option}
{list-data}
{table-cell}
{table-row}
{table-row}
{table-cell:width=100px}
Estado:
{table-cell}
{table-cell:width=200px}
{list-data:State}
{list-option}Propuesto{list-option}
{list-option}Rechazado{list-option}
{list-option}Aprobado{list-option}
{list-option}Diferido{list-option}
{list-data}
{table-cell}
{table-row}
{table-row}
{table-cell}
Dueño:
{table-cell}
{table-cell}
{list-data:Owner|required=true}{user-options:groups=confluence-users}{list-data}
{table-cell}
{table-row}

{table}

{column}
{column:width=90%}
*Descripción*
{text-data:Description|type=area|content=wiki|width=100%|height=500px}
{column}

{section}

{set-data:FormName|hidden=true}Requirement{set-data}


El resultado es un formulario:



Y un listado de todos requerimientos:



Finalmente, queda por decir que el plugin para Graphviz nos permite hacer diagramas sin salir del wiki (ver UML class diagrams in Confluence using Graphviz and DOT), lo que aumenta varios grados la agilidad de la documentación y permite gráficos como este:

3 comentarios:

raul dijo...

Has tardado mucho en escribir, haber si te prodigas mas.

Un abrazo Raul

Anónimo dijo...

Hola,

No puedo por menos que agradecerte el trabajo que has realizado. El documento me ha ayudado mucho a empezar con la gestión de proyectos en Jira.

Ahora voy a aportar mi granito de arena:

- En mi opinión un espacio por proyecto no es necesario ya que los requerimientos son hijos de cada proyecto y son del tipo requirements con lo que ya quedan suficientemente acotados para la herramienta Reporter.

- Para que los ejemplos que pones funcionen adecuadamente, además de:

* Graphviz Plugin de Atlassian Software Systems and other contributors
* Reporting Plugin de CustomWare Asia Pacific
* Scaffolding Plugin de CustomWare Asia Pacific

como indicas, hay que instalar también:

* Content Formatting Macros de Adaptavist.com Ltd
* Linking Plugin de CustomWare Asia Pacific
* Page Information Tools de Adaptavist.com Ltd

- Y ahora unos pequeños bugs en el documento:

(+) {add-page:template=Requirement|live=true}Agregar requerimiento{add-page}

debería ser

(+) {add-page:template=Requirements|live=true}Agregar requerimiento{add-page}

si es que has llamado Requeriments a la plantilla como dices en tu documento.

Aparte, la plantilla de proyecto la he juntado con la primera de requerimientos que has escrito para unificar (y así no necesitar un espacio por proyecto). Quedaría de la siguiente forma:

| Nombre: | {page-info:title} |
| Cliente: | {report-link:content:parent > content:url}{report-info:key=content:parent}{report-link} |
| Codigo JIRA | {text-data:JiraCode|content=text|width=100px}{text-data} |
| Project Leader: | {list-data:ProjectLeader|required=true}
{user-options:groups=confluence-users}
{list-data} |
| Team Members: | {list-data:TeamMembers|type=check|multiple=true}
{user-options:confluence-users}
{list-data} |
| Start Date: | {date-data:StartDate|format=dd-MMM-yyyy}today{date-data} |
| End Date: | {date-data:EndDate|format=dd-MMM-yyyy}{date-data} |
| Status: | {list-data:Status}
{list-option}Unstarted{list-option}
{list-option}In progress{list-option}
{list-option}Awaiting approval{list-option}
{list-option}Completed{list-option}
{list-data} |

h3.Requerimientos Funcionales
{report-table}
{content-reporter:type=page|scope=@self > children}
{text-sort:data:Date|order=ascending}
{text-filter:data:FormName|include=Requirement}
{text-filter:data:Type|include=Funcional}
{content-reporter}
{report-column:title=Título}{report-info:content:title|link=true}{report-column}
{report-column:title=Estado}{report-info:data:State}{report-column}
{report-column:title=Prioridad}{report-info:data:Priority}{report-column}
{report-column:title=Dueño}{report-info:data:Owner}{report-column}
{report-column:title=Creado}{report-info:content:creation date}{report-column}
{report-column:title=Creado por}{report-info:content:creator}{report-column}
{report-table}

h3.Requerimientos No Funcionales
{report-table}
{content-reporter:type=page|scope=@self > children}
{text-sort:data:Date|order=ascending}
{text-filter:data:FormName|include=Requirement}
{text-filter:data:Type|include=No Funcional}
{content-reporter}
{report-column:title=Título}{report-info:content:title|link=true}{report-column}
{report-column:title=Estado}{report-info:data:State}{report-column}
{report-column:title=Prioridad}{report-info:data:Priority}{report-column}
{report-column:title=Dueño}{report-info:data:Owner}{report-column}
{report-column:title=Creado}{report-info:content:creation date}{report-column}
{report-column:title=Creado por}{report-info:content:creator}{report-column}
{report-table}

(+) {add-page:template=Requirements|live=true}Agregar requerimiento{add-page}

[Casos de Uso|UseCases]
[Iteraciones|Iterations]
[Actas de Reunión|MeetingMinutes]
[Informes de estado de proyecto|StatusReports]

{set-data:FormName|hidden=true}Project{set-data}

Me queda por implementar los casos de uso, iteraciones, etc. Pero con esta guía que te has currado será facilísimo. Espero que mis aportaciones también sirvan de ayuda. Un saludote!

Anónimo dijo...

He vuelto a releer el documento y el bug del documento que he descrito acerca de cambiar Requeriment por Requieriments no es más que una mala interpretación por mi parte que se me coló al unir las dos plantillas. El bug es mío así que disculpadme y un saludo!