Facts acerca de TDD
- TDD se compone de, Unit Test, Test Automation, Test First y Enfoque iterativo con refactoring
- TDD es una técnica de diseño y es utilizada por Desarrolladores (Código).
- TDD incrementa la calidad en el código facilitando el cambio en el software
- TDD reduce defectos y permite tener un testeo de regresion constante
- El manejo de dependencias es la parte más dificil de TDD
Como siempre digo, las decisiones arquitecturales habilitan los atributos de calidad, pero obviamente no siempre los garantizan, hay otros aspectos y decisiones que entran en juego y el arquitecto no siempre puede manejar. Pero inevitablemente, la Arquitectura es la principal responsable de garantizarlos, y como arquitectos debemos buscar las formas, y TDD es una de ellas, con lo cual considero que TDD permite lograr los siguientes atributos de calidad:
Maintainability: Siguiendo las guías de Feathers, primero haciendo fallar el test case y luego corregirlo, la mantenibilidad se vuelve un detalle, lo mismo pasa con lo simple que queda el código y con la no necesidad de perder tiempo en un debugger. No nos olvidemos del regression test aca.
Extensibility / Modifiability: Esto es básico, como excelente técnica de diseño, al tiempo de aplicarla la productividad aumenta y el código queda mucho mas simple.
Reliability: Tiene que ver con la robustez en lo que respecta a las reestructuraciones o cambios en la arquitectura, un codigo que se construyo utilizando TDD, difícilmente sea complicado de modificar a cambios inesperados
Geographic (including Localization): TDD es una excelente técnica de comunicación, para equipos distribuidos es fundamental, tener bien claro y definido cual es el comportamiento esperado, no se paga con mastercard
Time: Ya hablé de la Productividad que trae aparejada el Test First, aca hay un paper que habla de los estudios que aumenta la productividad, hasta que lo leí fue solo un feeling mio y personal, ahora se ve que está probado.
Decisiones Arquitectónicas para Soportar TDD
Ahora, como (re) diseñamos nuestra arquitectura para soportar el uso de TDD, bueno, lo encaré desde el punto de vista de "Tácticas y Principios de Diseño" y "Estilos Arquitectónicos y Diseño Estratégico":
Tácticas y Principios de Diseño
- Separation of Concerns.
Una correcta separación de módulos, permite un mejor manejo de la complejidad y también permite el reuso del lado de los Test Cases (que no es poco) - Separación de la interface de la implementación.
Hace falta explicar esto? Bueno, principalmente es para el manejo de dependencias y el trabajo en paralelo - Design by Contract
Dos técnicas complementarias en el bajo nivel, desde un punto de vista arquitectural, definir los pre/post conditions entre módulos es básico - Informacion hiding
Previene cambios no deseados - Prevent Ripple Effects
Con 8 tipos de dependencias entre módulos, nos ayuda a no tener dependencias ocultas entre módulos, esto es muy importante, muchas veces hay modulos que dependen en variables de contexto y está oculta, TDD ayuda a evitarlo.
Mas allá de cosas específicas, hay estilos arquitectónicos que ayudan muchísimo al uso de TDD en aplicaciones empresariales, estos son algunos:
- Inversion of Control/Dependency Injection
Aca no hay nada que discutir, por excelencia permite permite el uso de TDD, sumado a esto la separación de interface de la implementación. - Hierarchical Layers
Estilo super conocido, con un modelo sencillo de dependencias, permite el coverage de una layer solo mockeando una layer inferior. Obviamente este patrón tiene cosas malas aparejadas, como la dificultad por encontrar las abstracciones y la modificabilidad. - Domain Driven Design
Un estilo muy interesante para dominios complejos, se lleva muy bien con el Dependency Injections y la Iteratividad. - Transaction Scripts
Modelo sencillo, en donde se puede lograr una completa de cada servicios a testear.
Quejas de otros profesionales para implementar TDD y como solucionarla
No siempre es fácil convencer el uso del TDD, hay muchas quejas que hay que afrontar, aca puse las que fui recolectando, en algún otro post voy a poner lo que dije verbalmente, así que por ahora se lo dejo a uds para que piensen :)
Project Managers
- Toma mucho tiempo para escribir test y termina impactando en la productividad.
- Me siento mal por dejar afuera del proyecto a Testers y gente de QA
- No me importa TDD, es una técnica de bajo nivel para programadores
- No es necesario to test drive el código, la arquitectura cubre todas las posibilidades
- Toma mucho tiempo en correr los test cases
- No es mi trabajo testear mi código
- Pero compila!
- A mi me pagan por escribir código, no para escribir tests
- Las dependencias son difíciles de manejar y toman mucho tiempo