Los días 18 y 19 de enero tuvimos la oportunidad de asistir a un curso de TDD impartido por Carlos Ble. Durante dos días, estuvimos aprendiendo la base del Test Driven Development y programando en parejas con diferentes personas, de diferentes empresas y con diferentes backgrounds de desarrollo. Vamos, pasándonoslo bien :).
El primer día descubrimos los principios SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion), que deben cumplir los métodos y clases que vayamos a implementar, que viene a ser lo siguiente:
- Single Responsibility -> Un objeto debe tener una sola responsabilidad.
- Open/Close Principe -> Las entidades de software deben estar abiertas a ser extendidas, pero cerradas a las modificaciones.
- Liskov substitution-> Un objeto en un proceso puede ser sustituido por otro sin que se altere la funcionalidad de dicho proceso.
- Interface Segregation Principle-> Los clientes no debería ser forzados a depender de interfaces que ellos no usan.
- Dependency Inversion Principle-> Módulos de un nivel alto no deberían depender de módulos de bajo nivel.
TDD realmente no es una herramienta "para testear", sino para diseñar tu API, para pensar y montar la arquitectura de la aplicación. Si simplificamos los pasos a seguir para hacer TDD, serían los siguientes:
- Crear una hoja de ruta con las especificaciones que queremos para una funcionalidad concreta
- En esa hoja de ruta, apuntar todos los posibles casos que se nos ocurran.
- Para cada caso de uso apuntado en tu hoja de ruta, montar un test pensando en cómo debería usarse dicha funcionalidad (al principio, es posible que ni compile el código, ya que todavía no hemos implementado nada de la API (¡luz roja!).
- Para cada test, hacer la mínima funcionalidad, de forma que el test pase (¡luz verde!).
- Una vez que el test pase, refactorizar.
Sin duda una de las fases más importantes en el TDD: La refactorización nos permite darnos cuenta de cosas como:
- Nomenclatura de nombres. ¿Estamos siendo claros? ¿Queremos expresar bien lo que hace tal método? ¿"hacerCosas" es buen nombre para un método? ;)
- Extracción de métodos/clases. ¿Realmente este método debería estar en esta clase? ¿Qué responsabilidad tiene?
- Arquitectura. ¿Usamos Interfaces para montarnos una buena arquitectura? ¿Cómo se van a comunicar los objetos entre sí? ¿Inyección de Dependencias? Particularmente esta es la parte que más me interesó, ya que aunque todos conocemos la herencia y tal, quizás no la usemos tanto como deberíamos.
El segundo día fue realmente revelador: aprendimos a usar mocks, particularmente el framework Mockito para Java. Cómo simular accesos a base de datos o conexiones a un servidor. El tema de los mock merece un post aparte, sin duda.
Un curso muy recomendable para aquellos que quieren meterse en el mundo del TDD y la creación de buen código. Además de pasártelo bien, programando con gente desconocida (creo que es lo que más me gusta), aprendes un montón.