TDD ... en la vida real

¿Qué es el TDD?

Es una técnica de programación para mejorar el "diseño" de nuestro código. Significa desarrollo guiado por pruebas.

¿Cómo funciona?

Consiste en aplicar pruebas unitarias (probar el código y comprobar su buen funcionamiento) y refactorizar (eliminar duplicados, código muerto, y en algunos casos rehacer el código).

Algoritmo básico del TDD

  1. Hacer un test y ver que falle (rojo)
  2. Hacer el còdigo mínimo y suficiente para que el test pase (verde)
  3. Refactorizar hasta que el código este lo más "limpio" que se pueda

Cabe aclarar que el TDD es una técnica de diseño no de desarrollo, su intención es que los programadores diseñen mejor su código, hacer que se vea más limpio y sea más funcional.

¿Me conviene usarlo?

Ver aplicado el TDD en un proyecto en "la vida real" es dificil. Los tiempos de entrega (del proyecto) muchas veces provoca que no se tome en serio esta técnica. A los desarrolladores les urge entregar el código lo más antes posible que se pueda. Y dejar las pruebas hasta el último momento. Sin embargo, surgen los problemas. El usuario no esta (a veces nunca ... jeje) conforme con lo entregado. "Esto no es lo que pedi", "¿no me entendieron?"...

Esto me hace pensar que si conviene usar esta técnica. Al menos para preparar al programadory mejorar su trabajo.

Es dificil pensar "al revés" primero hacer una prueba al código y después ... ¡escribirlo!
¿Cómo, tengo que escribir las pruebas primero? ...pero si no tengo el @#$ código hecho !!!!

IDEs: JUnit, TestNG y la refactorización

NetBeans, Eclipse, etc. poseen herramientas para refactorizar el código. Creeme estas herramientas son bastantes útiles a la hora de programar. Algunas funciones de la refactorización como el encapsulamiento de campos, extracción de métodos (entre otras) ayudan mucho. Además existen las librerías necesarias par hacer la pruebas unitarias (JUnit y TestNG).

Eclipse además tiene plugins para usarlo (TDGotchi y Pulse), solo basta descargarlos de http://www.happyprog.com/ ... e instalarlos. Cada quien programa como quiere, sin embargo no esta de más conocer algo "nuevo". El libro de @carlosble me sirvió de mucho para conocer esta técnica. En javaméxico hay post sobre esta técnica que sirve de mucho.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Sr. Negativo

jajaja por fin

El poder de la "persuación" (jeje)

Bueno quería hacer un ejemplo de TDD, pero antes una pequeña introducciön sobre el tema por si alguien no sabía de que se trataba.

Gracias.

Es difícil aplicar TDD en un

Es difícil aplicar TDD en un proyecto existente que no tenga suficientes pruebas, básicamente por dos razones:

Como no hay pruebas existentes:
1. No hay forma de evitar que alguien cambie funcionalidad que tu usas y rompa tu código
2. No hay forma de saber si rompes el código de alguien con tus cambios

Esto deriva casi siempre en un montón de pruebas que fallan. El programador las revisa y dice... ahh si ... es que no hay forma de blahblahblah y "acepta" que va a tener siempre 1 error, que luego se convierte en 2 y luego las pruebas no sirven para nada.

El esfuerzo para agregar pruebas a código existente es demasiado alto como para aceptarlo ( a menos que el código sea muy pequeño aún )

Quizá lo que se podría usar es una especie de BDD ( Behavior Driven Development ) que para acabar pronto es lo mismo pero en vez de probar los componentes unitarios se prueba el comportamiento en general ( en realidad la idea es que el usuario final pueda ver la descripción de la prueba y decir "Ajap.. eso es lo que quiero que haga" pero también aplica para pruebas de componentes "macro" )

Total que es difícil.

