Introducción
TDD (Test Driven Development), cuyas siglas en inglés significan "desarrollo dirigido por pruebas", es una técnica de diseño e implementación de software basada en metodologías ágiles, que se centra en seguir tres pasos: pruebas, codificación y refactorización.
Más concretamente, el proceso se basa en escribir las pruebas en primer lugar y verificar que el software las falla, para en segundo lugar implementar el código que hace que pase la prueba sin errores, y por último refactorizarlo. Conseguimos así, que el código escrito es robusto y manejable, además de conseguir rapidez en el desarrollo.
Esta metodología está sostenida por tres pilares fundamentales:
- Implementar las funciones que el cliente pide y no más.
- Minimizar la cantidad de errores que tiene el software.
- Producir software modularizado, reutilizable y preparado para el cambio.
Con esta metodología se va a conseguir a partir de realizar las pruebas, analizar profundamente cuales son los requisitos del software, hacer que el código sea el mínimo necesario, reduciendo partes del mismo que resultan innecesarias y que nunca son utilizadas, y además conseguir un código totalmente optimizado, fácil de entender y de mantener, a través de su refactorización.
Características
Podemos enumerar algunas de los hechos que caracterizan TDD:
- Antes de escribir el código, se crean las pruebas. Estas deben ser unitarias, es decir, que hagan pasar sólo una funcionalidad concreta del código.
- El código en primer lugar tiene que fallar la prueba, para así asegurar en que casos el código funciona en qué casos no lo hace.
- Escribir sólo el código mínimo para pasar la prueba, así se asegura que funciona, y que no se va a crear software que nunca va a utilizarse.
Ciclo de vida
- Requisitos: dados unos requerimientos establecidos para la realización del sistema se escoge el que más fácil parezca y que más información sobre el sistema abarque. Para ello, el desarrollador debe conocer cada una de las especificaciones y requerimientos.
- Pruebas: el desarrollador debe realizar la prueba del requerimiento escogido una vez entendidos los requerimientos. Las pruebas se habrán de realizar desde el punto de vista del cliente, intentando visualizar la interfaz que ha de ver el cliente.
- Verificar que la prueba falla: en caso de que la prueba no falle querrá decir que el requerimiento escogido ya se ha implementado o que la prueba es errónea.
- Implementación: se ha de realizar el código para el requerimiento seleccionado lo más simple posible, de forma que la prueba pase el test realizado.
- Ejecución de pruebas automáticas: se ha de comprobar si las pruebas realizadas funcionan correctamente mediante el código realizado.
- Duplicación: se revisa el código realizado en busca de código duplicado. Cada vez que se haga elimine código duplicado se habrán de pasar las pruebas otra vez y, una vez se realicen correctamente, seguir la búsqueda de código duplicado.
- Actualizar requisitos: una vez hecho las pruebas del requisito seleccionado, y cuando ya se haya implementado y probado, se actualiza la lista de requisitos eliminando el requisito realizado e incorporando nuevos requisitos en caso de que sea necesario.
Ventajas
Las ventajas del Test Driven Development son:
- El programador ve los resultados rápidamente ya que se va desarrollando por partes.
- Permite que el programador se centre en la tarea actual, es decir, que el código pase la primera prueba.
- Ofrece flexibilidad ya que el código se ha realizado en pequeñas partes.
- Obtenemos un catálogo de tests realizados durante el desarrollo del código, los cuales nos servirán para posteriores sistemas.
- Se obtiene un código claro, estructurado y modularizado debido a que se ha desarrollado el software con detenimiento y de forma modularizada para pasar cada una de las pruebas realizadas.
- Al obtener un código más claro y seguro, el programador obtiene un mayor nivel de confianza en el código.
Limitaciones
- Puede resultar difícil de usar esta metodología cuando se requieren pruebas totalmente funcionales para determinar el éxito o el fracaso de una implementación. Algunos ejemplos son los programas que trabajan con bases de datos, ya que es necesario de pruebas muy elaboradas para poder contemplar y probar correctamente un programa de estas características.
- Es necesario que la dirección del proyecto vea que toda la organización confía en esta metodología, sino podría pensar que el realizar tantas pruebas es una pérdida de tiempo.
- En la mayoría de ocasiones, la persona que escribe el código es la que crea las pruebas unitarias. Esto es una desventaja, cuando un desarrollador escribe un código a veces no tiene en cuenta ciertos aspectos del sistema o posibles casos de uso de los clientes, es probable entonces, que tampoco tenga en cuenta estos casos o aspectos del sistema a la hora de realizar pruebas. Por ejemplo, si el desarrollador escribe código, y en el mismo no contempla que no se pueda introducir como parámetro un número negativo, seguramente cuando realice las pruebas, no compruebe si esto falla, ya que normalmente los desarrolladores no pruebas cosas que ni tan siquiera pensaron a la hora de escribir el código.
- Un número elevado de pruebas puede hacer pensar al equipo que el sistema es muy seguro, haciendo que se realicen menos pruebas de las necesarias.
- Aunque esta metodología esté enfocada en las pruebas, no hay que realizar pruebas demasiado complicadas ya que el mantenimiento y actualización de las mismas también forma parte del desarrollo del proyecto y podrían resultar en un coste más elevado del proyecto. Además si no se realiza un mantenimiento correcto de las pruebas, podrían generar fallos erróneos que con el tiempo se ignorarían, con la consecuencia de que no se podrían detectar los posibles fallos reales.
- El nivel de cobertura y detalle de las pruebas durante las diferentes iteraciones del Test Driven Development no puede ser recreado en fechas avanzadas del desarrollo del sistema. Por consiguiente, las pruebas originales se convierten en algo muy preciado. En cualquier caso, si debido a un diseño o arquitectura ineficiente o a una estrategia de pruebas incorrecta, se produce un error en fechas avanzadas del desarrollo del sistema, es posible que docenas de pruebas comiencen a fallar, en ese caso la mejor estrategia será atender a cada prueba individualmente.
Opinión personal, conclusiones
Test Driven Development (TDD) es una metodología ideal si se emplea en proyectos cuyo perfil sea el indicado. Por ejemplo, no es una buena idea emplear una metodología de este tipo en un proyecto a gran escala ya que la realización de las pruebas y la escritura del código sería más una carga que una ventaja. Además en esta metodología no se emplea tanta documentación ni se guía tanto el desarrollo como en otras metodologías. Por todo esto hay que saber muy bien cuándo es idóneo emplear Test Driven Development y cuando no.
Una vez se estudian ciertas características y se determina que Test Driven Development es una buena metodología a seguir, ¿por qué usar esta metodología y no otra similar?. Esta metodología nos permite, mediante pruebas, enfrentarnos a problemas tanto concretos como generales, cerrando desde un principio las posibles brechas del sistema y evitando por lo tanto arrastrar una cantidad elevada de fallos a fases avanzadas del desarrollo.
Enlaces utilizados:
- http://www.developer.com/java/ent/article.php/3622546
- http://es.wikipedia.org/wiki/Desarrollo_guiado_por_pruebas#Ventajas
- http://en.wikipedia.org/wiki/Test-driven_development#Benefits
- http://www.dirigidoportests.com/wp-content/uploads/2009/12/disenoAgilConTDD.pdf
1.Las fases del test driven development se realizan en el siguiente orden:
- Codificar, Requisitos y Pruebas
- Requisitos, Codificar y Pruebas
- Requisitos, Pruebas y Codificar
- Ninguna de las anteriores
- Implementación
- Interfaz
- Cumplir los objetivos
- Todas las anteriores
- Flexibilidad
- Rápidos resultados
- Código de calidad
- Todas las anteriores
- Está dirigido por casos de uso.
- Está centrado en la arquitectura.
- Está enfocado en la realización de pruebas.
- Ninguna de las anteriores.
- Es difícil realizar cambios en el código ya que al haberse llevado a cabo tantas pruebas el código es ininteligible.
- Es fácil realizar modificaciones profundas en el programa, basta con realizar el cambio y pasar las pruebas para saber si todo funciona correctamente.
- El código no debe modificarse si las pruebas han sido pasadas satisfactoriamente.
- El código debe modificarse y aunque algunas pruebas fallen se debe continuar.
- Extensible pero no modularizado.
- Modularizado pero no flexible.
- Flexible pero no extensible.
- Ninguna de las anteriores.
- El código implementa las funcionalidades que justo pide el cliente, ahorrando así funcionalidades que no van a ser utilizadas.
- Al estar dirigido por casos de usos, es más lento que implementarse utilizando cualquier otra técnica.
- Produce software modular, reutilizable y preparado para los cambios.
- Los tests se escriben antes que la implementación.
- En ningún caso sirven como documentación técnica.
- Se crean a partir de los casos de uso, y son por tanto, reducciones de éstos.
- Aunque no falle, se escribe el código igualmente.
- Están pensados para que cuando el desarrollador esté programando pensando en un test, resuelva otros fallos de su código, aunque no tengan nada que ver con el test.