lunes, 9 de noviembre de 2009

Herramientas para un grupo de trabajo

En este post quería dar mi opinión sobre las herramientas que un grupo de trabajo formado por varias personas debería tener en un desarrollo de software. Como no me gustan los posts demasiado genéricos voy a concretar en un desarrollo que o bien sea PHP o Java. También voy a dar los nombres de algunos productos para cada tipo de herramienta.

A modo de resumen algunas de las piezas que un grupo de trabajo debería tener son las siguientes:
  • Un framework. O bien uno desarrollado por la propia empresa o bien uno existente.
  • Un buen IDE (o RAD)
  • Un sistema de control de versiones
  • Un sistema de gestión de incidencias o bugs
  • Una wiki empresarial
  • Varios entornos de desarrollo: desarrollo, integración, preproducción y producción
  • Tests y un servidor de integración continua
Sin querer he hecho una ordenación de las herramientas a utilizar que quizás sea bastante acertada. Por partes.

Framework

La primera pregunta es, ¿qué es un framework? Seguro que hay muchas definiciones en Internet pero voy a tratar de explicarlo de otra forma. Una librería se podría decir que es un conjunto de ficheros de código que te ayudan a resolver un problema. Por ejemplo, una librería para enviar correos electrónicos como Java Mail o SwiftMailer o una librería para hacer peticiones HTTP como Apache HttpClient o curl. Estas librerías se pueden utilizar en proyectos muy diversos (aplicación web, aplicación de escritorio, líneas de comandos,...) y no imponen muchas restricciones en cuanto al proyecto en el que se usan. Su API suele ser lo más sencilla posible para que pueda incorporarse a cualquier programa. El problema que resuelven suele ser muy concreto y común en muchos proyectos.

¿Un framework entonces es una librería? No. un framework es mucho más. Además de aportar una serie de ficheros de código un framework impone una serie de normas para el proyecto donde se encuentra. Muchas veces un framework suele ser un conjunto de librerías como las mencionadas anteriormente más esa serie de normas. Algunos ejemplos posibles de normas:
- Para poder crear una nueva acción hay que crear un fichero con extension .class.php y añadir su definición a un fichero XML.
- Los parámetros de conexión con la base de datos tienen que ir en el fichero databases.xml que se encuentra en la carpeta conf
- Si se quiere definir un interceptor para las peticiones HTTP este interceptor tiene que implementar la interfaz ServletListener

Estas normas pueden tener sus ventajas y desventajas. Hay muchos críticos de los frameworks en general que rechazan la imposición de estas normas que hacen estricto el desarrollo y que reducen el peso que tiene un programador en el producto final.

Sin embargo me gustaría diferenciar el uso de los frameworks en el uso individual y en el uso en un grupo de trabajo. Bajo mi punto de vista considero fundamental el uso de un framework en un entorno de trabajo y sobretodo cuanto más grande sea este grupo. También importante para aquellas empresas que piensen que un futuro pueden ampliar su equipo de trabajo y que las nuevas incorporaciones pueden trabajar en proyectos anteriores. En las siguientes líneas voy a tratar de explicar el por qué.

Como bien he comentado anteriormente un framework impone una serie de normas. Estas normas lo que obligan finalmente es que un proyecto tenga una estructura estandard. Esto es muy importante pues los integrantes del grupo de trabajo saben donde hay que crear las clases, dónde definir la conexión con la base de datos, cómo interactuar con ella, dónde y cómo crear la mayor parte del código. No es necesario reinventar la rueda. Si pensais en un proyecto que hace 6 meses que no se toca y que un buen día tienes que retomar te darás cuenta de lo importante que es tener una estructura ya definida. Además los integrantes del grupo de trabajo no hace falta que se pongan de acuerdo con dicha estructura. Ya está creada. Y normalmente tiene muchos casos de éxito que denotan que funciona.

Además estos frameworks están muy documentados. Tres ejemplos serían J2EE, Symfony o Spring. Muchos de ellos inclusos con libros con más de 1000 páginas con todo lujo de detalles.

Y si un nuevo integrante tiene que entrar en el proyecto no es necesario que conozca una nueva forma de hacer las cosas cada vez. Está ahí en la documentación. Seamos sincerios, a los informáticos no nos gusta documentar. Por lo menos el framework ya tiene algo.


