La verdad es que TDD no es una de las técnicas más utilizadas dentro de las metodologías. He tenido la suerte de conocerla y utilizarla en casos reales, que es donde se ve qué es lo que aporta y que es lo que no.
Varias veces hemos visto el famoso gráfico de los costes de los cambios según la fase en la que está el proceso. Evidentemente, un cambio en la fase de requisitos afecta bastante menos que un cambio cuando la aplicación está a punto de entregarse. Para refrescar la mente, dad un vistacillo a esta página.
Partiendo de que estamos de acuerdo con ese gráfico y, asumiendo que siempre ha habido, hay y habrá cambios no planeados en nuestra aplciación (cambios en los requerimientos, errores en el diseño que obligan a tocar módulos, mejora y optimización del rendimiento...), tenemos que encontrar una forma de poder absorver esos cambios con el mínimo impacto.
La solución es el desarrollo iterativo. Antes de aplicarlo, leed este artículo para poder aplicarlo lo mejor posible. La base de este modelo, es ir desarrollando la funcionalidad de mi aplicación poco a poco. Simplificando mucho este proceso, podríamos tener el siguiente caso con la tan manida calculadora.
- Hablamos con el cliente y nos dice que quiere una calculadora. Pero no quiere una calculadora normal y corriente, quiere una adaptada a su negocio. Iniciamos la captura de requisitos.
- Conforme llegan los primeros requisitos (que sume y que reste), el equipo de desarrollo comienza a implementar esas dos funcionalidades.
- Para cuando nos llegan otros dos requisitos (multiplicar y dividir) nuestra aplicación ya tiene el código necesario para sumar y restar, y estamos probándolos.
- El equipo de desarrollo ha acabado de probar los dos primeros requerimientos y empieza a desarrollar los otros dos. Mismo procedimiento: implementacion + pruebas + correccion de errores.
- Entre medias, el usuario quiere ver una demo de lo que vamos haciendo hasta ahora. Como nos movemos por funcionalidades concretas, podemos enseñarle la parte de sumar y restar. En caso de que hubieramos hecho todo en bloque, no tendríamos nada acabado, y no podríamos enseñar nada.
- Una vez vista la demo, nos dicen que no se deberían poder meter negativos en la suma, pero sí en la resta. El equipo de desarrollo adapta esa parte de la aplicación. La resta no se toca y siguen trabajando con la multiplicación y la división.
- Pasa el tiempo y, tras repetirse los puntos 1-6 varias veces, se entrega la aplicación a los usuarios para un UAT (test de aceptación del usuario). Concluyen que falta funcionalidad, que no se acordaron de decirnos porque lo daban por supuesto... No pasa nada, volvemos al punto 1, sabiendo que el resto de la aplicación no debería tener excesivo impacto.
Esto no es siempre tan fácil y tan teórico. Surgen prisas y nos saltamos puntos. O juntamos puntos. Además, el trabajo en equipo tiene particularidades que hacen que algunos pasos sean más complicados que otros.
Este desarrollo por ciclos se coplementa muy bien con TDD. Tests que prueban la funcionalidad (tanto que se cumplen los requisitos, como que los resultados son los correctos). Esos tests siempre están y me pueden decir qué es lo que debo hacer. Como dice Dan North en su blog:
I had introduced a bug. Bad me. Solution: Fix the bug.
The intended behaviour was still relevant but had moved elsewhere. Solution: Move the test and maybe change it.
The behaviour was no longer correct – the premise of the system had changed. Solution: Delete the test.
Son un punto de partida. Nueva funcionalidad necesitará nuevos tests, pero los que estén no cambiarán. Cambios en la funcionalidad necesitarán cambios en los tests e, incluso, algunos nuevos. Errores en la lógica de la aplicación necesitarán cambios en los tests o más tests o tests más precisos.
Nunca tengais miedo de cambiar un test si veis que no prueba lo que debe de probar.
Tras esta introducción, vamos a analizar las preguntas del principio:
¿Por qué no usamos TDD?
Empezamos con la negativa. Las causas más comunes son:
- No sabemos que existe, o, si lo sabemos, no sabemos cómo se aplica. Efectivamente, nadie nace sabido, pero existe una cantidad brutal de libros y de documentación sobre Agile, TDD, BDD, Testing...
- Es dificil montar un equipo que sepa usar TDD, y sin miedo. Algún día debe ser el primero. Por esa regla de tres, nadie habría empezado a usar OOP o los Web Services. Ante todo, que la gente que debe enseñarlo, se haya documentado muy bien y tenga una mínima experiencia.
- Tardamos más en desarrollar la aplicación. Esto es verdad, pero los que lo dicen como excusa deben decir también que el desarrollo es sólo una de las fases de un proyecto, que generalmente no llega a la mitad del tiempo del proyecto. Se alarga la fase de desarrollo, pero a cambio, se acortan la otras. Para ser más precisos, no es que se acorten, sino que se solapan.
- Mantener Tests + Codigo es más costoso que Mantener Código. Falso. En una aplicación donde un cambio afecta a 6 proyectos y 40 clases, es mucho más sencillo cambiar el código y ejecutar automáticamente los 300 tests que haya, para ver si afecta en algún otro punto, que ponerte a probar la aplicación exhaustivamente punto por punto y opción por opción.
- Tener tests, añade labor de documentación. Sí, totalmente de acuerdo, pero eso era bueno, ¿no? Más documentación, más informción, mejor mantenibilidad.
- Desconocimiento de herramientas. Visual Studio Team System 2005 integra el desarrollo y los tests, y permite automatizarlos. Visual Studio 2008 también trae los proyectos de test y, para los más humildes, siempre podéis usar NUnit junto con una Express Edition.
Y ahora, ¿Por qué usamos TDD? Muchas de las respuestas se han dado en los 6 puntos anteriores, pero podemos añadir más.
- Es una garantía de funcionamiento. Con unos tests bien diseñados, el hecho de pasar todos los tests, implica que nuestro código cumple los requisitos.
- Implica mayor conocimiento de la aplicación. Diseñar e implementar un test requiere saber exactamente qué es lo que debe de ejecutar nuestra lógica. Es decir, nos permite ver una caja negra que debe de cumplir los test, que va a hacer que nos centremos en QUÉ hace (funcionalidad) y no en COMO lo hace (código).
- No es exclusivo de un lenguaje. No es sólo de C#, ni VB.NET. Ni siquiera es exclusibo a .NET. Se puede usar en Java. Alguien que sabe TDD en un lenguaje lo sabe en todos.
- Mezcla gestión de proyecto con desarrollo. Permite que los desarrolladores tengan una visión más global de la aplicación, porque deben saber los requisitos para poder desarrollar los tests.
- Permite un análisis de efectividad. Cuanta más información tengamos de la evolución de un proyecto, mejor podremos detectar errores y subsanarlos, bien durante el desarrollo del proyecto, bien en el post-mortem. Los tests aportan información de cuanto código está testeado, cuanto funciona y cuanto no, cuanto influye un cierto cambio...
- Da una garantía entre fases. Saber en plena fase de desarrollo que el tiempo de test se reduce da cierta tranquilidad.
Estos son algunos puntos a favor de TDD. Por supuesto, usarlo implica riesgos. Pero, no usarlo también.
Estáis invitados a dar vuestra opinión al respecto.
Saludos @Madrid
No hay comentarios.:
Publicar un comentario