Estrategias de Testing en Equipos Scrum

Estrategias de Testing en Equipos Scrum

¿Terminan tus Sprints con todo el trabajo planificado completamente testeado? ¿Es el testing una tarea más del trabajo o una etapa del proceso? ¿Hay una persona dedicada a Testing o todo el equipo toma la tarea?

En este post voy a contar las formas en la que distintos equipos resuelven la problemática de desarrollo & testing en el proceso iterativo e incremental, siguiendo un orden desde los casos menos ágiles hasta los más ágiles. Para terminar, un listado de buenas prácticas de testing ágil.




Gestión Tradicional

Para situar un poco de contexto, describo como se gestiona el testing en la gestión de tradicional de proyectos de software. Es muy común encontrar una fuerte etapa de programación de un módulo (o proyecto completo). Cuando se completa el desarrollo se pasa el código al equipo de testing para verificación de calidad, quienes suelen tener un período más acotado para su tarea, luego de la etapa de testing, todos los defectos encontrados se pasan a desarrollo para bug fixing o estabilización del proyecto.





Son problemas comunes: 

- Si el desarrollo se demora y no se puede mover la fecha final de entrega planificada (deadline), se reduce el tiempo disponible para testing, generando un producto de menor calidad.

- Demoras por tiempos muertos: cuando el equipo de desarrollo termina su tarea y testing no comienza de inmediato. El equipo de desarrollo también puede demorar en re-tomar el proyecto para estabilización. (En ambos casos por estar trabajando en otro proyecto).

- Wishful Thinking: cuando testing toma el proyecto encuentra muchos más bugs de los que todos estaban esperando (o deseando) encontrar.

- El equipo de desarrollo no se siente responsable por el testing.



¿Y en Scrum?


En equipos Scrum se recomienda que los miembros del equipo sean cross-funcionales. Es decir que puedan tomar cualquier tarea por igual, incluso el testing. Si bien puede haber especialistas en testing, todo el equipo es responsable de la tarea y de la calidad. El mismo criterio se aplica también a las tareas relacionadas a otros perfiles y tecnologías (Backend, Frontend, etc.).

Por su parte, el trabajo del especialista en testing (y de todo el equipo Scrum) está mayormente orientado a prevenir errores. Para esto trabaja desde el inicio en la correcta especificación de los requerimientos, criterios de aceptación y casos de prueba. Las buenas prácticas recomiendan el uso de Acceptance Test Driven Development (ATTD) para la automatización de las pruebas de aceptación.

Programación de a Pares (Pair Programming)

Los Developers también adoptan las buenas prácticas para prevenir errores: Test-Driven Development (TDD) y Pair Programming donde el desarrollo tiene dos pares de ojos en tiempo real y testing automatizado. Esto reduce altamente la producción de errores e incrementa la calidad del código.



Cross-Testing

Si un programador hace el testing de su propio trabajo, es muy probable que use la misma lógica para que usó al desarrollarlo, con lo cual muchos errores pueden pasar inadvertidos. Es más efectivo que otra persona pruebe el trabajo. Para esto existe el concepto de Cross-Testing, donde un developer prueba el trabajo de otro.




Pero este post no es sobre teoría


En la práctica la mayorría de las empresas tienen bien diferenciado el rol de developer y el rol de tester. Es muy común que los testers no sepan programar y que los developers no estén dispuestos a hacer el trabajo de testing. Son pocos los casos donde encuentro buena disposición para hacer ambas cosas.

Estas son las distintas estrategias que encontré en equipos de desarrollo de software abordando el problema:


1) Ciclo de Dos Sprints (estilo Cascada)

Esta forma de trabajo es desaconsejada, 
pero la menciono porque es una práctica que se puede encontrar. 

Durante el primer Sprint el equipo de desarrollo está programando la funcionalidad mientras el equipo de testing está escribiendo el plan de testing -casos de prueba, test cases-.

Durante el segundo Sprint, el equipo de desarrollo está programando las funcionalidades del nuevo Sprint mientras el equipo de testing está testeando lo que fue programado en el Sprint anterior. Al mismo tiempo debe preparar los test cases para el trabajo del Sprint siguiente.

El equipo de desarrollo, además de programar nuevas funcionalidades tiene que arreglar los defectos que encuentra el equipo de testing del trabajo del Sprint anterior.



Este método es anti-Scrum, ya que el Sprint no termina con software terminado (ni potencialmente entregable). De hecho toma dos Sprints completar un solo Sprint Backlog. (se duplica el Cycle Time).

Es más común encontrar esta estrategia en equipos donde testing es un departamento separado, es decir, no es parte del mismo equipo (También, una práctica no recomendada)

El diseño de casos de prueba es una forma de completar la especificación del requerimiento y se terminan definiendo detalles al mismo tiempo (o incluso a posteriori) de la programación. Esto genera re-trabajo.

2) Un Sprint (Estilo Cascada)

Siendo más estrictos y con el objetivo de tener software funcionando en cada iteración, el equipo de desarrollo intenta comprimir el enfoque anterior dentro de los límites de un Sprint: primero programa la funcionalidad y luego testing la verifique todo dentro del mismo Sprint.


Como consecuencia, los primeros días el tester no está aplicado a la tarea de Testing. Hasta tanto no esté programada la primera funcionalidad.

También implica que los desarrolladores planifiquen menos trabajo para el Sprint, ya que deben finalizar su trabajo de programación días antes para dar tiempo a testing a verificar y terminar dentro del Sprint. Por lo tanto, los últimos días los developers no pueden desarrollar funcionalidad del Sprint backlog.