Un buen IDE o RAD

Todavía recuerdo mis primeras andaduras con los lenguajes de programación en la universidad. Pascal, C, C++, Python, LISP, Cobol... Quizás el peor recuerdo que tengo de todas ellas es tener que programar con Emacs o Vi. Por favor, eso es una tortura en toda regla.

Un IDE ahorra diariamente muchas horas de trabajo. Organiza todo el código, te permite hacer búsquedas en todos los ficheros del proyecto. Te permite ejecutar, debuggear, documentar, ejecutar scripts,... todo desde una misma herramienta. Además se integra con sistemas de control de versiones, sistemas de gestión de bugs,... Te permite arrancar y parar tus servidores de forma automática. Me hizo gracia una frase de Rafa Gaitán en los segundos encuentros de programadores Java que se celebraron en la Uji. Un IDE es como sistema operativo. Cuánta razón tiene.


Como he comentado un buen IDE es una herramienta clave para el desarrollo. Es como una navaja suiza que te simplifica tu trabajo diario. Al integrar todo lo necesario para el desarrollo aumenta la eficiencia y la eficacia de forma considerable.

Para Java y PHP recomiendo sin duda Eclipse. Llevo utilizando este IDE desde hace más de 7 años y estoy muy satisfecho. Se dio a conocer por su editor de Java integrado. Desde hace unos pocos años cuenta también con un editor de PHP, PDT. Debido a su plataforma modular se han desarrollado muchos plugins que permiten extender su funcionalidad. De hecho el editor de Java y el de PHP son plugins sobre la base de Eclipse (que se llama Equinox). Algunos de los plugins que recomiendo:
  • Sublicpse. Para utilizar subversion desde el propio editor
  • Eclipse Mylyn. Programación orientada a tareas. Te permite conectar Eclipse con sistemas de gestión de incidencias
  • Oxygen XML. Un editor XML con infinitas utilidades
  • MyEclipse: Un paquete con multitud de plugins para trabajar con J2EE, HTML, CSS, XML, bases de datos,...

Para .NET desde luego recomendaría Visual Studio.


Un sistema de control de versiones

Es un sistema que te permite guardar un historial de todos los cambios realizados al código fuente de un programa. Tiene dos funciones principales:
  • Mantener registro de cambios: Gracias a que se guardan todas las versiones de los ficheros es posible comparar un fichero con sus antiguas revisiones. Cuando se encuentran errores en la aplicación es muy común consultar las últimas versiones de cada fichero para averiguar cuándo se introdujo el error.
  • Sincronizar a un grupo de trabajo: Cuando es utilizado por más de una persona el uso de estos sistemas tiene un segundo propósito y es el de sincronizar los ficheros que forman el proyecto. Al estar todos los ficheros almacenados en un servidor común (además de la copia que tiene cada usuario en su máquina) el sistema de control de versiones permite que varios integrantes del grupo trabajen con los mismos ficheros. Realmente cada usuario trabaja con su copia local pero existe siempre una copia común a todos (la que está en el servidor). Al sincronizar sus ficheros locales con los del servidor se puede saber si ese fichero ha sido modificado o no por otro usuario, qué cambios introdujo dicho usuario y gracias a un buen editor, si los cambios introducidos por el usuario que va a subir los cambios entran en conflicto con los anteriores.


No quiero entrar en mucho más detalle en este post pero quien no esté muy familirizado con el uso de estos sistemas, después de aprender su funcionamiento básico, debería investigar el uso de ramas. Las ramas permiten tener varias versiones no de un fichero sino de un proyecto versionadas a la vez. Siempre hay una principal (o trunk) y tantas ramas como se quieran crear. Estas ramas te permiten seguir versionando tu código pero sin necesidad de que entre en conflicto con los ficheros principales. Esto es muy común cuando por ejemplo se desea incorporar al proyecto una funcionalidad pero no antes de incluirla definitivamente se quiere probar extensamente. Se abre una rama del proyecto, se trabaja con dicha rama, se hacen las pruebas, y cuando ya está todo afianzado se hace el merge de la rama con la rama principal.

