¿Cómo implementar pruebas unitarias con un pequeño equipo de Scrum sin gastar la mitad de las historias de pruebas unitarias de Sprint?

Somos un equipo muy pequeño (1 desarrollador front-end, 1 desarrollador back-end/arquitecto de soluciones, 1 PM/UX) trabajando en Scrum con Sprints de 2 semanas.

Hasta ahora, trabajábamos principalmente en proyectos de prototipos que no requerían ninguna prueba, pero uno de nuestros MVP está cobrando fuerza y ​​comenzamos a implementar pruebas unitarias como parte de nuestra Definición de Listo para nuestras historias de usuario.

Sin embargo, ahora tenemos un problema en el que las pruebas toman tanto tiempo, si no más, que el tiempo de desarrollo/codificación por dos razones principales:

  1. Mis desarrolladores no están acostumbrados al marco de pruebas unitarias y todavía están aprendiendo.
  2. Solo hay dos de ellos, cada uno con su propia especialidad (front-end y back-end), por lo que tienen que hacer tanto la codificación como las pruebas unitarias para su versión de la historia.

Esto nos ha llevado a fallar los sprints porque las pruebas unitarias terminan tomando tanto tiempo que las historias no se terminan antes del final del Sprint. Esto se vuelve problemático para las historias medianas que no se pueden dividir en historias más pequeñas porque cuando agregamos la estimación de pruebas unitarias, estas historias terminan siendo tan grandes que una sola historia termina ocupando casi la mitad de la capacidad de Sprint.

¿Tendría algún consejo sobre cómo mejorar este proceso para que las pruebas sean más ágiles o más rápidas? Nuestro front-end usa React y actualmente usa JEST para pruebas unitarias, y nuestro back-end está construido con .NET en AWS pero aún no ha comenzado a implementar pruebas unitarias.

Es importante identificar el nivel de calidad apropiado para su producto. Si tiene un alto nivel de calidad necesario para su producto, entonces tal vez dedicar la mitad del sprint a la calidad, incluidas las pruebas unitarias, sea la cantidad adecuada de tiempo.
TANSTAAFL . Si su equipo o su organización siente que las pruebas son un beneficio neto, que casi siempre lo es, entonces también debería estar dispuesto a tratar el esfuerzo de las pruebas como un trabajo por el que el proyecto está dispuesto a pagar. Doy una respuesta más larga a continuación, pero siento que el problema X/Y aquí es probablemente una mentalidad de "almuerzo gratis" dentro de su organización. Al menos es algo que usted y su equipo deben considerar seriamente al decidir si se trata realmente de un problema de proceso o cultural.

Respuestas (3)

Mis desarrolladores no están acostumbrados al marco de pruebas unitarias y todavía están aprendiendo

Esto mejorará con el tiempo a medida que adquieran más experiencia.

Solo hay 2 de ellos y cada uno con su especialidad (Front-end y back-end), por lo que tienen que hacer tanto la codificación como las pruebas unitarias para su versión de la historia.

Eso es absolutamente normal. ¿Quién más escribiría pruebas? Incluso si tuviera a alguien más para escribir pruebas, necesitaría contratarlos y pagarles probablemente al mismo precio que los desarrolladores. Las pruebas no aparecen mágicamente.

Esto nos ha llevado a fallar en los sprints porque las pruebas unitarias tardan tanto que las historias no se terminan antes del final del sprint.

Sí. Sus estimaciones están completamente equivocadas, porque hasta ahora no ha entregado un software que funcione y esté listo para la producción , ha entregado prototipos probados a medias. Y eso está bien para los prototipos, eso es lo que son: no están listos para la producción. Ese es el objetivo de un prototipo, poner algo en marcha, no perderse en los detalles, mostrar que se puede hacer un concepto. Pero ahora necesita entregar software de calidad de producción. Y eso lleva más tiempo que los prototipos. Es poco lo que puedes hacer. Mejore sus estimaciones para tener eso en cuenta para no fallar los sprints.

