Ir al contenido principal

Pruebas automáticas, TDD y BDD

Pruebas automáticas, TDD y BDD

Cuando se comienza con el desarrollo de software, el ciclo de producción es más o menos:  escribir líneas de código, realizar pruebas manuales del de sistema y luego repetir hasta quedar satisfecho con el producto resultante. Más adelante, se empieza a escuchar hablar sobre pruebas automáticas y se empieza a investigar en términos como Pruebas automáticas, TDD y BDD… y es fácil sentirse confuso y perdido.
Es fácil verse abrumado por toda la jerga técnica, y la situación se complica cuando se están comparando manzana con naranjas. Aquí me gustaría responder qué son cada uno de ellos.

Prueba automáticas

Una prueba automática es un trozo de código ejecutable que se escribe para probar un “bloque de código”. Generalmente son funciones cortas y simples; y se escriben para probar funciones, clases o módulos cuyo funcionamiento pueda ser verificado.

Si se tienen problemas para escribir el código de prueba para una función, lo más probable es que sea necesario refactorizar la función para dividir las dependencias.

La idea es tener muchas pruebas unitarias en un módulo, de tal forma que cuando modificamos un determinado código, el funcionamiento de todo el módulo sigue siendo el esperado; y no hemos provocado ningún efecto lateral inesperado.

Existen tres niveles dentro de las pruebas automáticas:

  • Pruebas unitarias: Se prueba una única pieza de código, como un objeto o una función, siempre aislandola del resto.
  • Pruebas de integración: Estas pruebas se corren una vez aprobadas las pruebas unitarias, con el fin de probar un conjunto de partes de software para ver su funcionamiento.
  • Pruebas funcionales o de aceptación: Son pruebas automáticas del conjunto de la aplicación.

Diseño impulsado por los Test (TDD, Test Driven Desing)

Por otro lado, TDD es un proceso para la escritura de pruebas. El proceso de desarrollo comienza escribiendo primero una prueba que invoca una nueva función vacía (antes de escribir la implementación de la propia función). Inicialmente, la prueba fallaría porque está llamando a una función sin implementar, de hecho debe fallar, de lo contrario estaría probando la función incorrecta. Después de ver que falla, entonces se empieza a escribir el código en la función para pasar la prueba.

El proceso de iterar entre entre las pruebas fallidas y la actualización de la función para pasar la prueba se conoce como TDD. El proceso no está limitado únicamente al alcance de las pruebas unitarias.

El código resultante será bien probado, porque la prueba se escribe primero y es necesario que se escriba una función que pase la prueba. El software resultante suele tener también una elevada cobertura de pruebas, ya que se está creando al menos un test por cada función.

Diseño impulsado por el comportamiento (BDD, Behaviour Driven Design)

El diseño impulsado por el comportamiento (BDD), como su nombre lo sugiere, es una de las mejores prácticas para escribir código mediante TDD. Se enfoca en cómo escribir un TDD centrándose en validar el comportamiento esperado, y no en la implementación del test. Es una forma muy recomendable de escribir los test de TDD porque la prueba que valida el comportamiento de una función es más fácil de mantener y tiene una mejor legibilidad.

Se parte de historias de usuario, como por ejemplo: “Como usuario quiero recibir una alerta cuando mi cuenta se quede al descubierto”. Ahora en vez de utilizar el “lenguaje natural” se va a utilizar un lenguaje específico de BDD: un lenguaje que entienden humanos y ordenadores.
Como vemos, la BDD sugiere probar comportamientos en lugar de ver cómo implementar el código. Expresar una prueba es decir “debería hacer esto”. BDD recoge las mejores prácticas del TDD e intenta guiar al desarrollador a la hora de elegir qué parte de la aplicación probar. Sumándole test de aceptación puede ayudar a priorizar el desarrollo de los requisitos que más valor aportan al usuario.

Conclusión

Las pruebas unitarias te dicen qué testear, la TDD cuándo y la BDD cómo. Aunque todos se pueden utilizar de manera aislada, se recomienda complementarlos para tener un código de alta que calidad que nos asegure que siempre va a cumplir con nuestros requisitos. Os aseguro que os va a quitar un montón de problemas de cara al mantenimiento del código, pues hasta un 77% de los errores que hay en producción se podrían evitar con unos buenos tests.

Fuentes:

    Sir Hoe Teo: Architect | Senior Software Engineer | Nodejs | MongoDB | AWS | C#
    Gemma Arnáiz Delgado: Global payments at Beeva, Organizer of Google Developers Group Burgos. Ruby on rails, Java (Spring) & iOS Developer.

Comentarios