Real-world TDD

El viernes pasado me tocó trabajar en una funcionalidad relativamente simple. Dada una aplicación de gestión de proyectos que tiene la capacidad de recibir mails (chiliproject) me pidieron que le agregue la capacidad de rutear los mails de entrada a uno u otro proyecto dependiendo de cierto algoritmo. Cuando estaba por empezar a desarrollarla pensé: “este es un excelente ejemplo para mostrar el uso de TDD en un contexto real”. Entonces abrí mi software de grabación y me puse trabajar. El resultado es este video que muestra cómo resolví parte del problema usando TDD. Espero lo disfruten.

Estrategia de Continuous Delivery: git + jenkins + heroku (parte 1)

En uno de los proyectos open source en los que participo hemos montado una infraestructura de continuous delivery que nos viene dando buenos resultados por ello quiero dedicar algunas líneas a describir su estructura.

El proyecto consta de 2 aplicaciones, una webapp y un servicio de backend pero cada una es manejada de forma independiente, por ello el resto de este artículo hablaré de forma genérica como si fuera una única aplicación. La aplicación web está construida con Ruby/Padrino, mientras que el servicio es Ruby “puro”.

El código de la aplicación es versionado en GitHub, donde tenemos un branch develop sobre el trabajamos y un branch master que tiene el código que está en producción. El código de develop es desplegado automáticamente por Jenkins en una instancia de prueba (que denominamos preview) mientras que el código de master es desplegado en la instancia de producción. Ambas instancia estan corriendo en Heroku.

En el proyecto somos tres programadores, que trabajamos en la aplicación en nuestros tiempos extra laborales. Cuando trabajamos en funcionalidades no tan chicas, que pueden llevarnos un par de días, creamos feature branches.

Adicionalmente al repositorio de GitHub, tenemos otro repositorio, privado, hosteado en BitBucket donde almacenamos la configuración de la aplicación. Aquí tenemos dos branches, uno por cada ambiente.

Jenkins se encarga de la correr la integración continua y los pasajes entre ambientes. Para ello tenemos los siguientas tareas:

  • CI: corre integración contínua sobre el branch develop. Básicamente corre pruebas unitarias y de aceptación.
  • CI_All: es análogo al CI, pero trabajo sobre todos los demás branches, lo que nos permite tener integración contínua incluso cuando trabajamos en feature branches.
  • Deploy_to_Preview: despliega en el ambiente de preview (test) el código proveniente del branch develop
  • Run_Preview_Pos_deploy: aplica la configuración actualizada y las correspondientes migraciones en el ambiente de preview y ejecuta un smoke test
  • Run_Pre_Production_deploy: mergea el branch develop en master
  • Deploy_to_production: despliega en el ambiente productivo el código proveniente del branch master
  • Run_Production_Pos_deploy: aplica la configuración actualizada y las correspondientes migraciones en el ambiente de preview y ejecuta un smoke test

Algunos detalles más para destacar son:

  • Todo commit a develop, se despliega automáticamente a preview.
  • No se hacen despliegues a preview y producción en forma manual, todo pasa por Jenkins
  • Ante cada build, Jenkins informa el resultado via chat (Jabber) a todos los miembros del equipo de desarrollo.
  • El monitoreo de la aplicación en el ambiente productivo lo hacemos con LogEntries y New Relic

