¿Qué es el Desarrollo Basado en Pruebas (TDD)?

large__8282043567 El desarrollo basado en pruebas es un proceso que se basa en la repetición de un ciclo de desarrollo muy corto. Se basa en el concepto de Programación Extrema (XP), el primero en probar, que fomenta un diseño simple con un alto nivel de confianza.

El procedimiento para hacer TDD es el siguiente:

  1. Escribir una prueba
  2. Ejecutar todas las pruebas
  3. Escribir el código de implementación
  4. Ejecutar todas las pruebas
  5. Refactor

Este procedimiento a menudo se denomina Refactor Rojo-Verde.

Mientras escribimos las pruebas, estamos en el estado rojo. Dado que la prueba se escribe antes de la implementación real, se supone que debe fallar. Si no es así, la prueba está mal. Describe algo que ya existe o que fue escrito incorrectamente. Estar en verde mientras escribe las pruebas es un signo de falso positivo. Pruebas como esa deben ser eliminadas o refactorizadas.

A continuación viene el estado verde. Cuando la implementación de la última prueba haya terminado, todas las pruebas deben pasar. Si no lo hacen, la implementación es incorrecta y debe corregirse.

La idea no es hacer que la implementación sea definitiva, sino proporcionar el código suficiente para que las pruebas pasen. Una vez que todo está en verde, podemos proceder a refactorizar el código existente. Eso significa que estamos haciendo que el código sea más óptimo sin introducir nuevas características. Mientras la refactorización está en su lugar, todas las pruebas deben pasar todo el tiempo. Si uno de ellos falla, refactor rompe una funcionalidad existente. La refactorización no debe incluir nuevas pruebas.

La velocidad es la clave

large_5836417589
Tiendo a ver el TDD como un juego de ping pong (o tenis de mesa). El juego es muy rápido. Lo mismo es válido para TDD. Tiendo a no pasar más de un minuto a cada lado de la mesa (prueba e implementación). Escribir una prueba corta y ejecutarla (ping), escribir la implementación y ejecutar todas las pruebas (pong), escribir otra prueba (ping), escribir la implementación de esa prueba (pong), refactorizar y confirmar que todas las pruebas están pasando (puntuación), repetir. Ping, pong, ping, pong, ping, pong, puntuación, servir de nuevo. No intentes hacer el código perfecto. En su lugar, trate de mantener la bola rodando hasta que piense que es el momento adecuado para anotar (refactor).

No se trata de probar

T en TDD a menudo se malinterpreta. TDD es la forma en que abordamos el diseño. Es la forma de obligarnos a pensar en la implementación antes de escribir el código. Es la manera de estructurar mejor el código. Eso no significa que las pruebas resultantes del uso de TDD sean inútiles. Lejos de eso. Son muy útiles y nos permiten desarrollarnos a gran velocidad sin tener miedo de que algo se rompa. Esto es especialmente cierto cuando se lleva a cabo la refactorización. Ser capaz de reorganizar el código mientras se tiene la confianza de que ninguna funcionalidad está rota es un gran impulso para la calidad del código.

El objetivo principal de TDD es el diseño de código con pruebas como un producto secundario muy útil.

Burlarse

Para que las pruebas se ejecuten rápidamente, proporcionando así una retroalimentación constante, el código debe organizarse de manera que los métodos, funciones y clases puedan ser fácilmente burlados y alterados. La velocidad de ejecución se verá gravemente afectada, por ejemplo, nuestras pruebas necesitan comunicarse con la base de datos. Al burlarnos de dependencias externas, podemos aumentar esa velocidad drásticamente. La ejecución del conjunto de pruebas unitarias debe medirse en minutos, si no en segundos. Más importante que la velocidad, diseñar el código de una manera que pueda ser fácilmente burlado y golpeado nos obliga a estructurar mejor ese código al aplicar la separación de preocupaciones. Con o sin simulaciones, el código debe escribirse de manera que podamos, por ejemplo, reemplazar fácilmente una base de datos por otra. Ese «otro» puede ser, por ejemplo, una base de datos en memoria o burlada.

Un ejemplo de burla en Scala se puede encontrar en el artículo Desarrollo basado en Pruebas (TDD) de Scala: Operaciones de archivos de pruebas unitarias con Specs2 y Mockito. Si su lenguaje de programación de elección no es Scala, el artículo puede ser muy útil para ver el patrón que se puede aplicar a cualquier lenguaje.

Watchers

Una herramienta muy útil cuando se trabaja en la moda TDD son los watchers. Son frameworks o herramientas que se ejecutan antes de que comencemos a trabajar y están atentos a cualquier cambio en el código. Cuando se detecta un cambio de este tipo, se ejecutan todas las pruebas. En el caso de JavaScript, casi todos los sistemas de compilación y corredores de tareas lo permiten. Gulp (mi favorito) y Grunt son dos de muchos ejemplos. Scala tiene revólver sbt (entre otros). La mayoría de los otros lenguajes de programación tienen herramientas similares que recompilan (si es necesario) y ejecutan todas las pruebas (o afectadas) cuando el código cambia. Siempre termino teniendo mi pantalla dividida en dos ventanas. Uno con el código en el que estoy trabajando y el otro con los resultados de pruebas que se ejecutan continuamente. Todo lo que tengo que hacer es prestar atención a que la salida de esos observadores se corresponda con la fase en la que estoy (roja o verde).

Documentación

Otro efecto secundario muy útil del TDD (y de las pruebas bien estructuradas en general) es la documentación. En la mayoría de los casos, es mucho más fácil averiguar qué hace el código mirando pruebas que la implementación en sí. El beneficio adicional que otros tipos de documentación no pueden proporcionar es que las pruebas nunca están desactualizadas. Si hay alguna discrepancia entre las pruebas y el código de implementación, las pruebas fallan. Pruebas fallidas significan documentación inexacta.

El artículo Pruebas como documentación proporciona un razonamiento un poco más profundo detrás del uso de pruebas en lugar de la documentación tradicional.

Resumen

En mi experiencia, TDD es probablemente la herramienta más importante que tenemos en nuestra caja de herramientas de software. Se necesita mucho tiempo y paciencia para dominar el TDD, pero una vez que se domina el arte, la productividad y la calidad aumentan drásticamente. La mejor manera de aprender y practicar TDD es en combinación con la programación por pares. Al igual que en un juego de ping pong que requiere dos participantes, el TDD puede estar en pares donde un codificador escribe pruebas y el otro escribe la implementación de esas pruebas. Los roles pueden cambiar después de cada prueba (como se hace a menudo en los dojos de codificación).

Pruébalo y no te rindas cuando te enfrentes a obstáculos, ya que habrá muchos.

Desarrollo basado en pruebas (TDD): Las mejores prácticas que utilizan Ejemplos de Java son un buen punto de partida. A pesar de que utiliza ejemplos de Java, las mismas prácticas, si no todas, se pueden aplicar a cualquier lenguaje de programación. Para ver un ejemplo en Java (como en el caso anterior, se puede aplicar fácilmente a otros idiomas), consulte el artículo de guía de ejemplo de TDD.

Otra gran manera de perfeccionar las habilidades de TDD son los katas de código (hay muchos en este sitio).

¿Cuál es su experiencia con TDD? Hay tantas variaciones como equipos lo practican y me gustaría escuchar sobre su experiencia.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.