Cómo implementar Test-Driven Development (TDD) sin morir en el intento

Daniel Rivera
Nursoft
Published in
6 min readJun 6, 2019

Si es sobre el día a día — las operaciones — de una boutique de desarrollo de software, estoy obligado a mencionar cinco temas principales que están en nuestras cabezas:

  1. Como la tecnología que desarrollamos entrega valor.
  2. Desarrollamos software de calidad.
  3. Código con una baja cantidad de bugs.
  4. Ciclos de desarrollo ágiles (o en resumen: cortos).
  5. Ganar las partidas de Mario Tennis.

El primer tema, es una compleja y larga historia. La última es fácil. La 2, 3 y 4 las abordamos en Nursoft ya sea a través de nuevas (o mejores) herramientas o metodologías de desarrollo.

En los varios almuerzo de desarrolladores (que por lo demás en este post se aborda un poco de que tratan) es implementar mejores fases de pruebas, específicamente mediante Test-Driven Development (TDD) en los procesos de desarrollo. Pero realmente no es algo que se pueda tomar a la ligera.

Si el ciclo de desarrollo fácil de entender y simple en su nomenclatura, ¿por qué resulta complicado implementarlo — al principio — como un proceso mas de desarrollo? Son varias las razones, por lo que es importante entender y visualizar el propósito y contexto sobre el cual se busca implementar las pruebas.

¿Que es Test-Driven Development o simplemente TDD?

Es un proceso que se basa en la repetición de pequeños ciclos de desarrollo.

Dicho de otra forma, los requerimientos de un software son convertidos en casos de pruebas específicos, y luego el software es construido con el enfoque de pasar estas nuevas pruebas.

La metodología TDD fue propuesta o ‘redescubierta’ por Kent Beck, y se encuentra relacionado con uno de los pilares fundamentales de la programación extrema (XP), siendo el enfoque de estos procesos simples que otorguen valor en corto plazo.

Ojo: la relación TDD-XP no es excluyente.

Etapas de TDD

Según lo que nos cuenta Kent Beck en ‘Test-Driven Development by Example’, las etapas para implementar TDD son:

1. Desarrollar una prueba

En el inicio del ciclo de TDD, cada nuevo proceso de desarrollo de una funcionalidad comienza con la creación de una prueba de validación.

Para lograr este procedimiento, el software engineer debe tener un conocimiento claro de los requerimientos, condicionales y casos bordes.

Este ejercicio es fundamental para que el desarrollador se enfoque primero en los requerimientos previo a crear código. Esto también es otra forma de orientarse al negocio buscando crear valor desde la tecnología.

2. Escribir código

Sin código, al ejecutar las pruebas obviamente estas resultarán negativas (red state), por lo tanto el proceso de desarrollo se debe enfocar en validar los casos de aceptación de las pruebas.

3. Validar las pruebas

Si el código desarrollado en la etapa anterior pasa todas las pruebas establecidas, entonces es seguro decir que el software pasa los requerimientos definidos.

El secreto está en definir correctamente los requerimientos.

4. Refactorización

En la etapa 2 (escribir código) el código no necesariamente se encuentre desarrollado de la manera más óptima (hay que recordar que los procesos de desarrollo deben ser ágiles). O conforme el software crece, comienzan a surgir necesidades de abstracción, modularización, eliminar casos de duplicación, entre otras .

Esta proceso (etapa) de refactorización de código ocurre cada cierta cantidad de ciclos cumplidos.

¿Porque es tan difícil incorporar Test-Driven Development?

Si el proceso es relativamente simple y rápido, ¿porque es tan difícil implementar TDD en el proceso de desarrollo de software?, más bien lo que resulta complejo es que las pruebas creadas otorguen un valor en el proceso de desarrollo para el cliente.

Todo puede ser convertido en una prueba de validación, pero:

  • ¿Es necesario que todo pase por una fase de prueba?
  • ¿Otorga valor a largo plazo?
  • ¿Es justificable el tiempo implementado en vez de destinar tiempo en desarrollo del software mismo?

La principal desventaja que resalta para aquellos que se están iniciando en el proceso de implementación de TDD, es que inevitablemente traerá consigo un mayor tiempo de desarrollo, la curva de aprendizaje es algo confusa, y finalmente cumplir los deadlines se convierte en la máxima prioridad.

