Principios de TDD (Test Driven Development)

TDD pone el testing en las fases más tempranas de desarrollo del código, cuando los errores son más fáciles y económicos de detectar.

Siendo conscientes de la importancia de las pruebas y de la calidad en el desarrollo de un proyecto de software, es fácil determinar que dichas pruebas deben empezar lo antes posible, clave por ejemplo en el testing continuo.

Y para conseguirlo, TDD avanza el concepto de pruebas hasta el punto tener que definirlo antes de escribir ni una línea de código.

Historia del Test Driven Development

El inicio de TDD se le atribuye a Kent Beck, autor del libro Extreme Programming en 1999, y que posteriormente también publicaría en 2003 Test-driven Development: By Example.

Aunque él mismo, lo menciona como un “redescubrimiento”, pues en libros de los años 50 y 60, ya se menciona que no se debe programar y después comprobar que funciona, sino que el programador primero debería definir la prueba para, con esa información, realizar el programa.

Lo que supone un cambio trascendental con la metodología de hace unas décadas, es que por aquel entonces las pruebas eran manuales, mientras que en la actualidad la facilidad para automatizar pruebas, nos permiten darle un enfoque distinto.

Qué es TDD

TDD son las siglas de Test Driven Development, que significa desarrollo guiado por pruebas.

Así, TDD es el proceso de desarrollo de software realizado a través de un pequeño y repetitivo ciclo, donde a grandes rasgos los requisitos pasan a ser casos de prueba y posteriormente se escribe el código que permitirá pasar dichas pruebas.

Beneficios del desarrollo guiado por pruebas

TDD permite una validación del código desarrollado, posiblemente en ciclos más pequeños, lo que facilita la detección de errores, así como su resolución.

Por otro lado, si se cumplen todos los pasos que se ven a continuación, la fiabilidad de esta aplicación será muy elevada, no solo desde el punto de vista de errores funcionales, sino también en la consecución de realizar el desarrollo solicitado por el negocio o el cliente.

Otro beneficio del Test Driven Development, es la optimización o rendimiento del código, ya que hace hincapié en escribir únicamente el código necesario para la consecución de los distintos objetivos, y dispone de pasos donde pueda mejorarse aún más.

El hecho de realizar pruebas por cada nueva funcionalidad o requisito, facilita el desarrollo de una forma modular, lo que aumentará la escalabilidad del proyecto, así como su futuro mantenimiento.

Ciclo de TDD

Ahora que ya sabes que es el Test Driven Development, y los beneficios que tiene su seguimiento, vamos a ver el ciclo completo de este proceso, detallando cada uno de sus pasos.

TDD

Crear el test

En primer lugar, se crean las pruebas.

Y éstas se realizan a partir de cada una de las nuevas características o funciones definidas en los requisitos.

En esta parte, es muy importante, que quien realice las pruebas comprenda perfectamente la especificación de requisitos, ya que las diferencias entre lo que haya entendido y lo que requiera la aplicación en realidad, repercutirá en la calidad de la prueba

Así, podemos ver, que la diferencia de estas pruebas, con los test unitarios, es que éstos últimos, se hacen observando el código (que ya está creado), mientras que en TDD, el foco se pone en los requisitos, entre otras cosas, porque el código aún no se ha creado.

Ejecutar los test y comprobar que fallan

Este paso se realiza para asegurar que los test funcionan correctamente, y por lo tanto, detectarán errores cuando haya un problema en el código.

Una de las principales ventajas de este paso, es la confianza que adquiere el desarrollador en las nuevas pruebas y, por lo tanto, en la calidad del código.

Escribir el código de la aplicación

El siguiente paso será el de escribir el código.

El objetivo, será simplemente el de pasar la prueba que hemos escrito.

Quizá este código no es perfecto, y no sea del todo bonito, pero para mejorarlo ya hay una parte posterior, donde con una visión más global del nuevo desarrollo, podremos optimizarlo.

Ejecutar los test

Ya con el código creado, podemos ejecutar las pruebas que hemos creado en el primer paso.

Si las pruebas se superan, podemos confiar en la calidad de nuestro código.

En caso contrario, debemos corregir el código hasta que supere todos los test, y por lo tanto, constatemos que tiene la calidad que queremos.

Refactorizar el código

En este paso, ya disponemos de código de calidad, porque pasa las pruebas. Pero ello no impide que pueda ser mejorado.

Por un lado, se debe recordar que, en el paso de escribir el código, el único objetivo, era que superara la prueba, por lo que en este paso, podemos mejorar su estructura para que se pueda interpretar mejor, o reducir por ejemplo su número de líneas. Siempre y cuando no altere sus resultados claro.

Por otro lado, el crecimiento continuo del código, obliga a revisarlo periódicamente, ya que, con una visión más amplia de todo el proyecto, podremos realizar mejoras y evitar malas prácticas como por ejemplo código duplicado o funciones redundantes.

Repetir

Una vez completado este ciclo para, por ejemplo, completar una historia de usuario, se debe repetir todo el proceso.

Recomendaciones de buenas practicas

Por último, solo queda recomendar una serie de buenas prácticas, que permitirán una mejor asimilación del proceso para aquellos que se inicien, así como una mejor comprensión del proyecto por parte de todo el equipo.

Estructura de los test

Un diseño efectivo de los casos de prueba, asegura  que todas las acciones se realizan, mejora la legibilidad de la prueba y mejora su ejecución.

Una estructura homogénea y estandarizada, ayuda en la construcción de la documentación oportuna.

Una estructura común que se suele aplicar sería la siguiente:

  • Configuración
  • Ejecución
  • Validación
  • Limpieza

Prácticas a evitar, o “antipatrones”

Por el contrario, deberíamos tratar de evitar lo siguiente:

  • Dependencias con el sistema, ya que obstaculizará la escalabilidad del proyecto.
  • Dependencias entre los casos de prueba, que reducirían la modularidad y la efectividad de dichas pruebas al repetirse cuando el proyecto evolucione
  • Comprobar detalles de implementación, pues las pruebas deberían centrarse en funcionalidades requeridas.
  • Pruebas que tarden mucho en finalizar.
  • Comprobaciones demasiado minuciosas de detalles poco relevantes.

Fuentes:

Imagen destacada:

Deja un comentario