Jugando con TDD

 

Hace tiempo que había oido hablar de TDD y hace unos meses que lo poco que codifico intento hacerlo siguiendo esta filosofía, de momento yo solo, por mi cuenta y riesgo. No me gusta mover a la gente y aconsejarles algo sin haber hecho primero mis pruebas. Pero la verdad es que en ese poco tiempo que he estado probando, las ventajas saltan a la vista. Ahí van algunas cosas que he notado.

La primera es que al pensar primero en hacer el test, te obliga un poco a hacer la/s clases/s con un diseño adecuado para ser testeadas. El ejemplo más típico es una clase que recoge datos de algún sitio, hace cosas con ellos y los deja  en otro lado. El diseño para hacer test de esa clase hasta cierto punto obliga a que esa clase se le pasen los datos (o los recoja de una interface que se le pasa) y devuelva los resultados (o se los pase a una interface que se le pasa). Este diseño, prácticamente obligado para poder hacer el test, generalmente es mejor que la clase "mazacote" que ella sola lee sus datos directamente de dónde sea, hace las cuentas y deja los resultados directamente en algún sitio. La clase "mazacote" sería muy difícil de testear, puesto que tendríamos que acceder directamente a los datos de donde la clase los recoge o los deja (una base de datos, una interface gráfica de usuario, un socket, etc). Hacer el test nos ha obligado a, en vez de hacer una clase "mazacote", hacer tres clases: LeerDatos, EcharCuentas y MostrarResultados, con una clara divisíón de responsabilidades, y además, con sus interfaces correspondientes.

La segunda ventaja, según vas haciendo test y codificando más y más, es que me siento con mucha confianza para retocar el código. El tener unos test detrás me hace ser más atrevido a la hora de tocar código que funciona para mejorarlo. De hecho, lo hago más que antes (aunque para decir la verdad, no lo hago todo lo que debiera por las malditas prisas).

Y otra ventaja verdaderamente importante y que me ha llevado a escribir este post, aunque no esté hablando estrictamente de TDD, es que ayuda muchísimo a buscar y corregir fallos. Cuento la experiencia de hoy:

En uno de nuestros sistemas enviamos mensajes por sockets entre los distintos ejecutables. Había un mensaje concreto que al enviarlo por socket aparentemente funcionaba, pero soltaba por el log unas excepciones muy feas y raras. Esas excepciones saltan en el código que convierte ese mensaje (una clase java) en un array de bytes para envío por el socket. Me "encasquetaron" a mí el problema, así que me puse a ello. Pero en vez de hacer lo que se hace tradicionalmente, que es arrancar el sistema con debugger y ponerse a probar, decidí aplicar alguna de las ideas de TDD: "No se toca código si no hay un test que falla". Así que en vez de eso, me fui a mi sitio y me puse a hacer un test que fuera capaz de provocar ese fallo.

Tras una hora y pico de trabajo y hacer un test relativamente complejo, como abrir un socket cliente y otro servidor, construir el mensaje y enviarlo y jugar con los datos del mensaje a ver qué podía provocar el error, conseguí reproducirlo. Ahora, la parte de debugger sobre el test de junit es mucho más sencilla, que es un programa muchísimo más simple que el sistema completo. Sentado tranquilamente en mi sitio con mi eclipse. Otra horita de debugger y localicé y corregí el error. Generar una nueva versión del sitema y prueba con éxito.

Pues bien, me costó casi tres horas localizar y corregir el error. No quiero ni pensar lo que habría tardado si me hubiera dedicado a arrancar el sistema completo una y otra vez, generando, instalando versiones y rearrancando cada vez que hubiera tocado algo para probar, manejando toda la interface gráfica (loggeo en el sistema, creación de unos datos, envío por el socket) en cada prueba. Estoy seguro que habría echado un día completo o más, ocupando el sistema e impidiendo a otros trabajar.

Y lo mejor de todo no es que me haya ahorrado varias horas de mi trabajo dejando libre el sistema a los probadores, no. Lo mejor de todo es que ahora hay una prueba que se ejecutará automáticamente cada vez que alguien compile el sistema y nuestro sistema de integración contínua (Hudson), se encargará de hacerlo todas las noches.

Y habría tardado mucho menos si hubiesemos hecho TDD desde el principio, ya que o bien no se habría producido el error, o bien ya habría tenido montada la base para el test automático y sólo habría tenido que añadirle más cosas.

Esta entrada ha sido publicada en tdd y etiquetada como , . Guarda el enlace permanente.

Una respuesta en “Jugando con TDD

  1. Hola, aprovecho que comentas tus primeros pasos en TDD para animarte a ti y a los que siguen tu estupendo blog a uniros a una lista recién creada de TDD en español.

    De momento, con tu permiso, voy a publicar el enlace a esta entrada porque me ha parecido muy inspiradora para aquellos que aún no se atreven a hacer TDD porque no le terminan de encontrar las ventajas.

    También aprovecho para pedirte que busques un hueco para el próximo día 16 de junio y te acerques a la siguiente reunión que organizamos el grupo de Agile Spain en Madrid. Allí queremos ir hablando no sólo de gestión de proyectos sino también de prácticas de ingeniería del software como TDD, integración continua, programación por parejas, etc.

    Un cordial saludo,
    JMB

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.