Comenzando a hacer desarrollo

Hace varios días nuestro servidor de integración tuvo algunos problemas. Sin hacer el cuento largo, cambiamos un disco y reinstalamos la máquina. Más allá de las complicaciones inherentes a la configuración final de operativos y herramientas, comencé a pensar en cómo habíamos ido adquiriendo todas esas herramientas de las que ahora dependemos.

Versionamiento y control de código fuente

La primer práctica que incluimos en el equipo fue el versionamiento. Por supuesto, ahora no hacemos ningún proyecto sin el apoyo de Subversion, pero antes de usarlo, no teníamos tan clara su utilidad. De hecho, yo mismo decía que en un equipo tan chico (entonces sólo dos) no hacía falta un sistema de control de versiones. Después de conocer el versionamiento, comencé a recomendar incluso a quienes trabajaban solos usar algo semejante a Subversion. Las ventajas no son sólo el respaldo continuo de los archivos, sino sobre todo, ofrecen la posibilidad de hacer un seguimiento de los cambios en los archivos, podemos recuperar una versión anterior sin tener que preocuparnos por andar guardando copias cada día o cada semana. Conforme el versionamiento se usa, las ventajas van creciendo, descubrimos nuevas metodologías que usan los sistemas de control de versiones para nuevas cosas, metodologías de desarrollo que requieren un control automatizado del código y los archivos. Al cabo de poco tiempo, usamos el sistema de control de versiones para todo lo que sea posible. Otros sistemas con mucha aceptación son CVS también dentro de las opciones Opensource y Clear Case (IBM) y Perforce (Perforce) como opciones comerciales.

TDD: Orientación a pruebas o Desarrollo dirigido por pruebas

La segunda práctica que incluimos fue la metodología de orientación a pruebas. Ya hacíamos pruebas unitarias, pero no probábamos todo ni seguíamos una metodología en particular. Como dice un amigo, el código que nunca falla es el que no está escrito, y esto es una de las directrices de la orientación a pruebas. Básicamente, no se programa nada que no tenga una prueba que respalde el comportamiento programado, y como las pruebas representan responsabilidades y requerimientos de contrato de clases, uno se asegura de no programar nada que no sea un verdadero requerimiento. Es decir, todo el código debe ser necesario (las florituras y accesorios de “por si lo usamos” desaparecen) y todo el código debe ser probado. Aquí tengo mis reservas como las tienen muchos, pero digamos que, el común acuerdo es que, la orientación a pruebas debe seguirse a pies juntillas en la capa de negocios. Todo aquello que tenga que ver con reglas de negocios debe ser probado y necesario. La capa de datos tiene sus trucos y probarla no siempre es tan fácil, y la capa de interfase, al menos para un servidor, sólo debe aceptar pruebas explícitas de supervisión humana que no entran en el paradigma de la orientación a pruebas. Aquí la herramienta por elección si uno trabaja en .Net sería NUnit, una implementación de la familia XUnit  creada por Kent Beck con SUnit para Smalltalk cuyo primer crío fue JUnit, una herramienta para pruebas unitarias en Java.

Cobertura de código

Por supuesto, con la orientación a pruebas surgen dos preguntas, la primera es, cómo sé que estoy probando bien las cosas, es decir, que mis pruebas en efecto garantizan mis requerimientos. La segunda, cómo sé que estoy probando todo mi código (si usted es un programador profesional, sabe que la cantidad de código en un proyecto promedio es demasiado, y llevar el traking mental de lo que se ha probado y lo que no es por completo imposible). La primera pregunta no tiene respuesta fácil, es más bien cuestión de práctica. Existen patrones para pruebas, metodologías de levantamiento de requerimientos, metodologías de modelado y arquitectura y otro montón de cosas para facilitar esta parte, pero una garantía total es casi imposible de tener. Lo importante es tener en cuenta que la orientación a pruebas no es para garantizar que todo esté probado, sino para facilitar el desarrollo de software. La segunda pregunta tiene una respuesta más fácil: una herramienta que se encargue de ver cuánto código está probado. De estas hay muchas, nosotros usamos NCover, pero existen otras opciones muy buenas como PartCover.

 Con estas dos buenas prácticas (tres contando el monitoreo de cobertura) las cosas comienzan a mejorar notablemente, sin embargo, uno se acostumbra a que las máquinas le ayuden y es muy fácil pedirles más. El siguiente paso es, quiero algo que integre mi código y el de los demás miembros del equipo, corra todas las pruebas y nos avise en caso de que alguna prueba se rompa, la solución no compile, o la cobertura comience a bajar.

Integración Continua

