¿Cómo aplicar TDD? - Nivel Intermedio

Para un desarrollador con un nivel intermedio en Desarrollo Guiado por Pruebas (TDD), el objetivo es profundizar en la comprensión de los principios avanzados, perfeccionar las técnicas y aprender a aplicar TDD en contextos más complejos.

Aquí te presentamos una ruta de aprendizaje estructurada para incrementar tus habilidades en TDD y alcanzar un nivel avanzado. 

1. Dominio de principios avanzados de TDD

Siempre es importante reforzar conceptos para que la práctica se realice con conceptos sólidos que te ayuden a aumentar tu técnica.

Algunas nociones que debes tener claras son la refactorización eficaz, entender cuándo y cómo refactorizar el código sin alterar su funcionalidad. Así como el diseño de software dirigido por pruebas y cómo aplicar patrones de diseño de software en el contexto de TDD. Un tema que genera mucho debate en el sector y que seguro puedes aportar tu experiencia.

Pero,  ¿por donde empezar? Un libro que te puede ayudar es Refactoring: Improving the Design of Existing Code de Martin Fowler. Aunque no se centra exclusivamente en TDD, la refactorización es una parte crucial del ciclo de TDD.

Asimismo, Sandro Mancuso, pionero del Software Craftsmanship, habla en varias publicaciones sobre cuestiones de diseño y su relación con el TDD. Mancuso plantea preguntas que cualquier desarrollador se ha hecho a lo largo de su carrera y genera dudas que, a través de la práctica, te permitirán sacar tus propias conclusiones.

2. Practica con katas 

A medida que avanzas, es importante que te enfrentes a problemas que te obliguen a pensar en la arquitectura, el diseño del sistema, y cómo TDD influye en las decisiones de diseño desde el inicio.

Katas de nivel intermedio:

  • Kata Smart Fridge: Debes crear un sistema para una 'nevera inteligente' que sea capaz de registrar los artículos que se añaden o quitan. 
  • Kata Sudoku: El objetivo es rellenar una cuadrícula de 9 × 9 con números, utilizando TDD.  
  • Kata Mars Rovers: Tendrás que guiar el comportamiento de robots exploradores que la NASA ha puesto en Marte

3. TDD en el Contexto de CI/CD

La integración de TDD en los procesos de CI/CD no solo mejora la calidad del software sino que también promueve prácticas de desarrollo más eficientes y colaborativas. 

TDD implica escribir tests antes del código de producción con el objetivo de definir cómo debería comportarse dicho código. Esto se alinea bien con CI/CD, donde el código se integra, prueba y despliega automáticamente, garantizando que las nuevas características o correcciones no rompan la funcionalidad existente.

Configuración de un pipeline de CI que soporte TDD

  1. Automatización de tests: Asegúrate de que todos los tests unitarios y de integración escritos siguiendo la metodología TDD se ejecuten automáticamente como parte del pipeline de CI. 

  2. Ejecución de tests en cada commit: Configura tu sistema de CI para que ejecute automáticamente la suite de tests cada vez que se realiza un commit en el repositorio. Esto asegura que cualquier cambio en el código no rompa la funcionalidad existente.

  3. Fallo rápido: Configura el pipeline para que se detenga si alguno de los tests falla, lo que permite una retroalimentación rápida al equipo de desarrollo. 

Despliegue continuo con TDD

  1. Despliegues basados en tests exitosos: Asegúrate que el despliegue de nuevas versiones del software se base en el éxito de todos los tests. Esto significa que solo se despliega código que ha pasado todas las pruebas de TDD y de integración.

  2. Automatización del Despliegue: Utiliza herramientas de CD para automatizar el despliegue del código a diferentes ambientes (testing, staging, producción) una vez que los tests son exitosos. Esto agiliza el proceso de lanzamiento.

  3. Rollbacks automáticos: Implementa mecanismos de rollback automático en caso de que el despliegue falle o cause problemas en producción.