Pero si su equipo no está produciendo lo suficiente con la calidad que necesita, no hay solución milagrosa. Necesitas más gente. Contrate a otro desarrollador frontend y backend. Producir software listo para producción en lugar de prototipos es fácilmente el doble de trabajo.


Aunque no lo hayas preguntado: contratar a más personas te da la oportunidad de mejorar tus procesos. Si tiene un desarrollador frontend y un desarrollador backend, cada uno con conocimiento de su dominio, no hay casi ninguna opción para el trabajo en equipo. Quiero decir, claro, el backend y el frontend tienen que hablar entre sí, pero ese no es el trabajo en equipo del que estoy hablando. No hay nadie para ayudar con el backend si se atascan. No hay nadie para preguntar si la interfaz se atasca en un problema. Ahora mismo no tienes un equipo, tienes una cadena de montaje. Necesitas más personas con la misma especialidad para que puedan ayudarse entre sí y trabajar en equipo. Debe poder compensar si uno de ellos tiene una semana de vacaciones o tiene que llamar por enfermedad. Necesita llevar su equipo al tamaño de producción. Como primer paso hacia un mínimo, equipo de barebones, puede contratar a un desarrollador de pila completa que pueda ayudar en cualquier parte o en el proyecto. Mejor sería uno más de cada rol. Scrum no funciona muy bien con un equipo de dos personas.

Oye, estoy completamente de acuerdo con todo lo que dijiste y he estado presionando para que se una al menos un desarrollador de pila completa, pero lamentablemente el presupuesto no lo permite en este momento. ¡Gracias por las ideas!

TL;RD

El problema real aquí es que su organización está enmarcando el costo de las pruebas como gastos generales no deseados, en lugar de como un costo esperado y necesario de hacer negocios para el desarrollo, mantenimiento y soporte de productos. Enfócate en arreglar eso.

Análisis y recomendaciones para la reformulación

¿Tendría algún consejo sobre cómo mejorar este proceso para que las pruebas sean más ágiles o más rápidas?

TDD y BDD no son botones para "ir más rápido". Si bien los equipos a menudo se vuelven un poco más eficientes con las pruebas a lo largo del tiempo, los objetivos de las pruebas están más alineados con:

  1. Reducción de la deuda técnica.
  2. Eliminando ciertas clases de errores comunes o predecibles.
  3. Creación de documentación ejecutable.
  4. Hacer que el código sea más flexible a través del diseño emergente y pruebas de regresión integrales.
  5. Facilitar las pruebas, el soporte y el mantenimiento al diseñar el código para probar y depurar desde el principio.

Si bien estas cosas a menudo facilitan la adición de nuevas funciones o la búsqueda/corrección de errores en el futuro, por lo general no hacen que el desarrollo actual sea más rápido. De hecho, la refactorización (o peor aún, el rediseño) del código para la capacidad de prueba inevitablemente agrega una carga a corto plazo y una sobrecarga a largo plazo. Además, poner a todo el mundo al día con las nuevas herramientas y técnicas requiere tiempo y esfuerzo y, por definición, consumirá la capacidad del equipo.

Hay varias cosas a tener en cuenta aquí:

  • Pagará los costos de las pruebas de cualquier manera, ya sea como gastos generales durante el desarrollo o como problemas de mantenimiento en el futuro. También podría pagarlos por adelantado, ya que estos costos son casi inevitables.
  • Independientemente de si paga los costos en TDD/BDD o deja que se conviertan en deuda técnica, todos los costos (incluido el costo de las pruebas) deben imputarse visiblemente al proyecto. En Scrum, haces esto agregando TDD/BDD a la Definición de Terminado y integrándolo en las estimaciones de tu Lista de Producto.