A la herramienta que hace esta magia se le llama servidor de integración y su tarea, aunque parezca un poco tonta, es monitorear el sistema de versionamiento, si hay cambios, actualizar su copia de trabajo, compilar el proyecto (mandar compilar el proyecto mediante alguna otra herramienta como NAnt o MSBuild, correr las pruebas (mediante NUnit o alguna otra herramienta), analizar la cobertura (también mediante alguien más) y otras cosas que por el momento esperarán. Al terminar de ejecutar todas las herramientas, integra un reporte y lo publica en un sitio Web para que el equipo pueda ver el estado del desarrollo. Nuevamente, los servidores de integración vienen en muchos colores y sabores y como dice el mismo Martin Fowler, no son indispensables para las tareas de integración continua, pero ayudan bastante.

 Basicamente con estas herramientas se tiene un entorno de desarrollo bastante respetable, y muchos equipos podrían conformarse con esto, pero existen algunas herramientas que mejoran aún más las condiciones de trabajo.

Monitoreo de código duplicado

Además del monitoreo de código duplicado, a muchos desarrolladores les preocupa el problema de la duplicación de código, y es que esa vieja costumbre del copy-paste, llevada al mundo del código, puede ser un verdadero dolor de cabeza a la hora de corregir errores o modificar funcionalidad. Si hay muchas copias del mismo código, y hay un error o un cambio en este código, tenemos que recordar hacer el cambio en cada una de las partes duplicadas, lo cual, dicho sea de paso, es muy dificil de lograr. Lo común es que al menos una de las copias se quede con el error o con la funcionalidad vieja. Para evitar esto, lo mejor es evitar el código duplicado por completo, o por lo menos saber dónde está. Para esto existen herramientas que buscan código duplicado y cuyos reportes pueden integrarse fácilmente a las herramientas de integración. Como ejemplo menciono la que nosotros usamos: Simian.

FxCop: Buenas prácticas de implementación

Otro de los problemas a los que nos enfrentamos los equipos de desarrollo es a mantener las buenas prácticas de codificación en todos nuestros archivos, por ejemplo, no permitir el paso de literales en métodos públicos que utilizan estas cadenas como consultas SQL contra el motor de datos, o levantar una excepción especializada cuando un argumento no cumple con los requisitos mínimos de un miembro público. Estas y muchas más reglas de “buena codificación” se olvidan fácilmente a la hora de estar programando, o un típico “al rato lo completo” en cocktail con nuestra mala memoria, pueden hacer que nuestro código sea más inseguro o más propenso a errores. Para evitar esto, podemos usar herramientas de monitoreo de código como el famoso FxCop que también se integra bien a los sistemas de integración continua. Para quienes lo utilizan por primera vez, el consejo de la paciencia sería poco. Esta herramienta puede ser un poco pesada de usar si uno no está dispuesto a seguir sus consejos (incluso cuando esos consejos han sido personalizados).

Ahora sí, parece que todo marcha como nunca, sin embargo, uno siempre quiere más y más, y siempre existió alguien igual o más ambicioso que nosotros en el pasado y dejó una herramienta para ayudarnos en nuestra obsesión automatizadora y controladora (broma a broma, tenga usted cuidado con no volverse un verdadero maniaco de la automatización y el control, recuerde cualquier modificación a los procesos debe agregar valor a la organización, no sólo darle gusto a la Gestapo que todos llevamos dentro).

Métricas de código y desempeño

Lo siguiente que nos interesaría tener como un apoyo incluso a la arquitectura y diseño de la solución es algo que nos de información sobre las relaciones entre los elementos de nuestro diseño, es decir, métricas de código y funcionalidad. Aquí las herramientas son muchas, pero NDepend es sin duda una de las mejores opciones, junto con NProf para monitorear el desempeño. Estas dos herramientas ya comienzan a tener sus desventajas, la primera es que ya no es tan fácil interpretar sus reportes, ahora sí hay que saber leer, la segunda es que se toman mucho tiempo, demasiado como para poder respetar el principio de integración continua (compilaciones en menos de 5 minutos).

Integración continua e integración nocturna

Nosotros tenemos dos proyectos de integración continua, uno sin estas herramientas que monitorea continuamente el repositorio y nos permite enterarnos rápidamente del estado del proyecto en todo momento, y otro que corre estas y otras monerías en las noches, cuando a nadie le importa que la integración se tome más de media hora.

Documentación automática, compilación de instaladores, estadísticas y otros

Las otras herramientas que se corren en el Build nocturno son, la generación de documentación HTML y PDF, la compilación de instaladores para tener listo un instalador funcional en todo momento por si el cliente lo pide, el monitoreo y estadísticas del repositorio que lleva una estadística por usuario, archivo, espacios de nombre, etc. de los cambios en el repositorio (muy útil para saber quien da más líneas por minuto en el equipo) y, dependiendo del proyecto, alguna otra tarea que pueda llevarse su tiempo.

Manejadores de proyectos

 Una vez completado el proyecto de integración continua (y nocturna), lo siguiente es un sistema que apoye en las tareas de seguimiento de proyecto, y para ello, cosas como Mingle de Thoughtworks pueden ayudar bastante, siempre y cuando la metodología del equipo sea alguna forma ágil. Mingle permite llevar un seguimiento del proyecto, casos de uso, requerimientos, ciclos de vida de requerimientos y otros artefactos dependiendo de la metodología utilizada, además de llevar una Wiki bastante fácil de utilizar y con acceso a funciones del dashboard de monitoreo.

Ya con esto, el entorno de desarrollo es más de lo que muchos podrían pedir, y agregarle más cosas depende de las necesidades de los equipos y de los proyectos.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s