¿Por qué testeamos? Entrega sostenible de valor

Puede parecer que hacer testing tiene como objetivo principal reducir el número de bugs y, aunque este es un efecto colateral muy interesante que tiene esta práctica, en mi opinión no es ni de lejos el que más valor nos puede aportar.

Razonar más y mejor sobre el problema es sin duda el superpoder que nos garantiza hacer testing a distintos niveles, siendo el diseño de nuestro software el más beneficiado al final del proceso. Por supuesto, si el diseño de nuestro código es mejor, será más sencillo de entender y, como decía Martin Fowler, más barato de modificar. Y es que en esta última afirmación podemos ver de una forma más clara la confluencia entre objetivos técnicos y objetivos de negocio.

En este y próximos artículos analizaremos las motivaciones que surgen en esta frontera tan difícil de negociar y cómo puede resultar mucho más sencillo hacer visible su valor si estos objetivos se mantienen alineados con los de negocio. Pero, vayamos poco a poco y centrémonos hoy en analizar cómo testing nos puede ayudar a conseguir que nuestro flujo de entrega sea más sostenible.

Sostenibilidad en el tiempo

Partiendo del Agile Manifesto, podemos ver cómo el software funcionando es uno de los aspectos que más se acaban valorando: Working software over comprehensive documentation. En definitiva, el software entregado y funcionando es el que permite recoger feedback y evaluar hipótesis de negocio, así que cuanto antes podamos tenerlo en manos del usuario, mejor que mejor.

En este sentido, una prioridad para el equipo y, por supuesto, para el negocio, será la entrega rápida y sostenida de valor. No hay nada que nos pueda dar más confianza que ver que el producto llega al usuario final a buen ritmo y sin errores (algo compljeo de conseguir y de hacer sostenible en el tiempo). El problema principal radica en que no es posible alcanzar esta confianza hasta conseguir tener un producto maduro y capaz de adaptarse a los cambios que se van produciendo.

Evidentemente, buscamos sostenibilidad ya que esto no va de acelerar a tope hasta quemar al equipo. De hecho, si el entorno y el proceso presionan demasiado al equipo, los resultados que obtendremos serán justo los contrarios a los esperados.

Entrega de las unidades de valor más prioritarias lo antes posible

Un punto a examinar antes de ver cómo mejorar este flujo de entrega, es cómo colaboramos como equipo para entregar el valor producido. Si arrancamos un sprint y hay una historia de usuario que es la más prioritaria, todo el equipo debería poner su máximo empeño por cerrarla lo antes posible. Todos absolutamente. Si resulta que llega un punto en que en lugar de aportar, nos estamos molestando, pues el resto de integrantes del equipo comenzarán con la segunda historia de usuario más prioritaria, de forma que si en algún momento pueden ayudar en algo a finalizar la primera, lo harán sin dudarlo. La máxima es siempre: El valor más prioritario es el primero en ser entregado.

Por contra, una práctica muy extendida es asignarse cada uno una historia de usuario y comenzar a trabajar en ella de forma autónoma o, incluso peor, tener muchas de ellas pre-asignadas al principio del sprint pensando en la persona concreta que se encargará de ella… Todo esto frena nuestra capacidad de entrega del valor prioritario y aumenta el tiempo total (lead time) de entrega de cada unidad de valor.

Testing en nuestro flujo de entrega

Por último, me gustaría hablar de cómo, si integramos testing en nuestro proceso, nos ayudará a tener más control sobre nuestro código, aunque es interesante tener presentes algunos otros aspectos involucrados como:

  • Confianza en la calidad del código y, en consecuencia, confianza en las estrategías de testing y en la suite que defiende el valor entregado. Un punto fundamental que sólo es posible alcanzar con la madurez del equipo y con la mejora continua de sus prácticas técnicas (aka extreme programming).
  • Independencia en las unidades de valor entregadas. Cada funcionalidad sólo es capaz de llegar a producción lo antes posible si es independiente del resto de historias de usuario y se puede desplegar de forma autónoma. Algunos aspectos clave aquí van desde un desarrollo efectivo del producto y de la definición de su backlog, hasta el uso de técnicas avanzadas de ejecución condicional de código en producción como en el caso de los Feature Flags o Feature Toggles.
  • Confianza en el despliegue y en su automatización. Aunque hay mucho que rascar aquí, quizá el más notable puede ser el relativo a la adopción de DevOps y de las prácticas necesarias de automatización a nivel cultural tanto en el equipo com al resto de niveles de la organización. De forma más contextual a lo que comentamos, podría suponer que cualquier debería de ser capaz de subir una versión a producción y este proceso se debería de poder realizar tantas veces al día como fuera necesario. Algunas referencias fundamentales aquí pueden ser Accelerate: Building and Scaling High-Performing Technology Organizations o Release It!: Design and Deploy Production-Ready Sofware.
  • Aplicación de las estrategias necesarias de Continuous Integration y Continuous Delivery (CI/CD) para la definición de un pipeline unificado y consistente (Continuous Delivery: Reliable Software Releases Throught Build, Test, and Deployment Automation).

En defintiva, muchos aspectos culturales y técnicos que condicionan nuestra forma de afrontar el producto y de cómo este será percibido por negocio y por el usuario final. Todos sumandos y correctamente alineados, incrementarán nuestras posibilidades de conseguir un flujo de entrega más rápido y sostenible en el tiempo.