El equipo también puede estar adelantando trabajo del Sprint siguiente. Programando funcionalidad  que entraría en el siguiente Sprint.




Esto deja tiempo ocioso para ambos roles

Por supuesto que es muy fácil encontrar tareas en las que mantenerse ocupados. Tareas que son útiles y agregan valor, como hacer test cases, automatización, investigación, bug fixing, refactors, etc. Pero este tiempo está dado por la limitación anterior y no como un objetivo en sí mismo. Con lo cual, si lo más valioso fuese desarrollar funcionalidades, el equipo no lo podría hacer.

Es una práctica superior al caso anterior, pero todavía poco ágil.


3) El enfoque ágil

Una forma de agilizar el proceso consiste en tomar porciones de funcionalidades más pequeñas. Así se minimizan los tiempos no productivos. Para lo cual se hace un trabajo previo de refinamiento y slicing.

Esto no soluciona por completo el problema: Hay funcionalidades que no son tan pequeñas. En un Sprint de dos semanas, es my factible que los tres primeros días no haya ninguna funcionalidad lista para testear. De igual manera los desarrolladores no puedan continuar desarrollando funcionalidad de producto los últimos dos días para que Testing pueda completar sus tareas a tiempo y solucionar los defectos encontrados.


Carry Over

Para optimizar el tiempo de ambos roles, el equipo intenta maximizar la cantidad de trabajo comprometido en el Sprint y esperar poder terminar todo dentro del mismo (Wishful Thinking)

Si no se llega a completar un requerimiento este "pasa al siguiente Sprint" ("Carry Over" o "Roll Over"). Como "solo queda el testing" los equipos pueden re-estimar el esfuerzo restante.

Esta práctica impacta en el resultado del Sprint. No se completa al 100%, sino que quede un margen de Carry Over al siguiente Sprint.

Cuando Testing encuentra más bugs de los esperados, pone el riesgo el Sprint siguiente.



4) Automatización de Casos de Prueba (La forma recomendada)

El problema se resuelve con un robusto enfoque en automatización de casos de prueba. Mientras el developer desarrolla la funcionalidad el tester desarrolla casos de prueba automatizados que verifican que la funcionalidad haga lo que se espera. 

La ejecución del caso de prueba es muy rápida y se puede ejecutar repetidas veces sin consumir tiempo de las personas, además de que puede ser ejecutada por el Developer o ser ejecutada automáticamente al momento del commit de código. 


Aquí es donde las prácticas de ATTD, TDD y PP se ven más aplicadas, como así también el sentido de responsabilidad compartida por la calidad y por todas las partes del proceso de desarrollo.



Consideraciones:

- Requiere de un equipo maduro.

- Puede ser complejo, dependiendo de la tecnología.

- Los test automatizados no reemplazan por completo el test manual.

Otros Desafíos

- Además de los desafíos de coordinación que planteo, es frecuente también encontrar el desafío de balancear correctamente la carga de trabajo entre Developers y Testers. Algunas funcionalidades son fáciles de desarrollar pero trabajosas de Testear y viceversa. El testing puede generar cuellos de botella en el proceso.



Buenas Prácticas

En la cultura de un equipo Scrum, todo el equipo es responsable por la calidad del producto, no es una responsabilidad que recae en el Tester. 

Los Testers tienen que ser parte del equipo de desarrollo, por lo tanto deben trabajar juntos en el día a día, estar fisicamente ubicados en el mismo espacio y participar en los eventos de Scrum (Refinamiento, Planning, Daily, Review y Retrospectiva)

En las metodologías ágiles el trabajo del Tester tiene un enfoque más preventivo que reactivo. Participan en la buena especificación y diseño de los requerimientos para evitar que ciertos defectos ocurran. Para esto deben trabajar de cerca con el Product Owners para la elaboración de los Criterios de Aceptación y considerar todos los casos alternativos posibles (situaciones de error, etc). Una tarea más relacionada con el análisis funcional. También deben trabajar de cerca con los Developers durante el desarrollo de los requerimientos.

Si el tester es un cuello de botella para el desarrollo, se debe optimizar su tiempo lo más posible: evitar recargar al Tester con tareas que no están directamente relacionadas con Testing (ej. reportes de bugs, cargas de horas, revisar quejas de usuarios, sacar estadísticas, etc). Otras formas de optimizar el tiempo de testing consiste en mejorar el reporte de bugs a Testing para recolectar datos relevantes antes de invertir tiempo en intentar reproducir bugs con poca información.

Un último punto a considerar es que el equipo tiene que tener como objetivo que los Testers no encuentren bugs. Si el equipo incrementa su calidad de desarrollo de manera de minimizar la cantidad de bugs detectados por Testing el proceso se hace más eficiente. Se reduce el re-trabajo y se optimiza el cuello de botella que suele representar el Testing. 

Conclusión

Llevar la teoría a la práctica resulta desafiante en este aspecto. Debemos buscar la estrategia más conveniente para la situación actual, adoptar buenas prácticas y utilizar el principio de Inspect & Adapt para ir mejorando continuamente el proceso y la efectividad del resultados.

Invertir siempre en el aprendizaje y apoyarse en la tecnología son siempre buenas opciones!

¿Tu Opinión?

Si tenés otras experiencias y querés compartir tu opinión te invito a usar el cuadro de comentarios!



Entradas populares de este blog

Visual User Story Mapping Aplicado

Historia de las Metodologías Ágiles en Contexto

Los Bugs en Scrum