Y cuando se aplica a proyectos nuevos, la difícil es resistir la tentación de no hacer refactoring, porque como va avanzando a buen ritmo se puede llegar a pensar "Bah.. lo tengo en verde, mañana si lo refactorizo" y ese mañana nunca llega. Es por eso que en a veces se recomienda dedicar un día a la semana o un par de días cada X semanas para dedicarlos únicamente a refactorizar, entiendase: No agregar ni un test más, y no dejar ningun test en rojo. Y el no agregar un test más implica que no se agrega ninguna funcionalidad más, solamente se refactoriza la existente.

Recientemente conocí una empresa que trabaja exclusivamente con TDD y guau!!.. si esta muy fregón el método de trabajo, de hecho pude verlos trabajar un par de horas en vivo y es un experiencia bastante mmmhh como decirlo ... no sé emotiva o algo. En fin. Cabe mencionar que la herramienta de trabajo que usan ( Ruby ) es bastante diferente a Java en cuanto a flexibilidad y casi los obliga a trabajar así ( no hay compilador que detecte errores básicos de sintaxis ). Y absolutamente todo se prueba, incluso por ejemplo poner un link a una página y ver que al hacerle click va a aparecer un texto en específico. Bastante completo.

En fin, es bastante interesante el tema.

Puntos a recordar:

1. Agregar métodos a toda la funcionalidad siempre ( yo por ejemplo no considero un getter setter como parte de la "funcionalidad" y eso no lo pruebo a menos claro que el getter/setter hagan algo, como por ejemplo validar que el dato no sea null, entonces si merece un test )
2. Refactorizar sin misericordia :) uuff que difícil es esto especialmente en un proyecto en solitario.

Saludos.

Imagen de Sr. Negativo

Dificil ... si

Hacer pruebas al código es bastante dificil. Considero que no es necesario hacer pruebas a TODO (por ejemplo los setter y getter) soloal código que pueda causar un problema.

Me falto mencionar que se trata de una técnica para mejorar el diseño del código y promover mejores prácticas, no tanto de testeo ( o testing).

?:)

y como sabes si puede dar

y como sabes si puede dar problema o no?

Es decir, estoy de acuerdo con los getters/setters, esos no se deberían de probar, aunque además de eso casi todo el código tiene algún efecto. Algo que tampoco tiene mucho efecto es por ejemplo el método toString() pero por otro lado tampoco cuesta mucho trabajo agregar la prueba, hasta se puede automatizar.

Pero si, yo tampoco los pruebo.

Imagen de Sr. Negativo

Todo debe probarse

@rodrigo salado
Me comentó que en algunos casos si es necesario probar todo el código. Por ejemplo para validar los setter y getter, probar métodos que no devuelven valores,etc.

Me pareció un tanto raro esto , pero creo tiene razón no esta de más hacer un buen testeo. Espero continuar con el tema.

Imagen de rodrigo salado anaya

@Todo debe probarse ..

Platicando con un amigo (Padawan) me aclaro un poco más las ideas.

Mis conclusiones de la charla:
Solo probar lo que sea molificable o valga la pena. Si el seter y el geter no son lo suficientemente complejos olvídalos.
No gastar energía en escribiendo código que vuelva más complejo el código de test.
Si el código de test es casi o más complejo como el código a probar, algo están mal.

En fin, saludos cuates. : )

Imagen de Shadonwk

Amí tambien me gusta aplicar

Amí tambien me gusta aplicar esta técnica, sin embargo solo lo hago con metodos grandes o que integren varios metodos, por ejemplo si tengo que hacer un codigo que abra un archivo y cuente el numero de palabras repetidas, hago la prueba en general, luego si ya tengo un metodo que abre un archivo y me devuelve el contenido en algun tipo de buffer, y es lo que necesito y ya lo probe antes, ya no le hago su prueba, si tengo que hacer un metodo que tome ese bufer y empiece a contar las palabras, no tengo nada igual, y menos probado, entonces primero le hago sy prueba y así, TDD puede ser una muy buena ayuda para tu realizar el codigo, y no solo al diseño, sí concidero que es una perdida de tiempo probar todo, pero con la experiencia llegas a probar solo aquello que sabes que puede causar un problema.

Saludos.

En teoría deben de ser los

En teoría deben de ser los método públicos.

Si no lo pruebas no debe de ser público.