La deuda técnica es trabajo de producto diferido, a menudo como consecuencia de decisiones tomadas por los Desarrolladores para favorecer la rapidez en detrimento de la calidad. Por ejemplo: la ausencia de tests automatizados, ausencia de tests unitarios, código duplicado o excesivamente complejo, ausencia de un sistema de build y deployment, etc. Estos “atajos” o malas decisiones de diseño o implementación crean deuda técnica, que se acumula poco a poco.
Si la deuda técnica se acumula hasta tal punto que hace difícil el obtener un Incremento de Producto Terminado al final de cada Sprint, será necesario saldar esa deuda cuanto antes. Lo ideal será no llegar a escenarios de deuda técnica tan elevada que afecte de manera severa a nuestra capacidad de innovar.
Uno de los casos más dramáticos de deuda técnica que he visto fue el de una plataforma que, a’un siendo el producto principal de la empresa, se había convertido en pura deuda técnica. El producto estaba programado en classic ASP y los Desarrolladores ni siquiera se atrevían a tocarlo. Hacer cualquier cambio llevaba semanas. La empresa había perdido su capacidad de innovación, mientras que la competencia era cada vez más acuciante. La solución en este caso fue reconstruir la plataforma desde cero, lo que supuso un esfuerzo de desarrollo gigantesco. En realidad, aunque pueda parecer extrema, esta situación la he visto no una vez, sino con una frecuencia sorprendente.
Otro ejemplo más al uso. Un Equipo, presionado por acuciantes plazos de entrega, intenta acortar tiempos y no escribir tests unitarios (como dictaba su Definición de Hecho). Ponen en producción una funcionalidad de contratos electrónicos, sin mostrarla aún a los usuarios finales, puesto que había que completar unos scripts con los datos individualizados que debían constar en tales contratos. Sin embargo, alguien puso una coma en el lugar equivocado y, por error, la nueva funcionalidad empieza a mostrarse en la aplicación. Los usuarios quedan confundidos, llegan cientos de quejas a soporte, y los Desarrolladores tuvieron que retirar la funcionalidad y pasar días lidiando con los daños colaterales causados. Antes de volver a desplegar a producción, el Equipo tuvo que añadir los tests unitarios y testearlo todo, eliminando la deuda técnica sin demora. Moraleja: mucho cuidado con esos falsos “atajos” que terminan por ser justo lo contrario.
1/ Tengamos una Definición de Hecho que deje poco margen a la acumulación de deuda técnica.
Cuando la Definición de Hecho tiene baja tolerancia para la acumulación de deuda técnica, esta aparecerá en menor medida, contribuyendo a hacer el producto más mantenible en el largo plazo.
Asimismo, a medida que el Equipo enriquece su Definición de Hecho, cuando trabaje en áreas del código que no la cumplan, deberá mejorarlas para que se adecúen. Por ejemplo, si la Definición de Terminado no incluía test unitarios, pero ahora sí, las pruebas unitarias deberán ser añadidas paulatinamente, a medida que los Desarrolladores trabajan con código preexistente.
2/ Hagamos que la deuda técnica sea transparente.
Si capturamos la deuda técnica dentro del Product Backlog, la estaremos haciendo visible para el Equipo Scrum y los stakeholders. Entonces, el Product Owner podrá ordenar los elementos del Product Backlog siendo consciente de ella, y tomará mejores decisiones.
Lo mejor será expresar la deuda técnica en términos de valor para el negocio o los clientes o usuarios. Por ejemplo, “refactorizar el carrito de la compra para minimizar el numero de bugs, considerando que estimamos una pérdida de ingresos de X al mes por estos errores”, o “Refactorizar la funcionalidad X, reduciendo el tiempo de testeo en un 50%”.
3/ Generemos un entendimiento compartido sobre la deuda técnica y la estrategia a seguir para afrontarla, dependiendo del cuadrante en el que nos encontremos.
Los cuadrantes de deuda técnica, acuñados por Martin Fowler, son los siguientes.