Sin duda que este esquema no es una bala de plata, pero nos funciona muy bien en este proyecto. Algunas cuestiones a revisar en otros proyectos serían:

  • En caso de trabajar con un lenguaje compilado estáticamente (Java, C#, etc) habría que considerar utilizar un repositorio de binarios para que la aplicación se compile una única vez (algo tipo Artifactory)
  • En caso de aplicaciones con requerimientos de disponibilidad 7×24, había que considerar una estrategia de deploy distinta, tal vez algo del tipo blue-green deploy.

Si gustan conocer más detalles, no duden en consultar.

Configuration Management in my .NET project

On these days I am working on big system that is built on several components: a couple of websites, some backend services and several shared libraries. At this moment all these components are stored in the same Subversion repository. As you can image, this is a huge repository. At the same time, the system is already running in production mode and some components are being updated/replaced. Because of this situation and in order to simplify configuration management I being working on designing a new configuration management strategy. The solution I have in mind includes 3 key tools:

  • Git: to store source code, in particular I like GitHub service
  • NuGet: a package manager for .NET components (for those not familiar with .NET, it is like a Maven in Java o npm in Node). We know we will need a private Gallery for some components, but we still don’t decide if  we are going to host our own instance or if we will use a cloud service.
  • Jenkins: to provide continuous integration and deployment automation

Now I will try to explain how these components fit together.

Each shared library has its own Git repository. In case a library depends on third party component, it should declare the dependency package.xml for Nuget to download the dependency at build time. At the same time, stable versions of share libraries are published in NuGet Gallery (possible a private one).

Each application has its own Git repository. In case an application depends on third party component, it should declare the dependency in package.xml for Nuget to download the dependency at build time. In case this application depends on a  private share library there two options:

  • If the shared library will be used as it is, then it is managed with NuGet
  • If the shared library needs to be modified, then the shared library repository is added as a submodule of the application repository. This way you will be able to add the shared library project to your Visual Studio solution and will be able to modify it.

At the same time, Jenkins will monitor all repositories and trigger a CI job to compile and run automated tests on each change. For each application there will be additional Jenkins Jobs to perform deployments to the different environments. For each shared library, there will be a Jenkins job to publish the library to the NuGet repository.

scm

Los dilemas del uso de Gherkin/Cucumber

Como mencioné anteriormente, estoy trabajando un proyecto ocupando el rol de Software Engineer in Test (SET). Una de las primeras cuestiones que debí resolver en el proyecto fue acordar con los analistas/testers la convenciones para escribir los tests con Gherkin. Todo aquel que haya trabajado con Gherkin en algún momento seguramente se ha enfrentado a los diversos dilemas que plantea el uso de la herramienta.

Dilema 1

  • Escribir steps con parámetros, que permiten un alto reuso de steps definitions disminuyendo la cantidad necesaria de glue-code
  • Escribir steps sin parámetros, que permiten un mayor nivel de abstracción y expresividad, pero que al mismo tiempo requieren de más glue-code

Dilema 2

  • Agrupar los steps definitions por feature, lo cual posiblemente genere muchos archivos de steps definitions y también repetición de glue-code, pero que facilita la trazabilidad entre los archivos de features y los archivos de steps definitions
  • Agrupar los steps definitions por concepto de negocio, lo cual ayuda a reducir la cantidad de archivos y la posible repetición de código, pero que puede dificultar la trazabilidad entre archivos de features y archivos de steps definitions

Dilema 3

  • Hacer steps “stateless” (que no dependen de datos de contexto) lo cual permite mayor reuso, pero que obliga a pasar la información de contexto como parámetro de los steps
  • Hacer steps “stateful” (que sí dependen de datos del contexto) lo cual permite generar steps más claros yreducir/omitir los parámetros en los steps, pero que disminuye el reuso de steps y obliga a generar código adicional para el manejo del contexto

En todos los dilemas planteados existen más alternativas que las mencionadas, de hecho las alternativas aquí planteadas son en cierto modo extremas pero sirven para ejemplificar algunas de las cuestiones que debemos definir al trabajar con esta herramienta.

Al mismo tiempo hay algunas cuestiones adicionales a considerar dependiendo de la implementación de cucumber que utilicemos. Por ejemplo: la implementación Ruby es un DSL que permite fácilmente compartir estado entre los steps definitions independientemente de la forma en que los agrupemos, mientras que en la implementación Java (Cucumber-JVM) sólo es posible (en principio) compartir estado entre los steps definitions que esten agrupados en la misma clase.

Todas estas cosas son las que estuve definiendo la primer semana de proyecto. Ahora estoy trabajando en generar un “micro framework” (básicamente algunas clases helpers) que me faciliten la implementación de los steps definitions.

Continuará…

 

 

 

Proyecto T: tecnología definida

Luego de investigar y hacer algunas pruebas de concepto, los alumnos eligieron construir la aplicación con Grails y AngularJS, una combinación con la personalmente no tengo experiencia pero que me gusta.

Respecto a la infraestructura, el repositorio será Git (github).

Respecto del build server y el ambiente de tests, yo tenía la ilusión de usar el servicio de CloudBees, pero los alumnos prefirieron ir con Travis y Heroku.

Un proyectito en PHP

En los inicios de mi carrera hice algunas cosillas con Php motivado por un curso de Php que había tomando en el Club de Programadores y cuyo instructor había sido el maestro AJ Lopez.

Hace un tiempo volví a poner mis manos en Php y me encontré con varios cambios, algunos de los cuales había escuchado pero no había tenido la oportunidad de experimentarlos.

Mi percepción es que el lenguaje ha evolucionado bastante, incorporando diversas construcciones y soporte para programación orientada a objetos.

Por otro lado veo un gran ecosistema de herramientas y frameworks que le han permitido mantenerse como uno de los principales jugadores en el ámbito del desarrollo web a pesar del gran avance de Ruby y Python.

Al mismo tiempo noto que a diferencia de lo que ocurre en Ruby y Java, la comunidad no estan del todo “alineada”, hay cuestiones que no parecen estar estandarizadas y otras que a pesar de parecer estandarizadas son ignoradas por gran parte de los practicantes.

En mi caso particular resulta que desde comienzo de año venía trabajando en una organización en una iniciativa de Continuous Delivery y llegado un punto necesitamos de una herramienta para secuenciar los pedidos de despliegue a cada ambiente. Por diversas cuestiones esta organización decidió construir esta herramienta con Php usando el framework Silex. Luego de una primera versión, fue necesario realizar algunas modificaciones y agregar nuevas funcionalidades y por cuestiones de disponibilidad de tiempo, fui yo el encargado de estas cuestiones. Esta organización ha manifestado la intención de liberar está herramienta con licencia open source, por ello es posible que en breve les traiga más noticias.

Continuará…

Comienzo de nuevo proyecto, llamémosle T

En estos días estoy por comenzar un nuevo proyecto, llamémosle T. Se trata de un trabajo de inserción profesional que voy a co-dirigir con Fidel. El trabajo será desarrollado por dos alumnos de la carrera y el objetivo es construir un sistema de gestión para la sala de guardia de un hospital. El proyecto surgió a partir de una necesidad detectada por Luis, un médico, jefe de guardia de un hospital del conurbano.

Como suelo recomendar para todos los trabajo finales de carrera, la idea es gestionar el proyecto como de alcance variable, lo cual requiere una trabajo muy cercano con el product owner para asegurar una correcta priorización de funcionalidades y un rápido feedback a medida que estas se van completando.

Continuará…

 

 

Relato de un desarrollo ágil en la industria petrolera

Resumen

Este artículo describe un proyecto en el que participé hace un par de años cuyo objetivo era la informatización del proceso de gestión de licitaciones de una empresa del rubro petrolero. El mismo fue realizado por un equipo de 4 personas en un plazo de 5 meses, trabajando con prácticas ágiles de gestión  en el marco de un contrato de alcance variable.

Contexto del proyecto

Trabajaba yo en aquel momento en un empresa de desarrollo de soluciones informáticas y nos había contactado una empresa del rubro petrolero para informatizar su proceso de la gestión de licitaciones. Hasta aquel momento esta empresa tenía un proceso de licitaciones totalmente manual lo cual implicaba:

  • Gran volumen de información en papel
  • Alto costo de gestión
  • Licitaciones más largas de lo deseable

El objetivo del proyecto era resolver estas cuestiones a partir de la informatización de proceso y adicionalmente lograr:

  • Una mayor transparencia del proceso de licitaciones
  • Mayor visibilidad del proceso
  • Tener métricas del proceso que permitan detectar posible puntos de mejora

Un detalle técnico relevante era que la solución debía ser implementada sobre una plataforma de gestión de contenidos (CMS) que el cliente ya estaba utilizando.

El acuerdo

La venta del proyecto fue llevada a cabo por el gerente del área de desarrollo con mi asistencia, que en aquel momento era líder técnico. Ambos hicimos un primer relevamiento a partir del cual, mi equipo de técnicos y yo hicimos una estimación de esfuerzo. Luego junto con el gerente del área del área de desarrollo, hicimos un plan tentativo de versiones (release plan ) tomando como base la estimación realizada por el equipo, los riesgos detectados y las fechas deseables que había manifestado el cliente.

Es importante destacar que antes de la presentación formal de la propuesta tuvimos una reunión con el cliente en la que hicimos una presentación informal de la misma, para explicar nuestra forma de trabajo y así asegurarnos que la propuesta escrita fuera bien interpretada. La propuesta tenía algunas particularidades interesantes:

  • Indicaba explícitamente que tendríamos reuniones semanales para validar el trabajo realizado y así tener feedback temprano y constante. Esto nos permitiría asegurarnos de estar construyendo el producto que el cliente necesitaba
  • Establecía un alcance variable, lo cual estaba justificado por la incertidumbre que había respecto de cómo se informatizarían ciertas cuestiones del proceso de licitación. Si bien la empresa ya tenía un proceso de licitaciones que venía utilizando, el mismo era manual y su informatización implicaba ciertos cambios en dicho proceso.Algunos de esos cambios era bien claro cómo debían ser, pero había otros que no y que requerían algo de experimentación.
    Al mismo tiempo la empresa de desarrollo se comprometia a entregar un sistema informático de soporte a la gestión de licitaciones. No se establecía el alcance completo de ese sistema pero estaba claro que ciertas funcionalidades debían ser cubiertas por el sistema.
  • El acuerdo tenía un alcance un año, donde los primeros 5 meses estaban destinados a generar la versión inicial de sistema con un equipo a tiempo completo. Los restantes 7 meses se preveía un esquema de soporte y mantenimiento evolutivo con un compromiso de unas 80 horas mensuales.

Inicio de proyecto

Aproximadamente 2 semanas después de haber presentado la propuesta, el cliente confirmó que haría el proyecto con nosotros. Para mi satisfacción el equipo encargado de la ejecución estaba conformado por los mismo técnicos que habíamos realizado la estimación inicial. De esta forma, por parte de la empresa desarrollo los involucrados éramos:

  • Danilo: gerente de desarrollo y responsable comercial del proyecto
  • Ramiro: era el responsable de sistemas del cliente.
  • Nicolás (yo): líder técnico del equipo de desarrollo y facilitador del proyecto
  • Camilo y Roberto: dos técnicos del equipo de desarrollo

Por parte de la empresa cliente los involucrados eran:

  • Felipe: sponsor, era el directivo de la empresa cliente que estaba pagando por el proyecto
  • Gabriel: era el responsable del  área de compras y en el contexto del proyecto ocupaba el rol experto de negocio y  product owner
  • Manuel y Matías: eran dos empleados del área de compras y como tales eran los futuros usuarios del sistema

La primer iteración fué particular pues duró sólo 1 semana y la dedicamos a algunas típicas del inicio de proyecto como ser configuración de ambientes y capacitación de los expertos de negocio sobre la dinámica de trabajo.

Para la gestión del proyecto utilizamos la herramienta Trac, que era la herramienta estándar utilizada por nuestra empresa de desarrollo en aquel momento. Dicha herramienta brindaba:

  • Gestión de tickets y plan de versiones
  • Wiki
  • Acceso web
  • Almacenamiento de documentos
  • Integración con sistema de gestión de código Subversion
  • Envío de notificaciones ante determinados cambios en los artefactos del proyecto

Dinámica de trabajo

El equipo de desarrollo trabajaba en sus oficinas, las cuales se encontraban a 1o minutos de a pié de las oficinas del cliente. En líneas generales la dinámica de trabajo estaba dada por :

  • Iteraciones time-boxed de 2 semanas de duración
  • Reuniones presenciales de planificación al comienzo de cada iteración
  • Reuniones presenciales de revisión y demostración al final de cada iteración

Dado que la informatización del proceso requería repensar algunos pasos del proceso de licitación, era común durante las iteraciones, hacer algunas reuniones adicionales a para ir analizando/definiendo las “nuevos pasos” del proceso de licitación.

Durante las reuniones de planificación se definían las funcionalidades a implementar en la iteración actual y establecían los criterios de aceptación de las mismas. Dichos criterios eran luego refinados y bajados a detalle por los especialistas de negocio en un plazo máximo de 3 días luego de la reunión de planificación. De esta forma el equipo de desarrollo podía contar con los criterios de aceptación antes de finalizar el desarrollo de las stories.

Apenas finalizada una funcionalidad, la misma era validada con un experto del negocio de forma de tal llegar al final de la iteración con la mayor parte de las funcionalidades con cierto grado de validación. La reunión de revisión al fin de la iteración no solía era un momento tenso, pues el cliente ya sabía lo que sea se iba a encontrar. Si una funcionalidad había sido completa, el cliente ya la habia visto y había dado algo de feedback. Al mismo tiempo, si alguna funcionalidad no había sido completada, el cliente también lo sabía previamente, pues el equipo comunicaba este cualquier tipo de desvío apenas lo detectaba.

Había un detalle importante respecto de la forma en que el equipo planificaba las iteraciones. Las reuniones de planificación se hacían los lunes de la primera semana de la iteración, preferentemente por la mañana. Las reuniones de revisión de hacían los viernes de la segunda semana de la iteración. Sin embargo, el equipo planificaba de cara a completar el desarrollo el miércoles de la segunda semana de la iteración, lo cual dejaba un día y medio para hacer prueba de regresión y realizar ajustes correspondientes al feedback temprano obtenido de los expertos de negocio.

Tanto la definición del proceso, como las user stories y sus correspondientes criterios de aceptación, eran escritos en la wiki del proyecto, en muchos casos por los mismos especialistas de negocio y luego eran revisados por algún miembro del equipo de desarrollo. También se pretendía que los expertos del negocio se encargaran de ejecutar las pruebas de aceptación, aunque esto no siempre se lograba.

La fase de desarrollo se completó con algunas variaciones respecto de lo planificado pero sin problemas graves. Una vez que el sistema estuvo productivo, se pasó a mantenimiento tal como estaba previsto.

Consideraciones finales

No todos los clientes están dispuestos a trabajar de la forma aquí descrita ni tampoco todos los proyectos lo requieren. Tal vez el proyecto se podría haber realizado utilizando otra dinámica de trabajo, pero en su momento creímos que esa era la forma apropiada de llevar ese proyecto. Hoy en día sigo pensando lo mismo.

Entre los puntos que considero fueron claves para el éxito del proyecto no puedo dejar de mencionar:

  • El alto grado de involucramiento de los expertos de negocio
  • Comunicación constante
  • Confianza del cliente en el equipo y vice versa
  • Compromiso y transparencia

 

To Heroku or not to Heroku

Hace un tiempo estuve escribiendo sobre el Proyecto CMS. Actualmente continuo trabajando en dicho proyecto y en estos dias estamos analizando en que plataforma hostear la aplicación. En este momento la aplicación está corriendo en Heroku, pero hay ciertas cuestiones que están ocasionando issues de performance. Ello llevó a que hicieramos una prueba de concepto levantando la aplicación en Linode.

Personalmente creo que las cuestiones de performance de la aplicación no tienen que ver con donde está hosteada sino con ciertas cuestiones de diseño y configuración. Al mismo tiempo, el pasaje de una plataforma como Heroku a otra plataforma del estilo Linode o Amazon EC2 implica un incremento importante en el costo de operación (al menos en un principio hasta que uno logra automatizar parte del trabajo).

Estimo que en las próximas dos semanas estaremos tomando una decisión respecto a esto (en realidad yo no tomo ninguna decisión, simplemente doy mi opinión).

Continuará…

Proyecto CMS, Go Live and Next Steps

Hace unas dos semanas, salimos en producción. La parte pública de la aplicación está accesible aqui.

Por estos dias estamos comenzado a trabajar en el siguiente hito: liberar como open source toda la plataforma. Esto me resulta especialmente interesante, pues si bien yo ya he publicado algunos proyectos open source, en general han sido cosas pequeñas. En este caso se trata de un producto de dimensiones interesantes y el cual se espera que tenga aportes de la comunidad. En cuanto tengamos algo publicado, les contaré.