jueves, abril 22, 2010

Integración Continua para mantener el proyecto en rumbo

Hoy en día tenemos muchas herramientas que dicen limpiar de forma mágica nuestro código. Mueven, modifican, emprolijan y mágicamente resuelven todos nuestros problemas. Lamentablemente, como la mayoría ya sabe, escribir buen código lleva trabajo. No existen herramientas mágicas que puedan salvarnos (y no importa lo que nos digan los vendedores), pero si hay una herramienta que funciona muy bien para ayudarnos a mantenernos en forma.

La Integración Continua es una idea bien simple. Configuramos un programa que mire el código fuente. Cuando alguien hace algún cambio, el sistema de Integración Continua lo compila de inmediato. Si la compilación pasa, se ejecutan las pruebas automatizadas. Por último, se publican los resultados.

Simple, ¿no? ¿Por qué es tan poderoso?

La Integración Continua es como una tarjeta de crédito al revés. Una tarjeta de crédito nos permite comprar algo grande hoy, y pagarlo de a poquito más adelante. Sin embargo, las tarjetas de crédito tienen un pequeño secretito oscuro... el interés compuesto. Terminamos pagando mucho, mucho más de lo que tomamos prestado. Siempre resulta más barato pagar en efectivo si podemos.

Cuando usamos un sistema de Integración Continua, ocurre lo opuesto. Podemos hacer pequeños pagos todos los días, o podemos esperar hasta el final y hacer un único gran pago. ¡Desafortunadamente este último gran pago tiene todo el interés compuesto agregado! Si esperamos al final, terminamos pagando más... mucho más!

Esto ocurre por el "tiempo a oscuras" entre que un desarrollador escribe el código y lo combina con el código que escribió el resto del equipo. Si combinamos el código todos los días, o incluso un par de veces a la semana, los cambios son menores y relativamente indoloros. Pero si esperamos...

Si esperamos, los cambios crecen. Mientras más esperamos, más código escribimos. Y más código escribe el resto del equipo. Al terminar el mes, cuando nos vemos forzados a combinar y unir todos esos cambios, las colisiones son gigantes. Los desarrolladores trabajan en los mismos archivos, a veces en las mismas líneas... otras veces hay funcionalidad en la que un desarrallador dependía y ahora hay otro desarrollador que la cambió (quiero decir, "mejoró"). Y los cambios mutuamente excluyentes generan caos.

Durante este tiempo entre escribir el código y hacer la combinación, compilación y testeo con el código de los demás, es cuando no podemos ver lo que está pasando. ¿Nuestros cambios entran en conflicto con los de alguien más? ¿Alguien cambió algo que necesitamos? No podemos verlo todavía... estamos a oscuras. Y vamos a seguir a oscuras hasta que unamos el código.

Una herramienta de Integración Continua ayuda los desarrolladores a aprender el ritmo de "escribir una cosa, subirla al repositorio". Esto funciona mucho mejor que "escribir una cosa... y otra... y otra... y otra...", y después "dedicar horas y días a combinar el código". ¡Y ni siquiera empezamos a ahblar de los beneficios de ejecutar las pruebas automatizadas después de subir cada cambio!

Tenemos que encontrar los problemas lo más rápido posible, cuando todavía los arreglos son menores. ¡Es el mejor momento para arreglar los problemas!

Algunos productos de Integración Continua para empezar

Fuente: DosIdeas

miércoles, abril 21, 2010

Crear amor, no dinero

Algunas personas de negocios siguen una estrategia que no se enseña en las escuelas de negocios: la mejor forma de maximizar las ganancias es dejar de pensar en maximizar las ganancias y, en cambio, enfocarse en tratar bien a las personas. Es decir, la mejor forma de hacer dinero es enfocarse en amar a las personas.

Joel Spolsky ya lo dijo: "Las mejores condiciones de trabajo -> Los mejores programadores -> El mejor software -> ¡Ganancia!".

Tony Hsieh lo dice de esta forma: "La Cultura es nuestra prioridad número uno... Creemos que si generamos la cultura correcta, entonces muchas otras cosas como construir una marca van a ocurrir de forma natural por si mismas".

Quisiera distinguir esta visión de dos perspectivas similares: la primera es el estilo del colectivismo hippie de los '60, en el cual el capitalismo es malvado porque es inherentemente manipulativo, que el trabajo y el capital deberían beneficiar a todos los miembros de la organización, y que, en realidad, el dinero es una molestia y lo que importa es el amor. En contraste, la perspectiva de Crear amor, no dinero no dice que el dinero sea una molestia o cómo debería organizarse el capital. Tampoco quiere decir que sea inconsistente con el punto de vista hippie.

