lunes, 10 de mayo de 2010

Principios ágiles #6

Hace muuuucho tiempo comencé una serie de post sobre los principios ágiles que hay detrás del manifiesto ágil. No se por qué, dejé de escribir en el blog y la serie se interrumpió. Hoy, a lo Fronkonstoin, voy a devolver la serie a la vida hablando del sexto de ellos (esperemos que dure):

The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
El método más eficiente y efectivo de comunicar la información a un equipo de desarrollo y entre los miembros del mismo es la conversación cara a cara.

Comunicar información
¿Por qué hay gente que oculta información, que no comparte? Quizás para hacerse indispensables (como bien dice David Bonilla en su entrada sobre cajas negras). Que no os engañen, no lo son y no lo serán. Lo único que van a conseguir es aislarse de sus colegas de profesión y perderse todas las cosas buenas que hay fuera de su cubículo. Van a quedarse obsoletos.

Como decía Newton (aunque la wikipedia dice que fue Chartres):

Si he visto más lejos es porque estoy sentado sobre los hombros de gigantes

Si es bueno para Newton (vale, Chartres. Creo que se nota que soy físico) es bueno para ti.

Hay que salir, enriquecerse. Hay que aprender a ser humilde, a compartir tus conocimientos. Hay que enseñar lo que sabes y aprender lo que no sabes. Para todo esto es necesario comunicarse. No te conviertas en una caja negra.

A un equipo de desarrollo
Como he dicho ya muchas veces en anteriores posts, es importante que el cliente esté en contacto continuo con el equipo. Que sea capaz de comunicar sus objetivos y preferencias es una parte imprescindible de dicho contacto. Esto implica un nivel de compromiso por parte del cliente en el proyecto muy alto, siendo éste uno de los problemas más comunes en los equipos ágiles (al menos en los que yo conozco). Veamos un dialogo tipo:

- Hola, ¿vosotros sois ágiles?
- ¡Sí!
- ¿Cómo habéis conseguido involucrar al cliente en el ciclo de desarrollo?
- Respuesta 1: A no, eso no lo hemos conseguido.
- Respuesta 2: Nuestro cliente es interno.

