For all of you who don't know what autotest is, it's just a ruby gem that lets you run your tests automatically in the background every time you make a change either in your code or in your tests. It is very clever, and a lot of people use it. You can see some examples in almost every screencast of a kata written in ruby.
Why I don't like autotest
Well, it's not that I don't like it. It is a very cool project and I've used it sometimes while performing a kata. My real problem with it is that it breaks the TDD cycle. Let me explain myself.
Running the test should be a blocking step
When we are doing TDD, we run the tests to get feedback. Then, we use that feedback to guide our code/design.
When we use autotest we are not waiting for the tests to fail, we just continue coding, ruining the TDD cycle.
Wait a second, I do not write any code till autotest tells me that there is a failing test.
Well done. Why are you using autotest then?
Update: Talking with Tom Brand the other day, he said that maybe it is ok to use autotest in the refactoring phase. I think he is right :)
Mostrando entradas con la etiqueta TDD. Mostrar todas las entradas
Mostrando entradas con la etiqueta TDD. Mostrar todas las entradas
domingo, 15 de mayo de 2011
miércoles, 24 de noviembre de 2010
Más sobre S.O.L.I.D.
En el último post os intenté convencer de que habíamos conseguido no violar el principio de inversión de dependencias con nuestra clase Banco. Si no lo recordáis, nos quedó algo como esto:
José Luis Barrera me sugirió en los comentarios que utilizáramos una clase Credenciales que agrupara tanto el nombre del usuario como el Pin. Con esa nueva abstracción, el código de Banco queda aún más claro:
Guay :D
Ahora bien, ¿qué ocurre cuando la validación de las Credenciales falla? Tal y como tenemos ahora mismo nuestra implementación, OperacionesBancarias lanzaría una excepción por cada tipo de error que se produzca al validar el usuario. Por ejemplo, si lo que falla es que las Credenciales son incorrectas se produce una excepción CredencialesIncorrectas. Si lo que sucede es que la validación de las Credenciales ha sido fallida más de tres veces, la excepción que se lanza es una AccesoInvalidadoPorMultiplesReintentosFallidos. Si lo que se produce es un error en el acceso al banco real, se lanzará un BancoInaccesible.
Veamos como implementaríamos un cliente de Banco (un Cajero) que se preocupe del resultado de la validación:
Pues no parece que sea muy legible... No se vosotros, pero yo estoy bastante acostumbrado a este tipo de código y tengo que decir ¡basta ya!
Las excepciones que captura Cajero no son parte de la abstracción de Banco, son detalles de bajo nivel que se encuentran en OperacionesBancariasBancoManolito, con lo que estamos volviendo a violar el principio de inversión de dependencias. Además, estamos controlando el flujo del programa mediante excepciones. ¡Que desastre!
Las excepciones deberían ser para casos excepcionales
Como bien nos contó (recordó) Enrique Comba en el curso de T.D.D., las excepciones deben ser excepcionales. No tiene sentido usarlas para controlar el flujo porque, en ese caso, dejan de ser excepcionales. Esto que parece tan trivial es una de las cosas que más nos cuesta cuando nos ponemos a programar.
Con esto en mente, volvamos a nuestro ejemplo, ¿Es excepcional que unas Credenciales sean incorrectas? ¿Es excepcional que un Banco tenga que anular una tarjeta porque el usuario se ha equivocado n veces al intentar usarla? De nuestro ejemplo, el único caso "excepcional" puede ser que el banco real no esté accesible pero ¿de verdad es tan raro que haya un corte de comunicaciones? Para mi, ninguno de estos casos es merecedor de una excepción, así que vamos a intentar arreglarlo. Lo primero que vamos a hacer es que Cajero no dependa de los detalles de OperacionesBancariasBancoManolito (y si de paso evitamos controlar el flujo con excepciones, mejor que mejor). Para ello, vamos a pasarle al Banco la responsabilidad de avisar al Cajero cuando suceda un evento de validación (correcta, incorrecta, invalida, sin conexión). Refatorizamos nuestro Banco para que quede como sigue:
y nuestro Cajero ahora queda mucho más limpio:
Aunque nuestra clase Cajero ha quedado mucho más clara, hemos pasado el problema de las excepciones a la clase Banco. Además, estamos violando el principio de segregación de interfaces (I). Vayamos paso a paso.
Segregación de interfaces
Para cumplir este principio, nuestra clase Cajero debe implementar un interfaz para manejar los eventos de validación, que es lo único que la clase Banco necesita conocer de Cajero:
Y nuestra clase Banco dejaría de depender de Cajero para depender de dicho interfaz:
Ahora que nuestra clase Cajero ya cumple el principio de segregación de interfaces, arreglemos Banco.
La solución que se me ha ocurrido es que sea la abstracción Token la que nos de la información que actualmente nos dan las excepciones:
Ahora el flujo ya no es guiado por excepciones pero, lo que me parece más importante aún, es que nuestro código ahora es más sencillo de extender. Antes necesitábamos ir a un javadoc (o similar) para leer que tipo de excepciones eran necesarias para que Banco funcionara, ahora basta con implementar Token.
Por último, tengo que decir que no me gustan las estructuras if-elseif-elseif-else, pero para este caso en particular no me parece tan horrible. Si los motivos por los que Token puede no ser válido fueran más o pudieran cambiar más a menudo me pensaría una solución con suscriptores similar a la que hemos utilizado con el Cajero. Si os apetece hacerlo os lo dejo como ejercicio :P
Perdonad que me haya quedado una entrada tan larga y atolondrada. Espero que al menos se entienda lo que he intentado expresar :D ¡Nos vemos en la siguiente!
Nota: No haría estas refactorizaciones que he hecho aquí si no tuviera una buena base de pruebas contra las que probar cada pasito.
José Luis Barrera me sugirió en los comentarios que utilizáramos una clase Credenciales que agrupara tanto el nombre del usuario como el Pin. Con esa nueva abstracción, el código de Banco queda aún más claro:
Guay :D
Ahora bien, ¿qué ocurre cuando la validación de las Credenciales falla? Tal y como tenemos ahora mismo nuestra implementación, OperacionesBancarias lanzaría una excepción por cada tipo de error que se produzca al validar el usuario. Por ejemplo, si lo que falla es que las Credenciales son incorrectas se produce una excepción CredencialesIncorrectas. Si lo que sucede es que la validación de las Credenciales ha sido fallida más de tres veces, la excepción que se lanza es una AccesoInvalidadoPorMultiplesReintentosFallidos. Si lo que se produce es un error en el acceso al banco real, se lanzará un BancoInaccesible.
Veamos como implementaríamos un cliente de Banco (un Cajero) que se preocupe del resultado de la validación:
Pues no parece que sea muy legible... No se vosotros, pero yo estoy bastante acostumbrado a este tipo de código y tengo que decir ¡basta ya!
Las excepciones que captura Cajero no son parte de la abstracción de Banco, son detalles de bajo nivel que se encuentran en OperacionesBancariasBancoManolito, con lo que estamos volviendo a violar el principio de inversión de dependencias. Además, estamos controlando el flujo del programa mediante excepciones. ¡Que desastre!
Las excepciones deberían ser para casos excepcionales
Como bien nos contó (recordó) Enrique Comba en el curso de T.D.D., las excepciones deben ser excepcionales. No tiene sentido usarlas para controlar el flujo porque, en ese caso, dejan de ser excepcionales. Esto que parece tan trivial es una de las cosas que más nos cuesta cuando nos ponemos a programar.
Con esto en mente, volvamos a nuestro ejemplo, ¿Es excepcional que unas Credenciales sean incorrectas? ¿Es excepcional que un Banco tenga que anular una tarjeta porque el usuario se ha equivocado n veces al intentar usarla? De nuestro ejemplo, el único caso "excepcional" puede ser que el banco real no esté accesible pero ¿de verdad es tan raro que haya un corte de comunicaciones? Para mi, ninguno de estos casos es merecedor de una excepción, así que vamos a intentar arreglarlo. Lo primero que vamos a hacer es que Cajero no dependa de los detalles de OperacionesBancariasBancoManolito (y si de paso evitamos controlar el flujo con excepciones, mejor que mejor). Para ello, vamos a pasarle al Banco la responsabilidad de avisar al Cajero cuando suceda un evento de validación (correcta, incorrecta, invalida, sin conexión). Refatorizamos nuestro Banco para que quede como sigue:
y nuestro Cajero ahora queda mucho más limpio:
Aunque nuestra clase Cajero ha quedado mucho más clara, hemos pasado el problema de las excepciones a la clase Banco. Además, estamos violando el principio de segregación de interfaces (I). Vayamos paso a paso.
Segregación de interfaces
Clients should not be forced to depend upon interfaces that they do not use.
Los clientes no deben verse forzados a depender de interfaces que no usan.
Para cumplir este principio, nuestra clase Cajero debe implementar un interfaz para manejar los eventos de validación, que es lo único que la clase Banco necesita conocer de Cajero:
Y nuestra clase Banco dejaría de depender de Cajero para depender de dicho interfaz:
Ahora que nuestra clase Cajero ya cumple el principio de segregación de interfaces, arreglemos Banco.
La solución que se me ha ocurrido es que sea la abstracción Token la que nos de la información que actualmente nos dan las excepciones:
Ahora el flujo ya no es guiado por excepciones pero, lo que me parece más importante aún, es que nuestro código ahora es más sencillo de extender. Antes necesitábamos ir a un javadoc (o similar) para leer que tipo de excepciones eran necesarias para que Banco funcionara, ahora basta con implementar Token.
Por último, tengo que decir que no me gustan las estructuras if-elseif-elseif-else, pero para este caso en particular no me parece tan horrible. Si los motivos por los que Token puede no ser válido fueran más o pudieran cambiar más a menudo me pensaría una solución con suscriptores similar a la que hemos utilizado con el Cajero. Si os apetece hacerlo os lo dejo como ejercicio :P
Perdonad que me haya quedado una entrada tan larga y atolondrada. Espero que al menos se entienda lo que he intentado expresar :D ¡Nos vemos en la siguiente!
Nota: No haría estas refactorizaciones que he hecho aquí si no tuviera una buena base de pruebas contra las que probar cada pasito.
Etiquetas:
dirigidoportests,
pair programming,
SOLID,
TDD
jueves, 18 de noviembre de 2010
Violando la D de S.O.L.I.D
A principios de semana tuve la suerte de asistir al curso de TDD que impartió Enrique Comba en Madrid. Me lo pasé genial pero me fui aún más convencido de que programar es muy difícil.
Aunque el temario del curso fue bastante amplio, yo sólo voy a centrarme en los principios S.O.L.I.D. Si queréis saber más sobre lo que hicimos allí, Jesús Jiménez ha escrito este post explicándolo.
El primer día del curso, Enrique nos dividió en 5 grupos y nos asignó la exposición de un principio S.O.L.I.D. a cada equipo. A nosotros (Amalia Hernandez, Jesús Jiménez, Leo Antolí y yo) nos tocó explicar la D.
Inversión de Dependencias (D)
Cuéntamelo con código
El segundo día lo dedicamos a crear el software que controla un cajero automático (haciendo T.D.D., claro). El código que creó nuestro equipo (los mismos cuatro que el día anterior) lo tenéis completo aquí, pero yo me voy a centrar sólo en nuestra implementación de la clase Banco:
Lo que hace la clase Banco es realizar una petición de validación mediante el Conector a una url. Dicha validación nos devuelve un json a partir del cual se puede crear el token de seguridad con el que se realizarán las siguientes operaciones del usuario validado.
¿Habremos sido capaces de respetar el principio que nos tocó explicar el día anterior?
Los módulos de alto nivel (Banco) no deben depender de módulos de bajo nivel(Implementaciones de Conector y GeneradorToken), ambos deben depender de abstracciones. Nuestro Banco depende de la abstracción Conector y de la abstracción GeneradorToken, pero no "conoce" que implementación de cada abstracción está usando (Ambas se le inyectan en el constructor). Parece que esta parte es correcta.
Las abstracciones (Banco) no deben depender de detalles. Los detalles deben depender de abstracciones. En esta parte es donde hemos metido la pata. Si Banco no debe depender de detalles ¿Qué pinta la construcción de la url contra la que debe operar el Conector? ¿Por qué el Banco conoce que el Conector devuelve json?
Pensando en esto se me ocurre el siguiente refactor de Banco:
Nuestro módulo de alto nivel depende ahora de una abstracción más general, dejándole a los módulos de bajo nivel (Las implementaciones de OperacionesBancarias) todo lo que tiene que ver con la infraestructura (tipo de comunicación, transformación de la respuesta, etc). Pero, ¿no es el token un detalle de bajo nivel? Si la respuesta es afirmativa deberíamos eliminarlo de Banco y OperacionesBancarias devolvería directamente la Cuenta, haciendo que nuestra clase Banco fuera redundante. Sin embargo, yo (que soy el que está programando :P ) creo que cualquier autenticación bancaria me va a devolver un token (hablo desde la ignorancia, pero suena bien) con lo que deja de ser un detalle para formar parte de la abstracción. Eso sí, no estaría mal que fuera una clase Token en lugar de un String, que no todos los tokens tienen porque ser iguales. La clase Banco que no viola el principio de inversión de dependencias quedaría así:
Conclusiones
Yo ya conocía los principios S.O.L.I.D. y se que mis compañeros también (aunque de este código tenemos la culpa Leo y yo :D ). Nos habíamos preocupado de leerlos y de intentar entenderlos mucho antes de dar este curso. Entonces, ¿por qué no fuimos capaces de recordar la dichosa D. incluso habiendo tenido que explicarla el día anterior? Yo pienso que es porque no lo tenemos interiorizado. Hace falta mucha práctica y mucha experiencia trabajando con los principios S.O.L.I.D. en la cabeza para que no se te olviden mientras programas. Por eso considero importante practicar T.D.D. con ejemplos sencillos, porque lo importante no es resolver el problema, lo importante es el proceso mental con el que resuelves el problema.
Criticadme, por favor
Lo que os he contado en este artículo es como entiendo yo el principio de inversión de dependencias. ¿Coincide con lo que entendéis vosotros? Si no es así, ¿en que me he equivocado?
Aunque el temario del curso fue bastante amplio, yo sólo voy a centrarme en los principios S.O.L.I.D. Si queréis saber más sobre lo que hicimos allí, Jesús Jiménez ha escrito este post explicándolo.
El primer día del curso, Enrique nos dividió en 5 grupos y nos asignó la exposición de un principio S.O.L.I.D. a cada equipo. A nosotros (Amalia Hernandez, Jesús Jiménez, Leo Antolí y yo) nos tocó explicar la D.
Inversión de Dependencias (D)
High level modules should not depend upon low level modules. Both should depend upon abstractions
Abstractions should not depend upon details. Details should depend upon abstractions
Los módulos de alto nivel no deberían depender de módulos de bajo nivel. Ambos deberían depender de abstracciones
Las abstraccciones no deberían depender de los detalles. Los detalles deberían depender de las abstracciones
Cuéntamelo con código
El segundo día lo dedicamos a crear el software que controla un cajero automático (haciendo T.D.D., claro). El código que creó nuestro equipo (los mismos cuatro que el día anterior) lo tenéis completo aquí, pero yo me voy a centrar sólo en nuestra implementación de la clase Banco:
Lo que hace la clase Banco es realizar una petición de validación mediante el Conector a una url. Dicha validación nos devuelve un json a partir del cual se puede crear el token de seguridad con el que se realizarán las siguientes operaciones del usuario validado.
¿Habremos sido capaces de respetar el principio que nos tocó explicar el día anterior?
Los módulos de alto nivel (Banco) no deben depender de módulos de bajo nivel(Implementaciones de Conector y GeneradorToken), ambos deben depender de abstracciones. Nuestro Banco depende de la abstracción Conector y de la abstracción GeneradorToken, pero no "conoce" que implementación de cada abstracción está usando (Ambas se le inyectan en el constructor). Parece que esta parte es correcta.
Las abstracciones (Banco) no deben depender de detalles. Los detalles deben depender de abstracciones. En esta parte es donde hemos metido la pata. Si Banco no debe depender de detalles ¿Qué pinta la construcción de la url contra la que debe operar el Conector? ¿Por qué el Banco conoce que el Conector devuelve json?
Pensando en esto se me ocurre el siguiente refactor de Banco:
Nuestro módulo de alto nivel depende ahora de una abstracción más general, dejándole a los módulos de bajo nivel (Las implementaciones de OperacionesBancarias) todo lo que tiene que ver con la infraestructura (tipo de comunicación, transformación de la respuesta, etc). Pero, ¿no es el token un detalle de bajo nivel? Si la respuesta es afirmativa deberíamos eliminarlo de Banco y OperacionesBancarias devolvería directamente la Cuenta, haciendo que nuestra clase Banco fuera redundante. Sin embargo, yo (que soy el que está programando :P ) creo que cualquier autenticación bancaria me va a devolver un token (hablo desde la ignorancia, pero suena bien) con lo que deja de ser un detalle para formar parte de la abstracción. Eso sí, no estaría mal que fuera una clase Token en lugar de un String, que no todos los tokens tienen porque ser iguales. La clase Banco que no viola el principio de inversión de dependencias quedaría así:
Conclusiones
Yo ya conocía los principios S.O.L.I.D. y se que mis compañeros también (aunque de este código tenemos la culpa Leo y yo :D ). Nos habíamos preocupado de leerlos y de intentar entenderlos mucho antes de dar este curso. Entonces, ¿por qué no fuimos capaces de recordar la dichosa D. incluso habiendo tenido que explicarla el día anterior? Yo pienso que es porque no lo tenemos interiorizado. Hace falta mucha práctica y mucha experiencia trabajando con los principios S.O.L.I.D. en la cabeza para que no se te olviden mientras programas. Por eso considero importante practicar T.D.D. con ejemplos sencillos, porque lo importante no es resolver el problema, lo importante es el proceso mental con el que resuelves el problema.
Criticadme, por favor
Lo que os he contado en este artículo es como entiendo yo el principio de inversión de dependencias. ¿Coincide con lo que entendéis vosotros? Si no es así, ¿en que me he equivocado?
Etiquetas:
dirigidoportests,
pair programming,
SOLID,
TDD
martes, 29 de diciembre de 2009
El coding dojo de agilismo.es
Por fin tengo un ratito durante las fiestas para hablar del coding dojo que organizó agilismo.es. Fue en Okuri Spaces y fueron ayudados por Autentia (que, ademas de encargarse de la grabación del evento, nos pusieron unas cocacolas y unas pastas muy ricas).
Como he tardado unos días en escribir esto (lo siento, las comidas y cenas navideñas me han dejado KO) algunos de los asistentes ya han escrito sobre el tema. Podéis leer la opinión de Alfredo Casado y la de David Bonilla. Coincido con ellos en todo. Fue muy divertido y os recomiendo a todos que acudáis a los eventos de este estilo que se organicen cerca vuestra. No os vais a arrepentir.
De todas formas, como soy un pesado, voy a contar como fue el evento para mi.
Presentación del problema del pomodoro
agilismo.es preparó una kata nueva para este evento. Dicha kata consistía en crear una clase que representara un reloj pomodoro que sirviera para utilizarla en la técnica del pomodoro. Nos dieron unas especificaciones y nos pidieron que hicieramos dos equipos de voluntarios para codificar el pomodoro. Hay que señalar que había que hacerlo en Java sobre eclipse y haciendo TDD. Esto frenó a muchos de los asistentes pero 9 "valientes" nos animamos a mostrar nuestro Kung-Fu (Copyright de Xavi Gost). El primer equipo comenzaría el trabajo y el segundo continuaría por donde lo dejó el primero.
Aquí podéis ver al primero de los equipos planeando la estrategía:
Los equipos dandole caña
Mi equipo fue el primero en entrar en acción. La idea era hacer programación por parejas de forma que uno de los dos componentes de la pareja hacía un test (Piloto) y el otro codificaba lo necesario para que el test pasara (Copiloto). Cada 5 minutos el piloto desalojaba, el copiloto se convertía en piloto y otro componente del equipo entraba como copiloto. Tengo que decir que contábamos con la ventaja de tener en nuestras filas a uno de los miembros de agilismo.es, José Manuel Beas, lo que nos ayudo a comenzar algo más rápido. Conseguimos crear pomodoros y asignarles una duración, aunque nos pusieron alguna pega por utilizar un operador ternario :D
No nos fue mal hasta que llegamos a la parte complicada del ejercicio, que era la parte en la que debíamos controlar que el tiempo del pomodoro se agotaba...
Nos quedamos atrancadillos y les dejamos el marrón al segundo equipo que, al menos, fue capaz de volver a tener todos los test en verde.
La kata ejecutada por los maestros
Después de que los equipos hiciéramos lo que pudimos (no fue mucho, la verdad). José Manuel Beas se puso a los mandos del portátil para realizar el ejercicio en modo kata mientras Xavi Gost nos comentaba las discusiones de diseño que habían ido teniendo mientras preparaban el programa. Hay que decir que Beas tardo menos de 20 minutos en realizar el ejercicio y que lo enseñaron funcionando. Doy fe :P Se que van a subir el vídeo de la kata. Cuando esté actualizaré el post con el enlace. De momento os tendréis que fiar de mi :)
Además del vídeo de la kata creo que también iban a colgar el vídeo del evento. Cuando lo cuelguen actualizaré el post con el enlace y podréis ver a los equipos desplegar nuestro Kung-Fu, todo amenizado con los comentarios/puyas de Xavi (menudo crack). De momento podéis echarle un ojo a las fotos que han subido los chicos de Okuri Spaces aquí (Algunas os las he mostrado en el resumen) y al vídeo-montaje que han realizado los chicos de Autentia con todos los asistentes al evento.
En fin, fue un evento muy divertido. Espero que se organicen más. Mejoraré mi Kung-Fu para la próxima :D
Para mi fue todavía más molón porque Jose Manuel Beas me regalo esto:
Toma pulsera de Clean Code :D Pedazo regalo de navidad.
En cuanto a la Pomodoro-Kata, prometo darle caña y mejorarla :P A ver si consigo picar a Alfredo y la hacemos en pareja.
Como he tardado unos días en escribir esto (lo siento, las comidas y cenas navideñas me han dejado KO) algunos de los asistentes ya han escrito sobre el tema. Podéis leer la opinión de Alfredo Casado y la de David Bonilla. Coincido con ellos en todo. Fue muy divertido y os recomiendo a todos que acudáis a los eventos de este estilo que se organicen cerca vuestra. No os vais a arrepentir.
De todas formas, como soy un pesado, voy a contar como fue el evento para mi.
Presentación del problema del pomodoro
agilismo.es preparó una kata nueva para este evento. Dicha kata consistía en crear una clase que representara un reloj pomodoro que sirviera para utilizarla en la técnica del pomodoro. Nos dieron unas especificaciones y nos pidieron que hicieramos dos equipos de voluntarios para codificar el pomodoro. Hay que señalar que había que hacerlo en Java sobre eclipse y haciendo TDD. Esto frenó a muchos de los asistentes pero 9 "valientes" nos animamos a mostrar nuestro Kung-Fu (Copyright de Xavi Gost). El primer equipo comenzaría el trabajo y el segundo continuaría por donde lo dejó el primero.
Aquí podéis ver al primero de los equipos planeando la estrategía:
Imagen Robada del blog de David Bonilla ;)
Los equipos dandole caña
Mi equipo fue el primero en entrar en acción. La idea era hacer programación por parejas de forma que uno de los dos componentes de la pareja hacía un test (Piloto) y el otro codificaba lo necesario para que el test pasara (Copiloto). Cada 5 minutos el piloto desalojaba, el copiloto se convertía en piloto y otro componente del equipo entraba como copiloto. Tengo que decir que contábamos con la ventaja de tener en nuestras filas a uno de los miembros de agilismo.es, José Manuel Beas, lo que nos ayudo a comenzar algo más rápido. Conseguimos crear pomodoros y asignarles una duración, aunque nos pusieron alguna pega por utilizar un operador ternario :D
Momento Ternario, con Xavi Gost metiendo el dedo en la yaga :D
No nos fue mal hasta que llegamos a la parte complicada del ejercicio, que era la parte en la que debíamos controlar que el tiempo del pomodoro se agotaba...
Momento marrón
Nos quedamos atrancadillos y les dejamos el marrón al segundo equipo que, al menos, fue capaz de volver a tener todos los test en verde.
Segundo equipo, enmarronado
La kata ejecutada por los maestros
Después de que los equipos hiciéramos lo que pudimos (no fue mucho, la verdad). José Manuel Beas se puso a los mandos del portátil para realizar el ejercicio en modo kata mientras Xavi Gost nos comentaba las discusiones de diseño que habían ido teniendo mientras preparaban el programa. Hay que decir que Beas tardo menos de 20 minutos en realizar el ejercicio y que lo enseñaron funcionando. Doy fe :P Se que van a subir el vídeo de la kata. Cuando esté actualizaré el post con el enlace. De momento os tendréis que fiar de mi :)
Agilismo.es en plena Kata
Además del vídeo de la kata creo que también iban a colgar el vídeo del evento. Cuando lo cuelguen actualizaré el post con el enlace y podréis ver a los equipos desplegar nuestro Kung-Fu, todo amenizado con los comentarios/puyas de Xavi (menudo crack). De momento podéis echarle un ojo a las fotos que han subido los chicos de Okuri Spaces aquí (Algunas os las he mostrado en el resumen) y al vídeo-montaje que han realizado los chicos de Autentia con todos los asistentes al evento.
En fin, fue un evento muy divertido. Espero que se organicen más. Mejoraré mi Kung-Fu para la próxima :D
Para mi fue todavía más molón porque Jose Manuel Beas me regalo esto:
Yo, féliz con mi pulsera
Toma pulsera de Clean Code :D Pedazo regalo de navidad.
En cuanto a la Pomodoro-Kata, prometo darle caña y mejorarla :P A ver si consigo picar a Alfredo y la hacemos en pareja.
Etiquetas:
Agile,
agilismo.es,
coding dojo,
coding kata,
pair programming,
TDD
Suscribirse a:
Entradas (Atom)