La segunda perspectiva proviene del mantra tradicional de Scrum: "El objetivo del equipo es maximizar el valor de negocio entregando software que funciona". Bajo la mirada de Crear amor, no dinero se podría re-escribir: "El objetivo de un equipo es optimizar su entorno de trabajo y, como efecto secundario beneficioso, va a incremental radicalmente el valor de negocio que se entrega". Es un hallazgo empírico que optimizar el entorno de trabajo suele llevar a incrementos significativos en los resultados financieros. Resulta consistente con el sentido común pero no necesarimante deriva de la premisa "optimizar el entorno de trabajo".

Una buena pregunta: ¿Por qué no hacen esto quienes maximizar las ganancias? El gerente típico medio, cuando se le pide que aumente las ganancias, responde despidiendo trabajadores o ahorrando en material de la oficina - no creando un gran entorno de trabajo. No sé porqué. Sospecho que tiene que ver con las limitaciones cognitivas de las personas. Nos resulta muy dificil comprender el enésimo efecto de nuestras acciones. Es mucho más simple comprar sillas baratas para lograrlo - cualquier otra cosa es más complicada.

Si se adoptara, quienes maximizan los beneficios podrían ver a la perspectiva de Crear amor, no dinero como una herramienta cognitiva que ayuda a tomar mejores decisiones, al igual que un coach de ajedrez enseña a desarrollar las piezas (en vez de pedirle que haga mate al rey).

En resumen: enfocarse en crear grandes ambientes de trabajo, y obtendremos gratis las ganancias extraordinarias.

Fuente: DosIdeas

lunes, abril 05, 2010

Lista de comprobación para hacer TDD

El Desarrollo Guiado por Pruebas (o TDD) se suele describir como un ciclo de rojo-verde-refactor, que se repite continuamente, para ir agregando nuevas características o arreglar bugs. La siguiente lista de comprobación que comparte Giorgio Sironi contiene un grupo de preguntas que deberíamos hacernos a nosotros mismos mientras avanzamos por las fases de TDD, para no olvidarnos de la esencia de esta técnica.

Rojo

El desarrollo de cualquier característica nueva tiene que empezar con una prueba que falla.

  • ¿Subiste el código al repositorio remoto o local? Si el código se rompe, es más fácil revertir los cambios que re-escribir.
  • ¿Ya escribiste código productivo? Si lo hiciste, comentalo o, mejor todavía, eliminalo para no estar atado implícitamente a un API mientras escribís la prueba.
  • ¿Elegiste la unidad apropiada para expandir? La clase modificada debería ser una que siga teniendo cohesión luego del cambio, y a menudo se deberían agregar claes nuevas en vez de acomodar la funcionalidad en las existentes.
  • ¿Falla la prueba? Si no, re-escribila para exponer la falta de funcionalidad.
  • ¿Una parte de la prueba ya falla? Si es así, eliminá el restante de la prueba; el resto lo podés agregar en métodos diferentes.
  • ¿El nombre del método de prueba describe su propósito? Asegurate de no atarte a detalles de implementación.
  • ¿Los mensajes de fallas son descriptivos sobre el problema? Asegurate que describan en dónde está fallando la funcionalidad, destacando la ubicación si se rompiera en el futuro.
  • ¿Los números y strings mágicos están expresados dentro de constantes? ¿Hay código repetido? El refactor del código de pruebas es más fácil cuando se hace tempranamente y mientras aún falla, ya que en este paradigma es más importante hacer que siga fallando que hacer que pase.

Verde

Se debe escribir el código productivo necesario para que la prueba pase.

  • ¿El código productivo hace pasar a la prueba? (así de simple)
  • ¿Hay un subconjunto del código productivo que hace pasar a la prueba? Si es así, comentá, o mejor todavía, eliminá el código productivo innecesario. Cualquier otra línea de código que escribas no tendrá cobertura, y serán líneas sin pruebas que deberemos leer y mantener en el futuro.
  • Cualquier otra acción específica será llevada a cabo en la fase de Refactor.

Refactor

Mejorar la estructura del código para facilitar los cambios futuros y el mantenimiento.

  • ¿Existe código repetido en la clase actual?
  • ¿El nombre de la clase es el apropiado?
  • ¿Los métodos públicos y protegidos tienen un nombre descriptivo? ¿Son legibles? El refactor de renombrado es uno de los más poderosos.
  • ¿Hay código repetido en diferentes clases? ¿Existe un concepto de dominio que está faltando? Podemos extraer hacia clases abstractas o hacer un refactor de composición. Este alto nivel de refactor también debería aplicarse a las clases de pruebas unitarias.
Fuente: DosIdeas