Tareas realizadas y no realizadas
Por Ken Schwaber y David Starr, Scrum.org
Enero de 2012
La entrega de un incremento finalizado es crucial para el éxito de Agile Software Development. Mediante el uso de ejemplos reales y teóricos, los autores muestran la diferencia entre la percepción de "finalizado" y la realidad de “finalizado”, y cómo afecta esto al éxito de un proyecto. Con estos ejemplos, los autores muestran las herramientas y las estrategias que pueden ayudar a los equipos a empezar con una definición de finalizado que tenga sentido para ellos, así como los métodos que les ayudan a comunicar las dependencias, el estado y el significado de “finalizado”.
Se aplica a
Application Lifecycle Management; Team Foundation Server
En este artículo:
Introducción
Pérdida de transparencia en la compañía de Ana
Lo que la gente pensaba que sucedía
Lo que sucedió realmente
La lección
Deuda técnica en Nanomedtronics AZ
Lo que la gente pensaba que sucedía
Lo que sucedió realmente
La lección
La deuda técnica aumenta cuando hay varios equipos
El plan de lanzamiento en A Datum Corporation
Lo que la gente pensaba que sucedía
Lo que sucedió realmente
La lección
Técnicas a gran escala para finalizar tareas
Scrum de Scrums
Integración continua
Conclusión
Scrum es un marco de trabajo ágil incremental e iterativo. Los equipos lo utilizan para entregar rápidamente incrementos de "finalizado", funcionalidad de software potencialmente utilizable en cada iteración o sprint.
"Finalizado" es una palabra sencilla pero que se suele interpretar erróneamente. Para mí, significa terminado, finalizado y completo. Finalizado significa que no queda nada por hacer. Listo es fácil de definir; sin embargo, la entrega de un incremento finalizado sigue siendo uno de los requisitos fundamentales y más escurridizos de Scrum y la agilidad.
La agilidad requiere entregar incrementos listos para su uso de software que funcione en cada Sprint. Aun así, la mayoría de los equipos de Scrum y ágiles generan incrementos incompletos parcialmente realizados. Cuando se pregunta a un equipo de Scrum por qué los requisitos del trabajo pendiente del producto no se completaron totalmente en un sprint, los miembros del equipo responden a menudo “No teníamos tiempo”.
Este documento trata de los problemas relacionados con los incrementos finalizados mediante ejemplos de casos prácticos reales procedentes de los primeros días de Scrum. Los nombres y las ubicaciones de los implicados se han cambiado pero estoy seguro de que las personas se reconocerán a sí mismas y a su duro trabajo. Todos los sprints de este caso son una iteración mensual, a menos que se indique lo contrario.
Pérdida de transparencia en la compañía de Ana
Ana necesitaba automatizar la recepción de cambios en los títulos de propiedad en su departamento. La compañía para la que trabajaba construía y explotaba los gasoductos de casi toda Norteamérica. Su departamento procesaba y abonaba los derechos a las personas que poseían la tierra que atravesaban. La información sobre los títulos de propiedad que recibía el departamento de Ana estaba en forma de copias impresas o documentos de cambio de propiedad. El volumen llegaba a ser abrumador, por lo que Ana deseaba automatizar el proceso de lectura de datos y de pago de derechos.
Nuestro equipo de desarrollo propuso que creáramos el sistema de derechos para Ana mediante Scrum. Gracias a esto, tendría un software útil para inspeccionar cada mes. Ella también tenía derecho a cambiar de opinión cada mes sobre lo que haría nuestro equipo a continuación.
Al final de tercer Sprint, teníamos una fuente de alguna de las provincias funcionando e integrada con datos más antiguos. Lo demostramos mediante una sencilla solución SQL. Ana estaba muy contenta porque la mayoría del trabajo pendiente del producto del personal era de esta provincia.
Quería que enseñáramos SQL a su personal para que pudieran empezar inmediatamente a utilizar el software que el equipo de desarrollo había entregado.
¿Qué quería decir con que deseaba utilizarlo? Seguramente, ella había confundido terminar con un Sprint con terminar con el software.
Se lo dijimos a Ana de la forma más delicada posible. Ella se puso lívida. “¿Qué quiere decir con que no está listo? Vi el primer incremento, el segundo incremento y ahora quiero empezar a usarlo. Impleméntelo y enséñenos a usar SQL para que podamos usarlo”.
Comenzamos a sentirnos incómodos. Le dijimos a Ana que sí, que estaba finalizado. Pero que no era ese tipo de tarea realizada. Estaba listo para mostrárselo, pero todavía había problemas que resolver antes de que el software se pudiera usar:
Algunos registros de entrada no se podían procesar. Necesitábamos una instalación para almacenarlos y administrarlos, en vez de tirarlos.
Varios de los campos de los registros de entrada parecían utilizarse para propósitos distintos de los documentados. ¿Qué se debe hacer con ellos?
Los campos de la base de datos existente contenían punteros o información que parecían información de referencia. Esto estaba por toda la base de datos.
Cuando ejecutábamos las fuentes entrantes y consultábamos la base de datos, el sistema se bloqueó varias veces. Parecía que los datos estaban dañados durante estos bloqueos.
Ana nos preguntó cuánto tiempo quedaba para que pudiéramos hacer que fuera su tipo de finalización, una finalización que se pudiera utilizar. Estimamos que eran necesarios otros dos sprints para poder utilizar los incrementos. Nos dijo que siguiéramos adelante y que lo tuviéramos listo para que lo utilizase su departamento. A continuación, me “pidió" que me reuniera con ella la mañana siguiente.
A la mañana siguiente Ana, su jefe y el director de desarrollo estaban allí. Se mostraron decepcionados por no encontrar la transparencia que yo había solicitado. Opinaban que yo debía haber tratado los problemas sin resolver de una manera diferente que simplemente registrarlos como errores. Estaban molestos porque el progreso que se reflejaba en los informes de evolución proporcionados a todo el mundo era incorrecto.
Después de la reunión, los pedidos en curso eran:
Investigar y corregir los cuatro errores.
Finalizar e implementar los tres primeros incrementos para que el departamento de Ana pueda comenzar a usarlos.
Mejorar nuestras habilidades en ingeniería y automatización de pruebas de modo que nuestra definición de tarea realizada sea igual que la definición de Ana (uso inmediato por parte de la empresa).
Cambiar la manera de registrar defectos, de modo que el requisito no se considere finalizado a menos que se corrijan.
Nos dijeron que sería una buena oportunidad de aprendizaje, si todos aprendíamos nuestras lecciones.
Lo que la gente pensaba que sucedía
Cuando desarrollamos un plan de línea base para el sistema, este representaba lo que Anna y las partes interesadas pensaban que sucedería. El equipo de desarrollo informó sobre el progreso y todo parecía indicar que la versión marchaba según lo previsto, y las personas creyeron el informe.
El equipo de desarrollo creía realmente que hacía lo correcto mostrando que el trabajo continuaba según lo indicado en el plan.
Lo que sucedió realmente
La velocidad es la medida y el registro histórico de la productividad por sprint de un equipo de desarrollo. La velocidad se mide en cada sprint y se utiliza para establecer patrones de productividad.
Nuestro equipo de desarrollo necesitaba una velocidad continua de 8 unidades completas de trabajo en cada Sprint para cumplir el plan. Cuando algo amenazaba con disminuir nuestra velocidad por debajo de 8, no terminábamos todo el trabajo de esos elementos.
Entregábamos funcionalidad que funcionaba bastante bien, pero que no estaba suficientemente completa para poder utilizarse o servir como base para el desarrollo. Nos propusimos mejorarlo posteriormente. Cuando volvimos para estimar el trabajo no realizado, esto agregó otras 14 unidades de trabajo.
Teniendo en cuenta lo complicadas que eran las fuentes iniciales de títulos, tuvimos que revisar la totalidad del plan para reflejar una programación de probablemente veinte meses. El departamento de Ana envía incrementos cada dos meses aproximadamente, habilitando fuentes nuevas. Las nuevas fuentes automatizadas redujeron el trabajo manual total de tal manera que fue decepcionante cuando el sistema se activó veintidós meses después de su inicio.
La lección
La transparencia real requiere que todas las personas que vean el incremento deben ver y entender lo mismo. La inspección transparente del incremento debería haber permitido que Ana administrase el riesgo y consiguiese previsibilidad. Sin embargo, puesto que el incremento no era transparente, no lo podía planear eficazmente.
Al principio del proyecto, Ana estableció un objetivo para el lanzamiento. Después del Sprint 1, evaluó el progreso con respecto al objetivo inspeccionando lo que pensaba que era un incremento utilizable. Tomó una decisión sobre lo que hacer en el Sprint 2 basándose en el progreso incremental hacia el objetivo. Si hubiera pensado que nuestro progreso era inadecuado, podría haber cancelado el proyecto.
Al final del Sprint 3, Ana creyó que se había completado 3/10 del total, lo que era claramente incorrecto.
Desgraciadamente, apenas habíamos hecho lo justo de cada incremento para mostrarlo. El trabajo pendiente hizo que los incrementos fueran inutilizables para el departamento de Ana y opacos a su inspección.
La opacidad al inspeccionar un incremento es como cubrir un termostato con un toallita fría y húmeda. El termostato no entiende bien la temperatura real de la habitación y podría encender incorrectamente la calefacción cuando en realidad debería poner el aire acondicionado.
Sin incrementos transparentes, las partes interesadas no tienen una comprensión correcta de lo que está ocurriendo realmente, y pueden que tomen incorrectamente medidas que no tienen sentido.
En resumen, sin una transparencia completa, se pierde la capacidad de los equipos de inspeccionar y adaptarse eficazmente.
Deuda técnica en Nanomedtronics AZ
La deuda técnica es el trabajo aplazado que se debe completar antes de que el software se considere terminado. La deuda técnica adopta varias formas, como un diseño deficiente, duplicación de código y características no comprobadas. En el ejemplo siguiente se muestra la causa y el impacto de la deuda técnica como trabajo sin hacer a lo largo de un proyecto.
Nanomedtronics AZ era una pequeña empresa de software que acababa de empezar. Tenían un equipo Scrum que trabajaba en una nueva versión de su producto más crítico: un software utilizado por nanorrobots para limpiar las arterias obstruidas de los pacientes con hipertensión.
Lo que la gente pensaba que sucedía
Cuando el equipo se puso en marcha, le encargaron la selección de elementos de trabajo pendiente del producto para convertirlos en algo finalizado (sin restos de trabajo pendiente, utilizable y que se pueda entregar) en un sprint de un mes. El equipo de desarrollo tenía todos los conocimientos para desarrollar totalmente los requisitos en un incremento finalizado.
Cuando el equipo de Scrum inició el primer Sprint, vieron que había 80 unidades de trabajo que debían completarse en 10 meses. En consecuencia, el equipo de desarrollo seleccionó diligentemente 8 unidades de trabajo en cada Sprint. Argumentaron que solo con hacer 8 unidades por sprint, habrían terminado en los 10 meses exigidos por la compañía.
El equipo de desarrollo mostró un incremento operativo al final de cada sprint. Lo que se percibía desde fuera era que Scrum estaba funcionando y Nanomedtronics AZ estaba en el buen camino para entregar su producto según lo previsto.
Lo que sucedió realmente
Lo que no estaba claro más allá del equipo de desarrollo era que cada incremento entregado incluía realmente ciertas implementaciones deficientes, errores no críticos, lógica repetida y código generalmente sin optimizar. Además, los incrementos no se habían probado totalmente porque el equipo de desarrollo detuvo las pruebas cuando se le presionó con los plazos en un Sprint. El equipo de desarrollo se comprometió a cumplir la programación, y reducir la calidad era a menudo la manera de hacerlo.
El equipo trabajó duro y creó el producto durante los 10 meses. El cliente estaba encantado y preparado para implementar y utilizar el software. Sin embargo, el equipo de desarrollo había acumulado 48 unidades de trabajo sin realizar, que se muestran en la ilustración siguiente como una nueva deuda técnica.
El equipo de Nanomedtronics AZ no tomó en consideración todas las actividades y el trabajo que realmente sería necesario realizar. A continuación se incluyen aspectos que el equipo no tuvo en cuenta, y no pretende ser ni mucho menos exhaustivo. Hay muchas más cosas que se podrían incluir.
Análisis
Diseño
Análisis de dependencias
Pruebas de rendimiento
Pruebas de estabilidad
Refactorización
Pruebas de respuesta inmunológica
Integración con el trabajo de cualesquiera otros equipos que estén trabajando en un producto
Pruebas de integración con el trabajo de cualquier otro equipo para que el incremento sea la totalidad de las contribuciones de todo el equipo
Notas de la versión
Internacionalización para las seis referencias culturales donde se venderá el producto
Prueba de aceptación del usuario
Pruebas de regresión
Revisiones de código
Todo el trabajo anterior se debe completar para crear un incremento completo e integrado al final del sprint. Sin embargo, la mayoría de los equipos de desarrollo no completan todo el trabajo anterior. Dejan algo “sin hacer” en cada sprint. Esto crea incrementos con diseño deficiente, código duplicado, lógica excesivamente compleja, funcionalidad o capacidades no comprobadas u otras formas de estado incompleto. Así es cómo los equipos crean la deuda técnica en el software.
Nanomedtronics AZ supo que su producto incluía todas las características necesarias para entregarlo a los clientes, pero que también incluía muchos defectos y que le faltaba el empaquetado y el acabado necesarios para comercializar el producto. El equipo de desarrollo había creado accidentalmente un trabajo pendiente de trabajo adicional que se tardaría otros 6 meses en completar, suponiendo una velocidad ya incorrecta de 8 unidades por sprint.
Una espera de 6 meses para entregar el producto no era aceptable para los directivos de la compañía, y el producto se entregó con trabajo pendiente sin hacer después de solo 3 meses. El potencial perdido no era simplemente el retraso de 3 meses en la entrega del producto, sino la lenta capacidad de agregar nuevas características, ya que el equipo de desarrollo ahora tenía que pelearse con la deuda técnica en sprints futuros.
La lección
La deuda técnica oculta el verdadero progreso y empaña la transparencia necesaria para la toma de decisiones empírica del propietario del producto y las partes interesadas. La deuda técnica se pagará, ya sea en tiempo empleado deliberadamente en corregir problemas técnicos, o en pérdidas debidas a entregas retrasadas o con mala calidad.
En la mayoría de los casos, al menos el 50 % del trabajo no realizado permanece en los productos cuando se lanzan. En consecuencia, el trabajo no realizado se institucionaliza como deuda en curso. La deuda técnica provoca rápidamente la fragilidad del producto y puede forzar en última instancia la toma de decisiones empresariales negativas, como invertir en la reescritura del software o abandonar un producto.
La deuda técnica aumenta cuando hay varios equipos
Un equipo de desarrollo debe elegir cuidadosamente solamente la cantidad de trabajo que pueda realizar en un Sprint. Con la experiencia, el equipo de desarrollo aprende el volumen de trabajo que representa. No obstante, un equipo tiene que emplear procedimientos de ingeniería modernos como la compilación automatizada y las pruebas de regresión para lograr gran parte de sus objetivos. Si estos no se emplean, el trabajo manual suele sobrecargar un equipo hacia el cuarto o el quinto Sprint.
Piense en un equipo de desarrollo de tres programadores y dos especialistas de control de calidad. Cada día los programadores protegen código en el sistema de código fuente. Se realizan pruebas, se detectan errores y se entregan al programador adecuado. Transcurre cierto tiempo desde que se protege el código hasta que se detectan y se notifican los defectos. Durante ese tiempo, los otros programadores podrían haber protegido código sobre el código defectuoso. El trabajo necesario para corregir el problema inicial es mayor ahora. Si el equipo de desarrollo tuviera una capacidad continuada de compilación y pruebas, el error se habría detectado inmediatamente. Las personas podrían haberlo investigarlo, corregirlo y continuar. Se podía haber evitado trabajo adicional y desechos.
Muchas organizaciones usan más de un equipo de Scrum para compilar software. Cuando esto sucede, el problema de deuda técnica descrito en la sección anterior aumenta considerablemente. Las posibilidades de proteger código sobre código defectuoso son mucho mayores. El costo de remediar la creciente fragilidad del software aumenta exponencialmente a medida que progresa el trabajo.
El plan de lanzamiento en A Datum Corporation
Trabajé recientemente con otra compañía a la que llamaré Datum Corporation, una empresa de software de infraestructuras. La línea de productos principal emplea a más de 800 desarrolladores, incluidos 250 programadores. La infraestructura de desarrollo era parcialmente automatizada y parcialmente manual. Las pruebas a menudo retrasaban varios días la codificación. El tiempo que transcurría desde que un programador protegía código defectuoso hasta que se detectaba y notificaba a menudo era de diez días o más.
Para minimizar la complejidad de tener tantos programadores, cada equipo de desarrollo trabajaba en su propia bifurcación de código. Los administradores de desarrollo ayudaban a organizar los requisitos del trabajo pendiente del producto para minimizar las dependencias. Si cada equipo de desarrollo combinara su código en la línea de código principal cada día, la cantidad de trabajo de revisión potencial se reduciría al mínimo.
Sin embargo, la administración creía que esto tardaría demasiado tiempo. La administración decidió combinar todas las bifurcaciones de código en la raíz cada tercer Sprint. Las pruebas de integración encontrarían cualquier defecto, que a continuación se corregiría. Habría un candidato de versión comercial al final de cada tercer mes.
Lo que la gente pensaba que sucedía
En la ilustración siguiente se muestra la programación y el ciclo de versiones planeados.
En el plan original se suponía:
9 Sprints
3 candidatos de versión comercial y después una versión completa
Una organización de desarrollo de 800 personas
Lo que sucedió realmente
Cuando esta organización llegó a la fecha de lanzamiento después de nueve sprints mensuales, el producto no estaba preparado para su lanzamiento. El sexto candidato de versión comercial tenía más de 5.000 defectos y más de 2.000 requisitos de trabajo pendiente del producto sin completar. Nos preguntábamos cómo era posible. Habíamos visto un candidato de versión comercial cada tres meses. Cuando investigamos, descubrimos que la demostración había sido desde la bifurcación de código de cada equipo de desarrollo. No se había realizado ninguna integración. No se realizado ninguna prueba de integración.
Para mantener la velocidad necesaria para cumplir la fecha de lanzamiento, los equipos de desarrollo habían aplazado cualquier trabajo de integración, con lo que estaban creando una gran cantidad de deuda técnica. El resultado fue un retraso de ocho meses con respecto a la fecha de lanzamiento programada. Las palabras “candidato de versión comercial” no tenían ningún significado.
En la ilustración siguiente se muestra el proyecto real más el tiempo necesario para la estabilización.
Los candidatos de versión comercial tenían funcionalidad parcialmente operativa de la bifurcación de código de cada equipo. Se necesitaban cinco meses de “estabilización” antes del lanzamiento. Un defecto especialmente molesto que retrasó la entrega más que otros fue “un rendimiento insuficiente”. Este problema se registró en el primer Sprint.
La lección
Los distintos equipos que trabajan en el mismo software combinan finalmente su trabajo. La integración del software para asegurarse de que funciona reduce el riesgo de las integraciones y debe realizarse con frecuencia.
Es tentador esperar a combinar el trabajo de varios equipos, ya que permite retrasar el costo de la combinación. Sin embargo, este costo final del retraso está relacionado con el número de equipos participantes y el número de bifurcaciones que se deben integrar.
Técnicas a gran escala para finalizar tareas
Es difícil llegar a un estado “listo” en varios equipos. Las complejidades implicadas son numerosas. Existen dependencias entre los equipos y entre las bifurcaciones de código. Aunque esta complejidad de escala tenga un costo, es factible y proporciona un valor enorme cuando los equipos sincronizados se coordinan en su trabajo.
Hay varias técnicas que considero que resultan útiles cuando varios equipos trabajan juntos.
Scrum de Scrums
Cuando muchos equipos de Scrum trabajan en el mismo proyecto, necesitan una técnica para coordinar su trabajo. He recomendado un “Scrum de Scrums". Se trata de un evento diario que tiene lugar inmediatamente después del Scrum diario de cada equipo. A él asistirá personal técnico de cada equipo. El representante de cada equipo describe en lo que ha trabajado su equipo. Después describe en qué piensan trabajar el día siguiente. Según esta información, los representantes intentan identificar cualquier repetición del trabajo necesaria, las dependencias siguientes y cualquier trabajo que se deba volver a programar.
El Scrum de Scrums ha sido útil para muchas organizaciones. Sin embargo, no es suficiente. Puede que las dependencias y la repetición del trabajo no se identifiquen correctamente, ya que los problemas se prevén en lugar de conocerse. Las dependencias imprevistas fueron la causa de repeticiones del trabajo y pruebas no superadas. Algunos equipos dedican más del 50 % de cada Sprint a trabajar y repetir el trabajo en las dependencias.
Integración continua
La programación extrema (XP, Extreme Programming) requiere la integración y pruebas de integración continuadas del trabajo de un equipo. ¿Por qué no extender esto a todos los equipos? Tanto si hay dos equipos como si hay cincuenta, los equipos están obligados a producir un incremento integrado con integración comprobada al final de cada sprint. Para ello, los equipos tienen que integrar su trabajo con frecuencia. Puesto que cualquier trabajo no integrado puede contener dependencias no resueltas, la integración continua es la mejor solución.
La integración continua de todo el trabajo es similar a las técnicas de producción eficiente. En las líneas de producción eficiente, se emplean muchas técnicas para evaluar la calidad de un producto durante todo el proceso de producción. Cuando se producen desviaciones o problemas de calidad, se detiene la línea de producción. La integración y las pruebas de integración continuadas proporcionan las mismas técnicas para el desarrollo de productos de software.
Aunque sea difícil, recomiendo que cada equipo y miembro del equipo deje de codificar si se produce un error en una compilación o prueba continuadas. Cualquier trabajo posterior se creará potencialmente sobre errores, produciendo un efecto dominó de errores. Si se usa la integración continua, los equipos trabajan en estrecha colaboración evitar errores de integración. Mejoran sus hábitos de trabajo, se reducen los residuos y mejora la calidad.
La mayoría de las organizaciones que adoptan Scrum no empiezan a compilar un incremento finalizado con todos los conocimientos y herramientas de ingeniería. Se debe iniciar y perseguir un programa riguroso para lograr incrementos finalizados. Los grupos de menos de cincuenta personas pueden alcanzar rápidamente un estado en el que se complete un incremento finalizado dentro del Sprint. Las organizaciones de más de quinientos desarrolladores suelen necesitar varios años para llegar a ese punto.
Los incrementos no finalizados crean residuos e impiden que los equipos alcancen una verdadera agilidad. El costo real del trabajo no realizado es mucho mayor que la falta de una característica o una función en el incremento. El costo incluye los residuos de la replaneación y la repetición del trabajo necesarias cuando un incremento no está realmente terminado, así como los costos de una menor previsibilidad y un riesgo mayor.
Muchas organizaciones desean las ventajas de la agilidad y emplean Scrum para obtenerlas. La entrega de un incremento finalizado es crucial para el éxito de Agile Software Development. Los equipos deben comenzar con una definición de finalizado que tenga sentido para ellos y ampliar deliberadamente la definición con el tiempo. Solo entonces adquirirán una auténtica agilidad.
Vea también
Conceptos
Colaboración (Profundizar más) [redirigido]
Repasar y estimar el trabajo pendiente