Mi experiencia personal es del segundo tipo, así que tengo suerte :P Sinceramente, no se cómo resolver el primer caso :( Lo que sí que tengo claro es que, si no consigues que tu cliente se comprometa en el proyecto vas a pasarlas canutas...

Entre un equipo de desarrollo
Está claro que un equipo de desarrollo, si es sano ,debe estar en continua comunicación. Cuando se trabaja en intervalos de tiempo cortos es necesario que todo el equipo esté sincronizado de forma que se evite el trabajo duplicado. Igualmente, es muy importante que los miembros del equipo se encuentren comodos entre si, de forma que no resulte extraño que alguien pregunte cuando no sabe algo (No hay preguntas tontas ni respuestas estupidas, ya sabéis). Básicamente, es necesario que los miembros del equipo creen relaciones de confianza que ayuden el desarrollo de su trabajo (Todos trabajamos mejor con amigos alrededor ¿no? Huy, me ha salido muy piruleta esto último...).

Conversación cara a cara
Lo más eficiente no es ni usar el teléfono, ni el e-mail, ni el wave, ni el twitter, ni el skype... lo más eficiente (y por tanto lo deseable) es la comunicación cara a cara.

Pensad en la cantidad de herramientas que propone el agilismo a los equipos para que mejoren su comunicación. Desde el ¡Sienta al equipo junto! de Henrik kniberg a las reuniones diarias de Scrum sin olvidarme de algunas de las prácticas XP como la programación en parejas. Todas ellas se basan en la comunicación cara a cara, lo que debe dar una idea de su importancia.

Conclusiones
El sexto principio ágil:

  • Implica un alto nivel de compromiso en el proyecto por parte del cliente
  • Necesita que se den relaciones de confianza entre los miembros del equipo (incluido el cliente)
  • Señala la importancia de la relación directa entre las personas


Foto de "portada": Galería de Fernando en Picasa, bajo licencia Creative Commons.

martes, 2 de febrero de 2010

Principios Ágiles #5

Siguiendo con la temática de los principios ágiles, hoy voy a hablar del quinto de ellos:

Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.

Construye proyectos con profesionales motivados. Dales el entorno y soporte que necesitan, y confia en ellos para que realicen el trabajo.

Profesionales motivados
Cuando una persona encuentra un nuevo trabajo su motivación inicial es bastante alta. Si tiene experiencia previa probablemente haya conseguido un trabajo que le guste con un sueldo acorde a dicha experiencia. Estará contento y querrá demostrar que vale lo que le van a pagar. Si es un junior sin experiencia querrá aprender y prosperar en su carrera profesional. ¿Qué lleva a cualquiera de estas dos personas a desmotivarse? Pues multitud de causas. Falta de dirección (visión de empresa, visión de producto, abandono por parte de la gerencia...), mala cultura empresarial (mala relación entre compañeros, infraestructura deficiente, falta apoyo al aprendizaje), etc. Imagino que todos hemos pasado por algo así en algún momento, por desgracia.
Una vez que una persona pierde la motivación es muy complicado volver a motivarla, por lo que hay que esforzarse en evitar que ocurra.
¿Cómo se puede evitar la desmotivación?
Dan Pink lo explica muy bien en esta presentación (Si aún no la habéis visto ya estáis tardando :P)
Os escribo las conclusiones para los más vagos (aunque ya os digo que mola mogollón). Básicamente cuenta que, una vez resuelto el tema salarial (está claro que es un factor importante, pero no el único) los factores que ayudan a mantener la motivación son los siguientes:

  • Autonomía. Muy en sintonía con la auto-organización de los equipos ágiles ;) Hay que confiar en que el trabajador es capaz de hacer su trabajo por si mismo.
  • Maestría. Para los agilistas significa buscar la excelencia técnica (Sea lo que sea eso, que ya lo veremos en futuras entradas)
  • Propósito. Contribuir a algo importante. En el caso de la agilidad sería equivalente a contribuir en la mejora del negocio del cliente. Aportar valor y tal :)

Estos tres factores ayudan a mantener la motivación de un profesional (no solo los profesionales técnicos, cualquier tipo de profesional) ya que crea un entorno en el que las personas son importantes y valiosas (Ya sabéis, personas sobre procesos...).

Crear un entorno y dar el soporte necesario
Tal y como hemos visto arriba, la cultura empresarial es muy importante a la hora de mantener la motivación.
Es necesario que la empresa proporcione un ambiente que favorezca el aprendizaje, que ayude a crecer profesionalmente a sus trabajadores, que confíe en ellos para realizar su trabajo, que les proporcione una infraestructura adecuada a sus necesidades, etc. Es decir, que se dedique a eliminar impedimentos externos del día a día para que los únicos problemas que se encuentren sus trabajadores sean los propios de su trabajo (Eliminar burocracia inútil, métricas absurdas, controles exhaustivos, etc).

Confianza
Todo lo anterior se basa en la confianza. Está claro que un buen profesional sabe hacer su trabajo. No necesita un jefe todo el día detrás suya, interrumpiéndole cada 10 minutos para preguntarle qué tal lo lleva. Ese micro-control, además de desmotivar, reduce la productividad.
Sin embargo, hay que tener claro que no todo depende de área de gestión, el empleado debe responder. Como dijo el Tío Ben :

Un gran poder conlleva una gran responsabilidad

Si queremos que nuestro trabajo mejore, que se nos trate como a verdaderos profesionales y que se confíe en nosotros, debemos responder con autentica profesionalidad. Si nuestra empresa fomenta el aprendizaje debemos aprovecharlo y mejorar. Si nuestra empresa nos permite autonomía debemos comprometernos. No podemos desaprovechar las (¿pocas?) oportunidades que se nos ofrecen.

