TDD (Test Driven Development)

El TDD no deja indiferente, o lo amas o lo odias. Personalmente no voy a entrar en polémicas sobre si el TDD está muerto o no, en lugar de ello, en este artículo vamos a practicar un poco de TDD.

¿Qué es TDD?

TDD en una frase:

Implementa únicamente el código necesario para que tu test pase

TDD es una técnica de desarrollo de software que nace de la mente de Ken Beck, creador de las metodologías de diseño ágil XP. No se trata de una técnica para probar el código, sino como ya he dicho es una técnica de desarrollo. Primero se plantea la necesidad a implementa a través de la definición de un test que describa la funcionalidad y luego se implementa el código. El algoritmo TDD es el siguiente:

  • Rojo (Se implementa un test que evidentemente fallará, ya que ni siquiera disponemos del código que implementa la solución).
  • Verde (se realiza la implementación mínima que hace que el test pase)
  • Refactorizar (Se refactoriza el código, evitando duplicidades, código sucio, etc.)
  • Se vuelve a repetir el cliclo, implementando test adicionales que completen toda la funcionalidad. Para esto existen tres extratégias:
    • Fake: Solición mínima, aunque sea hardconde (ej: return true;)
    • Triangulación: Añadir nuevas pruebas contra la misma funcionalidad buscando situaciones no implementadas
    • Imlementación obvia

El diario de diseño

Una de las cosas que raramente se hace y que bajo mi punto de vista es fundamental es definir el diario de diseño.

Antes de empezar un ciclo de TDD hay que pensar en que vamos a trabajar. El diario de diseño contiene la lista de tareas pendientes de hacer. El objetivo centrarnos en los objetivos que tenemos que implementar. Vamos a ver esto con un ejemplo. Implementaremos la versión ampliada del juego “piedra, papel o tijera” de la serie Big Bang Theory.

bbt

El primer paso será escribir nuestro diario de diseño:

  • Si las dos elecciones son las mismas es un empate
  • Las tijeras cortan el papel
  • El papel cubre a la piedra
  • La piedra aplasta al lagarto
  • El lagarto envenena a Spock
  • Spock destroza las tijeras
  • Las tijeras decapitan al lagarto
  • El lagarto se come el papel
  • El papel refuta a Spock
  • Spock vaporiza la piedra
  • La piedra aplasta las tijeras

Elegimos un elemento del diario de diseño y empezamos. No es necesario ir en orden.

Si las dos elecciones son las mismas es un empate

Rojo:

Aquí empieza lo interesante del TDD. Aunque no hemos implementado nada, ya hemos tomado algunas decisiones:

  • Definimos el modo en el que queremos realizar la llamada para invocar al juego.
  • Hemos indicado que queremos utilizar enumerados para enviar los parámetros
  • Hemos indicado que queremos utilizar enumerados también para obtener el resultado

Al ejecutar el test, evidentemente sale rojo, de hecho ni siquiera compila.

El test está en rojo

El test está en rojo

Verde. Aplicamos un Fake:

Como se puede ver, devolvemos directamente “EMPATE”. Creamos los enumerados Jugada y Ganador y ejecutamos el test. Comprobamos que el test está verde y refactorizamos. En este caso no hay mucho que refactorizar.

Bien, ahora tenemos que triangular, esto es, buscar test que fallen con nuestra implementación, así que volvemos al rojo:

Solución con código mínimo: “baby steps“, únicamente nos preocupamos de solucionar el problema que tenemos delante:

Bien, ya estamos en verde, así que refactorizamos, tanto el código como los tests:

Y avanzamos sobre el diario de diseño:

  • Si las dos elecciones son las mismas es un empate
  • Las tijeras cortan el papel
  • El papel cubre a la piedra
  • La piedra aplasta al lagarto
  • El lagarto envenena a Spock
  • Spock destroza las tijeras
  • Las tijeras decapitan al lagarto
  • El lagarto se come el papel
  • El papel refuta a Spock
  • Spock vaporiza la piedra
  • La piedra aplasta las tijeras

 Tijeras cortan papel

Rojo

 Verde

Refactorizar

Con la pinta que tiene la solución que hemos implementado, podemos ver que se está volviendo grande y repetitiva. Como hemos definido para la jugada un tipo enumerado, y cada enumerado es capaz de saber a quién gana, vamos a definir una función abstracta en el propio enumerado que reciba una jugada y nos diga si la gana o no. De este modo:

Ahora solo nos queda llevar a cada elemento del enumerado la relación de ganadores:

 Tijeras decapitan lagarto

 

Repetimos el proceso con el resto del diario de diseño, tachando los casos que vamos completando. En el caso de “Tijeras decapitan lagarto“, basta con añadir un OR:

Continuamos repitiendo el algoritmo TDD, hasta que terminemos la implementación.

La solución

La clase de test queda del siguiente modo:

La clase PiedraPapelTijeraLagartoSpook

 

La clase Jugada

Y finalmente la clase Ganador

Bueno, aquí terminamos el artículo. Espero que os haya gustado.

Recordad que los comentarios son moderados y pueden tardar en aparecer

Un comentario:

  1. Great!
    En este artículo estuve aprendiendo algo nuevo para mí pero aplicando lo que aprendí divirtiéndome con las alocadas aventuras intelectuales del famoso personaje Sheldon Cooper en The Big Bang Theory. Por cierto, lo explicaste muy bien. Una pequeña fe de erratas: no es spook sino Spock.
    Te mando un abrazo y… “Larga vida y prosperidad” (Spock).

Deja un comentario

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