¿Qué es TDD?
En el contexto de un negocio, el propósito del software es agregar valor a ese negocio. Debido a esto, uno de los desafíos clave de cualquier esfuerzo de desarrollo es la asignación de los requisitos y objetivos del negocio en los requisitos del sistema correspondientes. Después de esto, la pregunta se convierte en: ¿Cómo escribir software para cumplir con estos requisitos, y a medida que su proyecto y su base de código crecen, cómo asegurarse de que su software continúe cumpliendo estos requisitosIngrese al desarrollo impulsado por pruebas.
El desarrollo impulsado por pruebas, o TDD, es una metodología organizativa para escribir software mediante la escritura de pruebas que describen y ejercen ese software. En su esencia, TDD es una repetición de tres pasos: Escribir una prueba fallida, hacerla pasar, refactorizar.La idea es que comience con una prueba que describa una pieza de funcionalidad para cualquier característica de software que se esté desarrollando. Ejecutar esa prueba por primera vez debería producir un fallo, porque el código que se está probando aún no se ha escrito. Naturalmente, el siguiente paso es ir a implementar la característica, con el objetivo de hacer la prueba original pasada. El tercer paso, y posiblemente el más importante del ciclo de vida, es entonces refactorizar el código.
Escribir software es un desafío no solo por sus cualidades intrínsecas, sino también por su naturaleza dinámica. Los requisitos empresariales pueden cambiar constantemente y, como resultado, los requisitos de software deben poder adaptarse. El código que se escribe hoy se adaptará a las necesidades de hoy, pero mañana, o dentro de un mes, algo va a cambiar, y como resultado, el código de hoy ya no puede ser la mejor manera de resolver un problema en particular. Mediante la introducción de un mecanismo para comparar lo que el software es hacer a un registro de lo que el software debería ahora tenemos una poderosa herramienta que nos permitirá despedazar, reescribir y reconectar sin miedo nuestro código para cumplir mejor con los requisitos actuales, porque podemos estar seguros de que mientras pasen todas nuestras pruebas, la salida del sistema debe ser la misma.
¿Por qué deberíamos usar TDD?
Una revisión realizada en 2014 por la Universidad de Helsinki encontró que en muchos casos el TDD produjo efectos positivos en términos de defectos, calidad, complejidad y mantenimiento, pero que estas mejoras pueden producirse a costa de mayores esfuerzos de desarrollo. Esta no es una conclusión sorprendente, dado que escribir pruebas adicionales requerirá esfuerzos adicionales, pero lo que estudios de esta naturaleza parecen omitir es el beneficio clave de TDD, que es la retroalimentación.
Cerrar el ciclo de retroalimentación significa acortar la cantidad de tiempo que se necesita para hacer un cambio y aprender algo. Cuanto más rápido puedas hacer esto, más ágil podrás ser. La mayoría de las métricas que intentan cuantificar la productividad del desarrollo se relacionan con las unidades de trabajo a lo largo del tiempo, y al reducir el tiempo que se tarda en recibir retroalimentación accionable, TDD permite un uso más eficiente de ese valioso recurso. Se ha dicho que el tiempo es dinero, por lo que el beneficio económico aquí es evidente. Si alguna vez has escuchado a alguien mencionar un “cambio izquierdo” dentro del contexto del ciclo de vida del desarrollo de software, esto es exactamente a lo que se refieren.
Un beneficio adicional de tener una suite de pruebas para su aplicación es que puede automatizarla. Los desarrolladores no solo pueden ejecutar estas pruebas como parte del ciclo de vida del desarrollo, sino que también pueden ser ejecutadas por otros sistemas como parte de pruebas de humo o una tubería de CI/CD . Al automatizar los pasos para entregar código al mercado, permite una entrega más rápida del producto en su conjunto, lo que a su vez acelera la retroalimentación que puede recibir de los usuarios, que luego puede ser interpretada y aplicada a la siguiente iteración.
Los efectos sinérgicos de estos dos puntos son claros: Con un código base que permite a los desarrolladores adaptar continuamente el código base a las necesidades del negocio, y la capacidad de la empresa de solicitar rápidamente la retroalimentación de sus clientes, el resultado es un sistema que permite a los equipos ofrecer más valor con menos trabajo.
Sacar el máximo provecho de TDD
El desarrollo impulsado por pruebas es solo uno de los muchos enfoques diferentes para probar software. La parte importante, independientemente de la forma en que elija implementarlo, es que proporciona valor a su organización. Como cualquier otra disciplina, debes sentirte libre de usarla, adaptarla como te parezca oportuno, o no usarla en absoluto, basado enteramente en las necesidades de tu organización. Dicho esto, si eliges caminar por el camino del TDD, como predijo el profeta Clapton: “Está en la forma en que lo usas”.
Al igual que cualquier otro instrumento, la eficacia y el valor de la DDT dependen de su aplicación. Con demasiada frecuencia en el desarrollo de software, varias herramientas o técnicas se convierten en chivos expiatorios para explicar los fracasos o deficiencias de un proyecto, pero es un pobre artesano el que culpa a sus herramientas. Así que centrémonos en cómo sacar el máximo provecho de TDD.
Remodelación cultural
El último y más importante paso de TDD es refactorizar el código, pero para que TDD funcione, probablemente no sea la única refactorización que debe suceder. Si elige implementar alguna forma de desarrollo impulsado por pruebas, es importante que la cultura circundante también se adapte para apoyar este estilo de filosofía de desarrollo.
En el caso de TDD, el fracaso más común tiende a ser que el ciclo continuo de escritura de pruebas, haciéndolas pasar, y luego refactorización nunca se completa realmente, sino que se cortocircuita al saltarse el paso de refactorización. La mayoría de las veces el problema no es TDD, o cualquier otra técnica específica, sino más bien la propia cultura en la que se desarrolla el software.
No a diferencia de la documentación, la refactorización parece ser una de las primeras cosas que se tiran por la borda cuando los plazos o los presupuestos se restringen porque después de todo, alguien tiene que escribir todas esas pruebas. Y así se deduce que durante el tiempo de crujido, las pruebas y la documentación, y cualquier otra cosa que no se considere crítica de misión, se descartan. Lo que sigue invariablemente es una disminución constante de la calidad general del código base y, en su lugar, una acumulación de deuda técnica.
La refactorización es el paso del proceso que se esfuerza por transformar el código que simplemente funciona en un código base que es más limpio y más mantenible. Es la parte que permite a los desarrolladores dar un paso atrás y reconocer los patrones dentro del sistema en general y tomar decisiones mejor informadas sobre cómo podrían adaptarse para ser más versátiles o reconocer los antipatrones emergentes y tomar medidas para mitigarlos. Incluso puede ser la diferencia entre reconocer cuándo es el momento de dividir la arquitectura general en microservicios discretos o cualquier otro de una miríada de mejoras potenciales. Sin este paso, puedes perder oportunidades de introspección y mejora incremental, y en última instancia, tu base de código corre el riesgo de una transformación gradual (o no) en una gran bola de barro.
Para cosechar los beneficios del desarrollo impulsado por pruebas, es importante que la cultura tome una visión a largo plazo del proceso en su conjunto, y su potencial, e invierta el tiempo en la aplicación del ciclo completo de «rojo, verde, refactor», y no solo los bits que son convenientes.
Juguetes nuevos brillantes
Cuando se trata del diseño del sistema en su conjunto, muchas veces se dedica demasiado tiempo a planificar los detalles de un sistema sin escribir ningún código. Un proyecto de “campo verde” puede ser emocionante, con todo el potencial anticipatorio asociado con una hoja de papel limpia. Tanto los ingenieros como los arquitectos son víctimas de probar esto, donde abogan por el uso de una tecnología de sabor del mes, ignorando cualquiera de las señales de advertencia de que podría no ser una buena opción para este proyecto en particular a favor de la oportunidad de probar algo nuevo o fresco. Avancemos unos meses y el framework-du-jour ya no satisface las necesidades del equipo, la calidad del código está sufriendo, y volvemos a la parte donde la tecnología se convierte en el chivo expiatorio del mal resultado del proyecto.
Al final lo importante es que la tecnología, metodología o marco utilizado para facilitar TDD funcione para el equipo y para el negocio. Si estás atascado por tus herramientas, no solo no están agregando valor, sino que están trabajando activamente en tu contra. Tenga cuidado en evaluar a fondo cualquier marco que pretenda usar, y tómese el tiempo para entender exactamente cómo lo usará. Este enfoque es válido para todas las decisiones de diseño, no solo para las relacionadas con TDD!
Terminación
En pocas palabras, la idea de algo como TDD es proporcionar un marco para recopilar retroalimentación de una manera más conveniente y no simplemente una técnica para evitar que los bugs aparezcan en su base de código. Sea cual sea el enfoque que elija, la clave debe ser que permita que su negocio y su software se adapten más rápidamente a las tendencias cambiantes y necesidades empresariales. En el camino, ten en cuenta que TDD y sus contrapartes no son simplemente algo que puedes pedir a tu equipo de desarrollo que implemente y luego olvidarte, y que para aprovechar eficazmente estas técnicas se debe tener cuidado en adoptar y habilitar el enfoque a nivel cultural antes de sumergirte en detalles de implementación como marcos y herramientas.