Hay varios sistemas de control de versiones. El primer gran conocido fue CVS, seguido por Subversion. Estos sistemas se instalan en un único servidor. Ahora se tiende a sistemas de control de versiones distribuidos como git pero no es el propósito de este post.

Eclipse cuenta con varios plugins para CVS y Subversion. De Subversion recomendaría Subclipse. Todos estos plugins te permiten consultar el historial de todos los ficheros, sincronizar todo un proyecto de forma que se pueda saber rápidamente todos los cambios que se han efectuado,... Consultar la documentación para más detalles


Un sistema de gestión de incidencias o bugs

Los sistemas de gestión de incidencias o bugs permiten centralizar en un servidor todas las tareas, mejoras, bugs de una aplicación. Es muy común entre los desarrolladores contar con una libreta donde se va apuntando todas las tareas que te faltan por hacer, errores que has ido encontrando, apuntes puntuales,... Esto es muy útil pero lo sería más si esa libreta fuera compartida por todos los integrantes del grupo de desarrollo. Si esa libreta la informatizamos y hacemos que todos puedan apuntar en ella lo que estaremos programando es el sistema de control de incidencias.

Los beneficios que aporta el sistema son tremendos. Gracias a tener centralizados toda la información referente a errores y mejoras el director de proyecto puede ir asignando la resolución de estas tareas a los desarrolladores. Esto permite que no se solapen en la faena. También permite desacoplar al equipo de desarrollo. Cuando se encuentra un error se guarda en el sistema, si un cliente propone una mejora se registra sin necesidad de que dicha información tenga que ser comunicada de inmediato, ni de apuntarlo en un postit o enviarlo por correo electrónico.

Estos sistemas permiten también priorizar las tareas, indicar para qué versión de la aplicación van a estar solucionadas, guardar la información de la resolución del error...

Toda la información registrada en el sistema permite a los responsables del proyecto tener fotos diarias de todo el trabajo que se está realizando, las tareas resueltas por cada integrante del grupo, informes automáticos de las nuevas mejoras de cada nueva versión,...

Habitualmente estos sistemas vienen con una interfaz web. Pero también se puede integrar dentro de Eclipse. Para ello se utilizar el plugin Eclipse Mylyn. Mediante el plugin se podrán crear las tareas (mejoras/incidencias/bugs), consultarlas,... y todo sin salir del editor.

Pero Mylyn es mucho más que eso. Mylyn es un plugin de Eclipse para la programación orientada a tareas. Como tarea entender la mejora, la incidencia o el bug del que se ha hablado en líneas anteriores. Con Mylyn en todo momento indicas sobre qué tarea estás trabajando. Cuando inicias la tarea Eclipse cierra todos los editores abiertos y crea un contexto vacío. Si estamos trabajando en la tarea crearemos ficheros y modificaremos los existentes. Todos estos ficheros se guardan en el contexto. Así, si tenemos que iniciar una nueva tarea y posteriormente volver a la primera sólo con indicar a Mylyn que activamos la primera tarea se abrirá automáticamente los ficheros de su contexto. Este contexto puede ser incluso compartido por varios usuarios. No es de extrañar que las tareas sobre las que se trabaja son las registradas en el sistema de control de incidencias. Tareas compartidas con el resto de integrantes del equipo.

Pero su punto de integración llega incluso al extremo de que si subes cambios al sistema de control de versiones, como comentarios de la subida te pone automáticamente la referencia a la tarea sobre la que estás trabajando. Eclipse - Sistema de control de versiones - Sistema de control de incidencias. Es un triángulo clave en el desarrollo.



Hay muchos sistemas de gestión de incidencias. Yo destacaría sin duda Atlassian Jira. En opciones Open Source tendríamos bugzilla o Trac pero son muy inferiores en cuanto a facilidad de uso y prestaciones.


Wiki empresarial

En muchos casos el propio sistema de control de incidencias, si se hace público, se suele utilizar como fuente clave para la documentación pero es también muy aconsejable tener un sistema wiki empresarial en el equipo de desarrollo.

En este sistema se almacenan todas las notas, manuales y tutoriales que el equipo va generando con el paso del tiempo. Centralizando toda la información cualquier integrante del grupo puede encontrar en la wiki respuesta a problemas que otros ya han encontrado previamente. También nuevas incorporaciones al grupo pueden encontrar en esta wiki una fuente de conocimiento.