Conclusiones
El quinto principio ágil:

  • Busca fomentar la confianza
  • Advierte que lo importante son las personas
  • Pide que se eliminen los impedimentos externos
  • Implica responsabilidad y profesionalidad


NOTA: Si os interesa más el tema de la motivación de un equipo os recomiendo el libro Peopleware. Yo aún no lo he podido leer, pero José Manuel Beas lo recomendó en la reunión que tuvimos sobre principios ágiles al hablar sobre este principio. El libro se lo dejó a Alfredo Casado, que nos ha ido contando algunas de las cosillas que ha ido leyendo. La verdad es que tiene muy buena pinta :)

Foto de "portada": Galería de Fernando en Picasa, bajo licencia Creative Commons.

miércoles, 27 de enero de 2010

Sprint #2 - Aceptando el riesgo


Os presento la segunda planificación del ScrumBlog. Si no leistéis la primera planificación podéis echarle un ojo ahora (Allí explico un poco los roles de Scrum y las fases de la planificación). Doy eso por sabido y me meto directamente a planificar.

Planificación de la iteración
Voy a intentar que todas las iteraciones duren lo mismo, por lo que esta también durará 15 días. Quedan las fechas del sprint como siguen:
Planificación - Miércoles 27 de Enero
Inicio de Sprint - Jueves 28 de Enero
Fin de Sprint - Jueves 11 de Febrero
Retrospectiva - Viernes 12 de Febrero

Disponibilidad del equipo
Tal y como señale en la retrospectiva, la velocidad del equipo es de 11 puntos de historia cada 15 días. Dado que la disponibilidad del equipo es la misma que en la iteración anterior, fijamos los puntos de historia en 11.

Estimación de las historias
Veamos el estado de la pila de producto:



El equipo ha estimado las historias pero, si os fijáis bien, la historia de FitNesse aparece con un símbolo de exclamación. Esto es debido a que dicha historia tiene un factor de riesgo alto debido al desconocimiento del equipo en la tecnología a utilizar. La idea es hacer un ScreenCast cuando nunca he hecho ninguno. Es muy probable que mi estimación sea mala pero, es la mejor que puedo hacer.
¿Qué hacemos con este tipo de historias? Existen varias alternativas. Las que yo considero más adecuadas son las siguientes:

  • Fijar un limite de tiempo a dedicar a dicha tarea (en este caso 4 horas) de forma que, si mientras estamos investigando como realizar dicha historia nos damos cuenta de que la complejidad es mucho mayor que la que estimamos, dejemos dicha historia para la siguiente iteración.
  • Dividir la historia en dos. Por un lado tendríamos una historia para la formación del equipo y otra historia para la ejecución.
En este caso, tras hablarlo con el dueño de producto optamos por la primera de las opciones (algo más arriesgada). Si al final se lía la cosa el cliente como el equipo tendrán claro el por qué.

Selección de las historias del sprint
Estas 4 historias suman 12 puntos y solo tenemos 11 disponibles. Volvemos a encontrarnos con que no entran todas en el sprint. Sin embargo, esta vez, después de acaloradas discusiones entre el equipo y el dueño de producto, se decide aumentar el nivel de compromiso del equipo para que entren las cuatro historias en la iteración, por lo que las proximas entradas del blog serán:

  1. Principios ágiles #5. Importancia de la motivación de, la confianza hacia y el apoyo a las personas involucradas en el proyecto.
  2. How To: Primeros pasos con FitNesse. Mi primer ScreenCast. Espero que no sea el último :D Además, este ScreenCast lo añadiré al resumen de la reunión de Madrid para completarlo un poco más.
  3. Principios ágiles #6. Comunicación cara a cara como método más eficiente y efectivo para que fluya la información.
  4. How To: Mockeando llamadas asíncronas con easymock. ¿Os habéis planteado como hacer TDD con llamadas asíncronas? Intentaremos explicarlo en esta entrada.