Otra razón por la cual resulta complicado implementar TDD es que el proceso en sí ofrece muy poca orientación para su práctica. Cuando uno se encuentra en etapa de aprendizaje de algo nuevo, es común seguir un set de reglas pre establecidas para entender el contexto y adquirir suficiente experiencia para cuestionar y/o romper dichas reglas, he ahí la famosa frase de cual es la mejor manera de realizar una acción: “Depende del contexto”.

Las reglas de TDD son tan simples, que estas no te ofrecen suficiente guía para ser aplicadas sin entender el contexto ni el propósito del código a evaluar. Son muchas las variables que se deben considerar, tales como: framework disponible, tipo de prueba (unitaria, integración), nivel de abstracción, entre otras variables.

Si las pruebas desarrolladas en el ciclo de TDD son creadas sin tener una clara comprensión del contexto y sin un objetivo bien planteado, terminarán aumentando el tiempo de desarrollo, sin otorgar valor y frustrando al cliente y al software engineer.

Entonces, ¿cuál es el camino a seguir si uno busca aprender e implementar de forma correcta Test Driven Development?

Como software engineer en Nursoft — que estuvo en proceso de aprendizaje — , no resulta eficiente llegar e implementar TDD a mitad de un ciclo de desarrollo y esperar obtener un resultado que otorgue valor en el corto y largo plazo.

Por eso hice estos pasos para avanzar de forma iterativa e impregnarse de forma correcta con la cultura de Test-driven Development.

Documentación, entender el mecanismo

Entender la herramienta que uno está usando es fundamental para comprender sus alcances, pero también la filosofía detrás del procedimiento y el objetivo que se persigue, en este caso: mejorar la calidad y mantenibilidad del código.

Como ejemplo: dado un entorno con ReactJs como frontend, el framework Jest es ampliamente usado y validado por la comunidad, dada su simplicidad y su filosofía de ‘zero-configuration’. Probar en un entorno seguro con las diferentes configuraciones es mas seguro que implementar en un entorno de trabajo real, dado que es altamente probable que los primeros tests desarrollados no otorguen valor claro.

Implementar Pruebas y desarrollar al mismo tiempo

Esta suena contraproducente al principio de TDD, pero ¡el objetivo en esta etapa es crear código!

Empezar desarrollando pruebas para código ya implementado no es tiempo perdido, ya que otro de los beneficios de implementar pruebas es crear documentación comprensible, especialmente para el desarrollo de legacy code.

Identificar patrones y casos de usos frecuentes

Durante el paso de la etapa anterior, comienzan a surgir los patrones de implementación. Hay algunas cosas comunes que uno puede comenzar a observar, por ejemplo:

  • ¿Qué es lo que se repite en la validación de formulario?
  • ¿Cómo implementar validación en servicios externos (API, Sockets, entre otras)?
  • ¿Es posible abstraer categorías de pruebas?

Tener una imagen generalizada (big picture; hablar con el software architect es una buena idea) de la estructura y alcance de los distintos tipos de pruebas es clave para pensar en ellas previo su correspondiente desarrollo.

TL;DR

  • TDD es una metodología que se compone de 4 pasos (diseño de pruebas, desarrollar, validar y refactorizar) que permite centrarse y validar los elementos tecnológicos que le generan valor al cliente.
  • No suele ser fácil la implementación de TDD en las organizaciones, principalmente porque se ve fácil pero entender la real idea y función es más complejo. Protip: TDD permite centrarse en el cliente.
  • Para facilitar la implementación de TDD en cualquier organización es bueno: centrarse en la filosofía de TDD, en un inicio implementar pruebas de código/software ya desarrollado y trabajar sobre patrones/casos frecuentes.

Lecturas Recomendadas:

Daniel es Software Engineer en Nursoft, es capaz de desarrollar cualquier proyecto que le pidan e imitar cualquier sonido, pero no necesariamente en ese orden.

¿Quieres un proyecto centrado en la calidad y valor? contacto@nursoft.cl

¿Sabes o te gustaría desarrollar centrado en pruebas (TDD)? humanos@nursoft.cl

¿Test-driven Development? hola@nursoft.cl

También tenemos Twitter, Instagram, Facebook, LinkedIn y Dribbble.

--

--