Tenga en cuenta que en muchos marcos ágiles, también es perfectamente aceptable agregar elementos de la pasarela arquitectónica directamente a la cartera de productos. Dado que está en el proceso de adoptar un nuevo enfoque de prueba, el propietario del producto puede y debe priorizar el trabajo relacionado con las herramientas, la capacitación y otros gastos generales que de otro modo no se pueden atribuir a una característica típica en la lista de pedidos del producto. . Esto garantiza que este trabajo necesario se trate como trabajo planificado y no como gastos generales inesperados o no deseados. Cuando se utiliza este enfoque, las actividades de prueba y pasarela arquitectónica se tratan adecuadamente como un costo de hacer negocios.

¡Gracias, Todd! Estoy de acuerdo con lo que dices y estoy considerando TDD. Mencionas algo muy interesante sobre la pasarela de arquitectura y antes, sobre la refactorización. Cosas que no se pueden atribuir a una característica típica/historia de usuario. Dado que hemos "avanzado el arma" del prototipo al producto, hay MUCHA reconstrucción que debería suceder para que sea más estable/preparado para el futuro/escalable. ¿Cree que valdría la pena simplemente "pausar" el proyecto actual para reconstruirlo como un proyecto de calidad de producción, impulsado por TDD? Tal vez esta debería ser una pregunta completamente nueva: D
No, no pausas el proyecto. Eso sigue siendo un antipatrón porque estaría tratando el proceso y la pasarela arquitectónica como algo separado del resto del esfuerzo de desarrollo. Dado que los comentarios no son para una discusión extensa, si todavía tiene preguntas sobre esto, abra una nueva pregunta que haga referencia a las preguntas, respuestas o comentarios relevantes que le plantean más preguntas.
Ok, gracias Todd!

Para hacer eco de lo que los otros han insinuado:

La prueba no es un mal necesario.

La prueba es un componente crucial de la entrega de software de calidad (o al menos funcional).

Tenga en cuenta que solo tiene una oportunidad de causar una primera impresión y la entrega de software con errores destruye su reputación.

Entonces, para responder a su pregunta: debe presupuestar más tiempo para las pruebas, e incluso más tiempo para corregir los errores que se descubren una vez que comienzan las pruebas.

Para "mejorar este proceso para que las pruebas sean más ágiles/más rápidas", haga que las pruebas sean el enfoque, no un castigo agregado en la programación posterior.

Entonces, ¿cómo haces eso?

Mencionas que tus historias son grandes y no se pueden reducir. Posiblemente necesite la ayuda de un Gerente de Proyecto Técnico experimentado, para ayudar a explicar a su equipo cómo reducir las historias .

Grandes historias = grandes fragmentos de código = más posibilidades de errores = más difíciles de corregir.

Un (ex)programador/PjM experimentado le mostrará a su equipo cómo reducir sus historias en fragmentos (o bytes) manejables.

Por ejemplo , se utilizarían técnicas como el stubing ; a medida que avanza, convierte cada trozo en código real. Pero mientras tanto, tiene muchas historias pequeñas , una por función, que se pueden codificar y probar por unidad, e incluso revisar por pares, ya que tienen un tamaño manejable con una sola función.

Y no tomará más tiempo, probablemente reducirá la línea de tiempo a medida que se dedique más tiempo a planificar el código antes de escribirlo.

¡Gracias, Danny! No estoy seguro de entender cómo puede tener "una historia por función" mientras mantiene las historias centradas en el usuario y no centradas en el desarrollador. Me gustaría evitar volver a caer en el tipo de historias "como desarrollador que necesito..." que conducen a trabajar en las características que los desarrolladores quieren en lugar de lo que quieren los usuarios. ¿Serías capaz de dar ejemplos?
@Paz, no es fácil proporcionar ejemplos sin saber lo que está desarrollando, pero para su historia de registro podría desglosarlo en "iniciar sesión" sin verificar que el usuario exista (el código auxiliar devuelve el "usuario" fantasma necesario), luego "crear nuevo usuario", luego "el usuario ya existe", luego "enviar correo electrónico de verificación", luego "contraseña perdida", luego "cambiar contraseña", luego "usuario/contraseña incorrectos": son 7 historias en lugar de una gran historia de "registro".