Burndown
Por último, falta el burndown de la iteración. Iré actualizándolo regularmente con los avances :D



  1. Reunión Diaria (Scrum diario) del 28 de Enero: Al ser la primera, lo único que se hace es que cada miembro del equipo elija la tarea en la que quiere trabajar. Voy a intentar escribir la entrada sobre el quinto principio ágil. Al menos el primer borrador
  2. Reunión Diaria (Scrum Diario) del 29 de Enero
    • ¿Qué hiciste ayer? Comence con el quinto principio, pero avancé menos de lo que esperaba. Me quedan un par de horitas todavía
    • ¿Qué vas a hacer hoy? Hoy espero terminar la entrada
    • ¿Algún impedimento? No
  3. Reunión Diaria (Scrum Diario) del 30 de Enero
    • ¿Qué hiciste ayer? Nada :( Las cañas de los viernes pudieron al blog
    • ¿Qué vas a hacer hoy? Hoy espero terminar la entrada
    • ¿Algún impedimento? No
  4. Reunión Diaria (Scrum Diario) del 31 de Enero
    • ¿Qué hiciste ayer? Pues hice un poquito más de la entrada de los principios. pero aún le falta una horita
    • ¿Qué vas a hacer hoy? Nada
    • ¿Algún impedimento? No
  5. Reunión Diaria (Scrum Diario) del 1 de Febrero
    • ¿Qué hiciste ayer? Pues jugar al COD. Menudo vicio.
    • ¿Qué vas a hacer hoy? Hoy acabo la entrada sí o sí
    • ¿Algún impedimento? No
  6. Reunión Diaria (Scrum Diario) del 2 de Febrero
    • ¿Qué hiciste ayer? ¡Terminé la entrada!
    • ¿Qué vas a hacer hoy? Pues investigar un poco como va lo de los screencasts
    • ¿Algún impedimento? No
  7. Reunión Diaria (Scrum Diario) del 3 de Febrero
    • ¿Qué hiciste ayer? Pues al final no me dio tiempo a hacer nada.
    • ¿Qué vas a hacer hoy? Creo que tampoco me va a dar tiempo a hacer nada, pero igual preparo el guión del screencast
    • ¿Algún impedimento? No
  8. Reunión Diaria (Scrum Diario) del 4 de Febrero
    • ¿Qué hiciste ayer? Terminé el guión del screencast.
    • ¿Qué vas a hacer hoy? Hoy me voy de concierto, así que nada
    • ¿Algún impedimento? No
  9. Reunión Diaria (Scrum Diario) del 5 de Febrero
    • ¿Qué hiciste ayer? Nada
    • ¿Qué vas a hacer hoy? Hoy voy a ver a los Arctic Monkeys, así que nada
    • ¿Algún impedimento? No
  10. Reunión Diaria (Scrum Diario) del 8 de Febrero
    • ¿Qué hiciste ayer (y antes de ayer y antes de antes de ayer)? Pues no pude ponerme con el screencast porque vinieron invitados a casa pero al menos saqué tiempo para avanzar con el sexto principio ágil. Le queda una horia más a esa entrada.
    • ¿Qué vas a hacer hoy? Quiero intentar el screencast, a ver si tengo tiempo.
    • ¿Algún impedimento? No


Foto de "portada":  Galería de boo_licious en Flickr, bajo licencia Creative Commons.

lunes, 25 de enero de 2010

Retrospectiva #2




Bueno, pues parece que hemos terminado la primera iteración del ScrumBlog :D Vamos a "retrospectivar" un rato sobre dicha iteración.

¿Por donde empezamos?
Vamos a empezar calculando la velocidad del equipo y su eficacia. Para ello vamos a basarnos en el burndown de la iteración. Podemos ver que la velocidad del equipo se corresponde a 11 puntos de historia y su eficacia es de un 100%. Estos datos nos servirán como base para la próxima planificación.

Parece que ha sido una buena iteración ¿no? Veamos que opina el equipo (Como ya hicimos en la retrospectiva anterior, vamos a hacer a basarnos en 3 preguntas para llevar la retro).

¿Qué nos ha gustado de este sprint y queremos seguir haciendo?
  • El compromiso. Ha sido "duro", pero ha merecido la pena.
  • Por fin hemos metido una historia técnica. No se si os habrá gustado, a mi sí :D. Me parece una idéa muy interesante, la verdad. Además, el tener una historia técnica me ha servido para iniciarme en git.

¿Qué estamos haciendo mal?
  • La priorización de las historias. No puede ser que la segunda historia más prioritaria no pueda empezarse hasta un par de días antes del final de la iteración
  • Aunque hemos aumentado la tasa de entradas, sigue siendo un poco baja.
  • Los Scrum diarios no han sido tan diarios :D Ha sido un poco despendole...
  • La plantilla del blog no permite leer bien el código :(

Acciones
  • Las historias bloqueantes hay que priorizarlas teniendo en cuenta dicho bloqueo.
  • Fijar una hora para realizar el Scrum diario. Si es posible, por la mañana
  • Modificar la plantilla del blog para que el código se pueda leer decentemente.

¡Que poquitos problemas! :D Se nota que esta primera iteración ha salido bien. Veremos las siguientes...
Si queréis proponerme algún tema para la próxima iteración dejad un comentario en la entrada antes de la planificación de mañana :D De momento, en lo más alto de la pila están el quinto principio ágil y una introducción a FitNesse.

jueves, 21 de enero de 2010

11º Encuentro Agile-Madrid. Definition of Done (Pruebas de aceptación automatizadas)


Entre todos los asistentes a la reunión hemos creado un resumen en el sitio google del grupo. Leedlo antes de continuar :D

Dado que el resumen ya está hecho, voy a escribir un poco qué supuso para mi la reunión.

Preparativos
En un principio, mi labor para esta reunión era preparar un ejemplo de automatización de pruebas de aceptación en FitNesse y presentarlo (Tengo que decir que, aunque conocía FitNesse, nunca lo había usado y, esta reunión me ha servido para aprender un poco de que va ese rollo :D Me ha gustado bastante y puede que para la próxima iteración del blog escriba un "How To" sobre FitNesse).
Unos días antes de la reunión, José Manuel Beas me dijo que no iba a poder ir y me pidió que me encargarse yo de la charla. Me cedió tanto la presentación como el ejemplo de Concordion que iba a presentar.
No estoy acostumbrado a hablar en público y soy bastante tímido, así que me puse un poco nervioso. Aún así, el tema era muy chulo y me apetecía hablar de él, por lo que acepté :)

El encuentro
Acudimos unas 20 personas, entre las que había bastantes caras nuevas (lo que aumentó el miedo escénico :D). No se lo que piensan los demás, pero para mi la reunión fue bastante entretenida (Me sentí bastante cómodo mientras casi improvisaba la presentación) y la gente debatió bastante. Como ya he dicho, el resumen podéis leerlo en el sitio del grupo, pero os apunto las conclusiones a las que llegamos por si sois un poco vagos :P

  • Las pruebas de aceptación deben comprobar las reglas de negocio (Qué y no cómo).
  • Las pruebas de aceptación deben producirse mediante la colaboración de cliente y equipo (Negocio y desarrollo juntos).
  • Es deseable que las pruebas de aceptación se escriban antes que el desarrollo, ya que ayuda a focalizar dicho desarrollo.
  • Utilizar un framework que ayude a automatizar las pruebas de aceptación es deseable.
  • Entre Concordion y FitNesse no sabemos con cual quedarnos. Ambos tienen aspectos positivos y negativos. Probadlos y decidid :D

Futuro
El haber dado esta charla me ha enseñado que no es tan duro hablar delante de la gente. Te puede salir mejor o peor, pero lo importante es compartir. La verdad es que me he animado bastante y creo que voy a proponer alguna charla más e, incluso, algún taller (A ver si hablo con Alfredo Casado y organizamos algo de TDD, que ya me lo ha dicho un par de veces. José Manuel Beas quiere montar uno sobre Concordion y creo que estaría muy bien).
Además, después de haber entrado un poco más a fondo en las pruebas de aceptación, queremos empezar a utilizar algún framework para automatizar las pruebas de aceptación en mi trabajo. Yo me decanto por FitNesse, que me parece más sencillo de cara a un usuario no técnico, pero algún que otro compañero prefiere Concordion. ¿Que haremos? De momento creo que vamos a probar FitNesse porque me voy a encargar yo de hacer esas pruebas :D Ya os contaré nuestros avances y nuestros problemas.

Animaos y venir a las reuniones, a los coding-dojos, a los talleres, etc. Son gratis y de verdad que merecen la pena.

domingo, 17 de enero de 2010

How To: Contract Tests (Pruebas de Contrato)


El diseño de un API es un problema bastante complejo. Hay que tener multitud de cosas en mente (modularidad, escalabilidad, extensibilidad, usabilidad, simpleza, etc). Si os interesa el tema os recomiendo este libro de Jaroslav Tulach (uno de los arquitectos de NetBeans). Es un libro difícil, como el problema que aborda, pero muy bueno.
En dicho libro conocí el concepto de Contract Tests(Pruebas de Contrato). Sin embargo, aunque me pareció una buena idea, no le dí mucha importancia en aquel momento (hace un año, aproximadamente). Antes de fin de año, J.B. Rainsberger twitteaba el vídeo de Ben Rady escribiendo Contract Tests en Junit 4 y todo el tema volvió a mi cabeza.

¿Qué son las Pruebas de Contrato?
J.B. Rainsberger lo explica en este artículo (Que escribió en el 2005, menudo crack). Básicamente, las Pruebas de Contrato son una batería de pruebas que especifican el comportamiento de un determinado interfaz (o clase abstracta). Cualquier implementación de dicho interfaz (o cualquier clase derivada de la clase abstracta) debe superar dicha batería de pruebas para ser considerada correcta.

¿Qué problema resuelven las Pruebas de Contrato?
Normalmente, cuando se crea un interfaz (o una clase abstracta) es para que tenga varias implementaciones (o clases derivadas). Sucede lo mismo con un API, puede tener más de una implementación pero un único interfaz.
Si no se define un comportamiento general, es posible que las implementaciones no sean intercambiables entre sí, violando así el principio de sustitucion de Liskov y, lo que es más importante, dejando a los clientes de dicho interfaz con el culo al aire. Dicho comportamiento es lo que se define como contrato. Podemos escribir dicho contrato como un documento más, con los problemas que ello conlleva (Código y documentación desincronizada, interpretaciones subjetivas de lo escrito, etc) o podemos escribir dicho contrato mediante pruebas.

¿Por qué me interesan las Pruebas de Contrato?
Imagino que estaréis pensando:

Vaya chapa nos está metiendo el Peña.

Así que voy a contaros un poco mi motivación. Mi pensamiento tras ver el vídeo de Ben Rady fue:

¡Coño! Que bueno. Si lo hubiera aplicado antes a mi proyecto ahora sería mucho más feliz.

El proyecto actual de mi equipo consiste en diseñar (e implementar, testear, etc. Nada de waterfallismo :D )un API y crear varias implementaciones de dicho API (y diseñarlas, testearlas, etc. :D ).
Cuando comenzó el proyecto no le dimos importancia a esto de las Pruebas de Contrato (Sobre todo por desconocimiento). Tampoco pasaba nada, solo existía una implementación para la cual teníamos una batería de pruebas.
Más adelante añadimos una segunda implementación y, en lugar de convertir los test de la anterior implementación en Pruebas de Contrato, hicimos un corta-pega del demonio (Me da vergüenza escribir esto, pero de los errores se aprende).
No os recomiendo este enfoque :D Las pruebas huelen a DRY que tiran de espaldas.
Además, aceptamos pequeños cambios en el comportamiento de las implementaciones ya que, al definir el contrato en un wiki en lugar de hacerlo con pruebas, malinterpretamos ciertos detalles (algunas veces a propósito :S ).
Le he planteado al equipo que, las nuevas pruebas funcionales que creemos sean Pruebas de Contrato, a ver si conseguimos eliminar duplicaciones.
NOTA: Tengo que aclarar que estoy muy contento con la marcha del proyecto :D Lo que pasa es que mi nivel de exigencia aumenta cada mes. De hecho, nuestro equipo es famoso por lo mal que habla de su propio código, estando dicho código bastante por encima de la media. Somos un equipo muy autoexigente y muy autocrítico.

Un caso práctico: El interfaz Collection con JUnit 4
Después de todo este rollo, vamos a la chicha.

Vamos a hacer unas Pruebas de Contrato para el interfaz Collection (No vamos a hacer el contrato entero porque nos puede dar un chungo).
Normalmente, las Pruebas de Contrato se añaden al proyecto que contiene los intefaces a definir. Las clases que ejecutan las pruebas para cada implementación se añaden al proyecto que contiene dicha implementacion. Como yo no tengo acceso a dichos proyectos, me he creado uno propio. He metido todas las clases en ese proyecto, pero he hecho una separación en paquetes para que entendáis un poco la distribución de las clases. Podéis verlo aquí (Es de NetBeans. A mi me gusta mucho, pero Xavi Gost me diría que madurara... Aún así, es tan sencillito que no creo que de problemas :D ).

Lo primero es crear una clase abstractra que contenga todos los test de contrato y un método abstracto que devuelva un objeto Collection. Yo he hecho la siguiente:



Como podéis ver, el método nuevaColeccion se llama en el setUp para no tener que escribirlo en cada prueba. Además, dicho setUp es final para que no pueda ser sobreescrito por las clases hijas.

Si ahora lanzamos las pruebas obtenemos el siguiente resultado:



Si os fijáis, la clase abstracta que hemos creado no termina en Test, así que JUnit 4 no la tiene en cuenta a la hora de ejecutar las pruebas.

Ahora vamos a probar las implementaciones. Empezamos por ArrayList, para lo que añadimos la siguiente clase:



Lo mismo para HashSet:



Si ahora pasamos las pruebas obtenemos:



¡Bien! Pasan todas las pruebas :D Eso quiere decir que ambas implementaciones cumplen con el contrato y todos somos un poco más felices.
Hay que destacar que las pruebas se están contabilizando en cada clase de prueba de cada implementación (Todas las Pruebas de Contrato se ejecutan en ArrayListTest y en HashSetTest). A la hora de contabilizar pruebas la clase base no existe :D

Vamos a ponérselo un poco más difícil a las implementaciones. Añadimos la siguiente prueba a la clase que define el contrato:



Si ahora pasamos las pruebas de las implementaciones obtenemos:



¿Rojo? mmmmm Huele a violación de los principios S.O.L.I.D.
La implementación HashSet no supera la nueva prueba que hemos añadido. Hemos definido un contrato demasiado estricto y algunas implementaciones no lo soportan.
En este caso, no podemos suponer lo que hará una colección cuando se le añada el mismo objeto varias veces. Depende de la clase derivada. Claramente, las implementaciones de Collection violan el principio de Liskov :D

Podríamos seguir añadiendo pruebas y tal, pero imagino que ya ha quedado más o menos claro ¿No? Ya veis que no sería muy complicado organizar las pruebas que ya tenemos para obtener unas cuantas Pruebas por Contrato. Espero poder hacerlo en mi equipo :D (Me temo que esto es deuda técnica).

Conclusiones
  • Las Pruebas de Contrato son una especificación del API.
  • Las Pruebas de Contrato se pueden usar como documentación del interfaz. La documentación escrita en prosa "a la antigua usanza" es mucho más fácil de malinterpretar.
  • El contrato puede ser todo lo estricto que queramos. Hay que aplicar el sentido común para saber cuando parar.
  • Mediante Pruebas de Contrato eliminamos duplicidad de código de test. Las pruebas hay que seguir escribiéndolas tengamos o no Pruebas de Contrato y, escribir las mismas (o parecidas) en cada una de las implementaciones es una perdida de tiempo y un infierno a la hora de mantenerlas (lo digo por experiencia).
  • Definir unas Pruebas por Contrato puede ayudarnos a descubrir problemas de diseño en el API. Una violación del principio de Liskov es un problema en el API

Esto es todo amigos. Espero que os haya gustado mi primera entrada técnica :D

Foto de "portada": Galería de Mark, bajo licencia Creative Commons

miércoles, 13 de enero de 2010

Principios Ágiles #4


Siguiendo con la temática de los principios ágiles, hoy voy a hablar del cuarto de ellos:





Business people and developers must work together daily throughout the project.
La gente de negocio y los desarrolladores deben trabajar de forma conjunta diariamente a lo largo del proyecto.


¿Gente de Negocio y gente de desarrollo?
Cuando se comienza un nuevo proyecto es lógico que el equipo de desarrollo (encargado de implementar una solución) no sea experto en el negocio del cliente. Por otro lado, un experto de negocio (encargado de explicar las reglas de negocio) casi nunca se interesará por el aspecto técnico (desde luego, ninguno que yo conozca). Ambos mundos están bastante separados, al menos sobre el papel, lo que provoca que sean incapaces de entenderse. No poseen un lenguaje común.

¿Por qué trabajar juntos de forma conjunta?
Obligar a que ambos mundos trabajen juntos de forma continua provoca que la separación entre ambos se reduzca. Obviamente, el objetivo no es que un desarrollador se convierta en un experto de negocio ni viceversa. Siempre existirá una cierta separación. El objetivo es construir un lenguaje común mediante el cual ambos grupos consigan entenderse y resolver sus dudas. Actualmente en el mundo ágil, dicho lenguaje común se plasma sobre todo en las pruebas de aceptación, definidas por la gente de negocio con ayuda del equipo técnico (Si queréis saber más sobre pruebas de aceptación pasaos por la próxima reunión de Agile-Spain Madrid).
Cuando ambos grupos empiezan a colaborar se empieza a reducir la brecha que los separa. Comienza a aparecer un sentimiento de equipo y una visión global del producto.

¿Por qué diariamente?
No vale con reuniones esporádicas, debe ser un esfuerzo continuo. No vale que los grupos se reunan una vez al mes para tratar ciertos temas y que después cada uno se marche a su cubículo. Si un desarrollador se encuentra con que tiene que tomar una decisión de negocio debe acudir a los expertos de negocio para que se la resuelvan. Si un experto de negocio quiere conocer que tal va el desarrollo de una funcionalidad X debe acudir al desarrollador para que le informe. Obviamente, esta colaboración no se puede llevar a cabo sin confianza y transparencia. No me sirve de nada que los desarrolladores estén siempre disponibles para el experto de negocio pero le mientan sobre el estado del proyecto.
Este trabajo diario no es sencillo de llevar a cabo. Muchas veces los desarrolladores no queremos levantar la cabeza del ordenador. Otras muchas los expertos de negocio no tienen tiempo (ni ganas) de reunirse con los "frikis". Por eso, es necesario un compromiso por ambas partes. Si alguno de los dos no se compromete se deja de ser ágil.

Conclusiones
El cuarto principo ágil:

  • Busca que la gente de  negocio y la gente técnica hablen un lenguaje común que favorezca el entendimiento.
  • Refuerza el sentimiento de equipo aumentando la confianza entre sus componentes.
  • Implica compromiso.
  • Obliga a la transparencia.
Imagen de "portada": Galería de thinkpublic, bajo licencia Creative Commons.