Curso de TDD con Carlos Blé (día 1)
Hoy ha sido el primer día del curso de TDD que estamos celebrando en AvanTIC de la mano de Carlos Blé, y escribo esta entrada para reflexionar sobre lo que hemos aprendido hoy, espero que te guste. Debo aclarar antes de que continues que no es una entrada introductoria y doy por supuesto que sabes lo que es TDD y otros conceptos de desarrollo ágil.
Introducción
Allá por el año 2009 (como si fuese una fecha muy lejana) tuve la oportunidad de hacer por primera un curso de TDD con Carlos Blé, ya había leído algo sobre el tema y había conocido a Carlos en la facultad, pero no había tenido relación con él. ¿Por qué hacer este curso por segunda vez?, pues usando las palabras de Dalton Rusell, personaje de Clive Owen en Plan Oculto, porque puedo. También puedo decir que Carlos ha mejorado mucho y aprendido muchas cosas a lo largo de estos años dando cursos, por lo que es una buena oportunidad para reforzar conceptos y revisar mi TDD :-) y no solo al lado de Carlos, sino junto a mis compañeros de AvanTIC y otra gente estupenda del grupo Agile Canarias.
Primera aproximación: Tests unitarios
Hemos empezado descargando un proyecto que tiene lo que podríamos denominar ... "un código con una calidad muy mejorable" :-) en el que Carlos nos ha pedido que hagamos una serie de tests para asegurar que no rompemos nada cuando empecemos a realizar refactorizaciones sobre el mismo. Aquellas personas que estén más interesadas en este tema pueden leer el libro de Michael Feathers, Working effectively with Legacy Code, porque lo que hemos hecho es básicamente eso, trabajar con código legado y siguiendo muchas de las recomendaciones aportadas por el señor Feathers en su libro.
Para este ejercicio compartí teclado con uno de mis compañeros de AvanTIC, Fran Olmedilla. A medida que avanzábamos Carlos hacía alguna pausa y explicaba aspectos importantes, no solo de TDD en particular, sino de programación en general. Por ejemplo nos podemos quedar con las características deseables de un test unitario y los principios SOLID.
Características de un test unitario
Introducción
Allá por el año 2009 (como si fuese una fecha muy lejana) tuve la oportunidad de hacer por primera un curso de TDD con Carlos Blé, ya había leído algo sobre el tema y había conocido a Carlos en la facultad, pero no había tenido relación con él. ¿Por qué hacer este curso por segunda vez?, pues usando las palabras de Dalton Rusell, personaje de Clive Owen en Plan Oculto, porque puedo. También puedo decir que Carlos ha mejorado mucho y aprendido muchas cosas a lo largo de estos años dando cursos, por lo que es una buena oportunidad para reforzar conceptos y revisar mi TDD :-) y no solo al lado de Carlos, sino junto a mis compañeros de AvanTIC y otra gente estupenda del grupo Agile Canarias.
Primera aproximación: Tests unitarios
Hemos empezado descargando un proyecto que tiene lo que podríamos denominar ... "un código con una calidad muy mejorable" :-) en el que Carlos nos ha pedido que hagamos una serie de tests para asegurar que no rompemos nada cuando empecemos a realizar refactorizaciones sobre el mismo. Aquellas personas que estén más interesadas en este tema pueden leer el libro de Michael Feathers, Working effectively with Legacy Code, porque lo que hemos hecho es básicamente eso, trabajar con código legado y siguiendo muchas de las recomendaciones aportadas por el señor Feathers en su libro.
Para este ejercicio compartí teclado con uno de mis compañeros de AvanTIC, Fran Olmedilla. A medida que avanzábamos Carlos hacía alguna pausa y explicaba aspectos importantes, no solo de TDD en particular, sino de programación en general. Por ejemplo nos podemos quedar con las características deseables de un test unitario y los principios SOLID.
Características de un test unitario
- Deben probar una unica funcionalidad.
- Deben ejecutarse muy rápido.
- Deben ser inocuos, no importa cuantas veces o en que orden los ejecutes, que el resultado ha de ser siempre el mismo.
- Single responsibility principle
- Open/Closed principle
- Liskov substitution principle
- Interface segregation principle
- Dependency inversion principle
Debatiendo sobre los principios SOLID llegó la hora de la comida y un merecido descanso para todos. Pero a la vuelta Carlos se puso a los mandos y mostró que cambios se podrían aplicar al código sobre el que habíamos trabajado para que tuviese una calidad más aceptable, tras lo cual nosotros continuamos haciendo nuestros propios cambios. Esta vez a mi me tocó con Guillermo Fuentes, otro de mis compañeros en AvanTIC, y con @davioth.
Carlos dandole al teclado :-) |
En esta primera parte del día no me terminé de encontrar muy cómodo, es muy posible que me cueste un poco más trabajar con código legado y sobretodo haciendo pair programming (que se me dá mucho mejor cuando es un problema nuevo o generando código que no existe), porque me es más complicado encontrar un consenso debido a los distintos puntos de vista de cada persona. Desde luego es un punto que tengo que trabajar mucho más.
Segunda aproximación: TDD
Ahora sí, va la buena, por ahora solo habíamos calentado motores. Ahora toca empezar a resolver un problema nuevo, de la nada, por supuesto usando TDD. Para la primera iteración me ha tocado compartir teclado con @titeroygatra y al poco rato ya estábamos haciendo ping-pong (yo creaba un test, y él creaba el código para pasar el test y el siguiente test que tenía que resolver yo), ahora sí me encontraba en mi salsa y todo el código surgía bastante bien. Como "problema" en esta etapa yo señalaría que elaborábamos directamente métodos privados al intentar pasar el test en vez de en la etapa de refactorización, lo cual llevó a que algunos detalles no saliesen tan limpios como esperábamos (hay que dar pasos más pequeños), pero la calidad final era buena.
El secreto fue ir poco a poco, despacito y con buena letra, cuidando los detalles. Pero todo termina y ahora me tocaba continuar con la implementación que había empezado previamente, pero esta vez con @chozero de pareja. En esta etapa quizás cabe destacar que intentamos resolver una parte del problema con expresiones regulares y finalmente la descartamos para usar una simple concatenación de .replaceAll, pues sorpresa!!! esta solución que parece tan poco elegante se entendía perfectamente y funcionaba muy bien. El resto de la implementación no causo ningún problema y pudimos terminar todos los puntos que teníamos anotados en nuestra libreta de tests.
Para acabar el día me tocó cambiar de compañero y de ordenador, por lo que continuaría una implementación que no había visto previamente. Esta vez me tocó compartir asiento con otro de mis compañeros de AvanTIC, @diyipol. Esta vez ya había un test en rojo cuando he llegado y a vueltas con un problema con expresiones regulares, Carlos nos recomendó que empezáramos de nuevo esa parte haciendo tests muy sencillos, esto nos llevo toda la iteración, pero al final teníamos una implementación que funcionaba bien y también se entendía perfectamente, para redondear además tenía en cuenta una serie de casos que en iteraciones previas yo no había tenido en cuenta.
Y hasta aquí llegó el primer día y mis pequeñas reflexiones, sé que algunas personas estaban esperando código pero tendrán que esperar un poco a que termine de ordenar mis ideas, pero que sepan que en posteriores entradas pondré soluciones que han surgido en este curso o soluciones a problemas propuestos como por ejemplo la refactorización del código del primer ejercicio, pero hecha por mi y no por Carlos.
Comentarios
Con respecto a lo de la foto no te preocupes un par de desayunos con Domingo y ganas unos kilos en menos que canta un gallo :-)
Un abrazo.