No quiero extenderme mucho más en este punto pues es un tema más conocido por todos debido a la wikipedia, aunque raramente utilizado en entornos de desarrollo.

De nuevo hay muchas wikis. Yo recomendaría Atlassian Confluence. Aunque hay otras opciones interesantes como Alfresco. Si queréis utilizar MediaWiki (el utilizado en la Wikipedia) o similares mucho ánimo. No están preparados para los requerimientos de una empresa.


Varios entornos de desarrollo: desarrollo, integración, preproducción y producción

Un buen proyecto suele tener varios entornos de desarrollo. Esto es, distintas máquinas o servidores por los que pasa antes de ser instalado en el servidor real. De forma sencilla se podrían distinguir cuatro:
  • Desarrollo: Cada desarrollador tiene un entorno funcionando en su máquina
  • Integración: Servidor, normalmente alojado en las propias oficinas del equipo y que se utiliza para probar cambios realizados por varios miembros del grupo
  • Preproducción: Entorno con características casi similares al entorno real y para hacer las últimas pruebas para estar completamente seguro de que todo va a funcionar
  • Producción: El servidor real

Para pasar de un entorno a otro es muy importante contar con herramientas para hacer el despliegue (deploy) de forma automática. Así, pasar de un entorno a otro no debería ser más complicado que hacer doble click en un .bat, .sh o un fichero de ant. Merece la pena invertir horas de trabajo en automatizar este proceso pues a la larga siempre se obtiene un buen rendimiento


Tests y un servidor de integración continua

Por último resaltaría la necesidad de contar con una batería de tests en el proyecto. Los tests ayudan a mantener la estabilidad del código, a asegurar que no se introducen errores en su ciclo de vida. En la medida de lo posible hay que evitar el testeo manual.

Simplificando podemos distinguir dos tipos de tests:
  • Test unitarios: Testean piezas individuales de código. Por ejemplo una clase que valida DNIs.
  • Tests funcionales: Cubren varias clases y su cometido es comprobar que capas superiores de la arquitectura de la aplicación funcionan. Por ejemplo probar que una transferencia bancaria funciona correctamente.

Los patrones del TDD (Test Driven Development) llegan a decir que los tests tienen que cubrir el 100% del código y que tiene que haber un test unitario por cada pieza de código desarrollada. Yo usualmente sólo desarrollo tests funcionales pues hacer tests unitarios lleva muchísimo tiempo y creo que es muy complicado realizarlos correctamente.

En Java recomendaría JUnit o TestNG. En PHP yo utilizo un framework propio de Symfony aunque PHPUnit también es muy completo.

También comentar que Eclipse tiene plugins para los anteriores por lo que de nuevo no hay que salir fuera de él para ejecutarlos.


Los servidores de integración continua automatizan el despliegue de una aplicación y la ejecución de los tests asociados. Sus ejecuciones se suelen programar, por ejemplo, para cada tres horas. Poniendo un ejemplo, un servidor de estos se podría configurar para que se descargara del sistema de control de versiones la última versión del proyecto, la instalara en el servidor de integración y ejecutara uno por uno todos los tests. El informe de los resultados se guardaría y podría ser consultado en todo momento. Estos servidores obligan al equipo a hacer integraciones continuas y tener un ciclo de desarrollo de software iterativo.


Conclusión

En resumen, hay multitud de herramientas disponibles para el uso de un equipo de desarrollo. Un buen uso de estas herramientas mejora rápidamente la eficiencia del equipo y asegura una mejor calidad del producto final.

Un sistema de control de versiones para almacenar todo el código de los proyectos y permitir el trabajo en paralelo.

Un sistema de control de incidencias para centralizar todas las tareas que se realizan y asignar prioridades y miembros a cada una de las tareas

Un wiki para guardar la documentación generada y que los miembros actuales equipo y sobretodo los que están por llegar encuentren de forma rápida la información requerida.

Una batería de tests para asegurar que los cambios realizados en el código no afectan a otras partes del código.

Y poniéndonos en plan literario "y un IDE para gobernarlos a todos".