Algunas herramientas de CI/CD que te pueden ser útiles para automatizar procesos son Jenkins, GitLab CI/CD, CircleCI, y GitHub Actions. Estas plataformas ofrecen una amplia gama de plugins y funcionalidades para soportar TDD.

4. TDD para Código Legado 

Introducir tests en código legado y refactorizar dicho código son tareas desafiantes pero cruciales para mejorar la calidad del software.

Mientras incrementas tu nivel de TDD, aquí te compartimos algunas técnicas y estrategias efectivas para abordar estos retos:

Introducción de tests en el código legado

Comienza por identificar las partes del código que son críticas para el funcionamiento de la aplicación o que tienen una alta tasa de errores. Estas áreas deben ser prioritarias para la introducción de tests. Luego es importante que hagas un análisis de dependencias que dificultan el testing, para ello usa herramientas de análisis de código para entender estas dependencias y evaluar cómo pueden ser aisladas o simuladas (mocked).

Antes de sumergirte en tests unitarios, considera escribir tests de alto nivel, como tests de integración o de aceptación.  Éstos pueden ayudarte a garantizar la funcionalidad básica del sistema antes de refactorizar el código interno. Además, implementa tests de regresión, documenta los errores conocidos y escribe tests que capturen estos comportamientos.

Utiliza técnicas como la inyección de dependencias, el uso de interfaces, y herramientas de simulación (mocking) para aislar partes del código legado. Esto permite la introducción de tests unitarios, incluso en presencia de dependencias complejas.

Refactorización de código legado con TDD

Aborda la refactorización en incrementos manejables. Asegúrate de que cada cambio pequeño pase todos los tests existentes antes de proceder al siguiente. Este enfoque minimiza el riesgo de introducir nuevos errores.

Para cada cambio o mejora, sigue el ciclo TDD clásico:

    • Escribe un test para el nuevo comportamiento deseado o la mejora.
    • Verifica que el test falle (esto valida que el test es efectivo).
    • Implementa el cambio y verifica que el test ahora pasa.
    • Refactoriza el código para mejorar su estructura, asegurándote de que todos los tests sigan pasando.

A medida que refactorizas, incrementa la cobertura de tests. Esto no solo te ayuda a detectar errores, sino que también asegura que el código refactorizado sea fácil de entender y mantener. Para ello puedes utilizar herramientas como JaCoCo (Java), Istanbul (JavaScript), o Coverage.py (Python). 

Algunos libros recomendados para afianzar conceptos son: Working Effectively with Legacy Code por Michael Feathers, que ofrece estrategias específicas para trabajar con código legado, y Refactoring: Improving the Design of Existing Code de Martin Fowler, que proporciona una guía detallada sobre técnicas de refactorización.

5. Comunidad y aprendizaje continuo

El aprendizaje en comunidad te ayudará conocer nuevas perspectivas para alimentar tus conocimientos. Participa en grupos de discusión y comunidades en línea sobre TDD. Plataformas como Reddit y Stack Overflow pueden ser valiosos.
 
De la misma forma, en nuestro canal de youtube te ofrecemos algunos workshops y sesiones prácticas sobre TDD y desarrollo de software. La interacción con otros desarrolladores y expertos te proporcionará nuevas perspectivas y conocimientos.
 
En este blog Emanuel Valverde, ofrece varios recursos (charlas y libros), que te puede ayudar también a incrementar tus conocimientos en refactorización

Recomendaciones Finales

Revisión y práctica continua: El dominio de TDD viene con la práctica y el estudio continuo. Regularmente revisa tu código y busca maneras de mejorar tus tests.

Capacitación y colaboración: Recibir formación de expertos es una forma muy útil de aumentar tus conocimientos y mantenerte al día de las tendencias del sector. Además, te da la posibilidad de obtener feedback inmediato sobre tu práctica.


Descubre el impacto real de Katalyst by Codurance