Soy parte de un grupo de desarrollo con 5 equipos, un total de aproximadamente 40 desarrolladores. Estamos siguiendo la metodología Scrum, con sprints de 3 semanas. Tenemos una configuración de integración continua (Jenkins), con una tubería de construcción que demora varias horas (debido a extensas pruebas automatizadas). Básicamente, el proceso de desarrollo funciona bien.
Sin embargo, observamos que después de unos días en un nuevo sprint, nuestra construcción a menudo se vuelve inestable y permanece inestable hasta que el sprint finaliza "commit stop". El efecto adverso de esto es que los pasos de compilación en el futuro, especialmente las pruebas de IU / Web no se ejecutan durante varios días (porque solo se activan en una compilación 'verde'). En consecuencia, los errores recientemente introducidos a menudo solo se detectan muy tarde en el sprint.
- Cada confirmación se verifica contra un conjunto básico de pruebas. Una vez verificado, el cambio se envía al maestro después de una revisión de código (Gerrit)
- Las pruebas unitarias básicas se ejecutan cada 30 minutos, duración inferior a 10 minutos
- Las pruebas de integración se ejecutan cada 2 h, duración 1 h
- UI- / Webtests se ejecutan en pruebas de integración exitosas, duración varias horas
Dependiendo de quién sea responsable de la estabilidad de la construcción durante el sprint (esa responsabilidad se transfiere por sprint), puede haber "paradas de compromiso" intermedias y ad-hoc para que la construcción vuelva a ser estable.
Entonces, queremos:
- Nuestros equipos de desarrollo para desarrollar y cometer cambios durante un sprint sin obstáculos
- Nuestro proceso de compilación se abandonará si falla un paso de compilación, ya que los resultados de compilación posteriores tienen poco significado
- Nuestro proceso de construcción para brindar a los desarrolladores comentarios de calidad de manera oportuna
Dado (2), los puntos (1) y (3) parecen contradecirse entre sí. ¿Alguien tiene una buena práctica de cómo lidiar con esto?
( Actualmente estamos aflojando el punto (2), y estamos permitiendo la continuación de la construcción incluso en los pasos de construcción fallidos. Todavía no tengo comentarios sobre cómo eso influye en nuestra calidad )
Gracias simon
fuente
several hours
, ese es el verdadero problema. significa que la solución combinada es demasiado grande y demasiado amplia. Debe buscar componentes de la solución y luego tener pequeños fragmentos de código como paquetes (disponibles de una forma u otra en todos los idiomas principales en todas las plataformas). Por lo tanto, cualquier cambio iría solo a los componentes y se detectará mucho más rápido. La compilación completa esencialmente solo juntará componentes ya combinados, y también será más rápido. Entonces, posiblemente solo ejecute algunas pruebas para asegurarse de que se hayan resuelto los componentes correctos.Respuestas:
Primero, un par de principios básicos: - Los cambios importantes siempre deben realizarse en una rama de características en su VCS - Las ramas de características deben pasar todas las pruebas antes de fusionarse en el tronco. Agregado : los commits siempre deben compilarse : un build roto requiere una acción inmediata del committer y / o del resto del equipo. - Una prueba fallida solo debe abortar las pruebas restantes si es una prueba crítica .
Si usted, como equipo, sigue estas prácticas y las aplica, por ejemplo: "nombre y vergüenza" cuando se rompe la compilación, entonces debería ser bueno ya que cualquier confirmación que pueda romper la compilación estará en una rama de características. Otros compromisos que rompen la compilación deberán abordarse de inmediato y luego obtendrá los resultados de las pruebas posteriores.
También puede agregar una prueba automática de la última compilación "exitosa" (no necesariamente una que pase las pruebas de integración), para las pruebas UI / Web como una ejecución nocturna que informa a primera hora de la mañana.
fuente
No tiene nada que ver con Scrum. Su construcción debe ser continuamente estable, independientemente.
Nadie debería registrar nada a menos que hayan realizado una compilación local y ejecuten las pruebas unitarias localmente (y ambas pasaron, por supuesto). Su proceso local de compilación y prueba debe ser sensible a las modificaciones y puede omitir las pruebas de código que no ha cambiado.
Cualquier persona que presente algo que haga que falle la construcción o que falle una prueba unitaria debe ser avergonzado públicamente . Si la compilación se rompe, debe repararse de inmediato.
fuente
Su problema parece ser que las pruebas tardan demasiado en ejecutarse. Afortunadamente, la ley de Moore nos ha proporcionado una solución a ese problema. Hoy en día, las CPU de servidor de gama alta pueden tener fácilmente más de 10 núcleos (y más de 10 HyperThreads). Puede haber múltiples CPU de este tipo en una sola computadora.
Si tuviera pruebas que llevaran tanto tiempo, resolvería el problema con más hardware. Compraría un servidor de alta gama y luego paralelizaría las pruebas para que las pruebas aprovechen al máximo todos los núcleos de CPU. Si sus pruebas son de un solo subproceso, aprovechar 10 núcleos y 10 HyperThreds probablemente hace que las pruebas se ejecuten 15 veces más rápido. Por supuesto, esto significa que también usan 15 veces la memoria, por lo que la computadora debe tener suficiente RAM.
Entonces, las varias horas se convertirán en 10-30 minutos.
No dijo cuánto tiempo lleva la compilación, pero las herramientas de compilación estándar como make permiten paralelizar también la compilación. Si paraleliza sus pruebas unitarias y la computadora típica del desarrollador tiene 4 núcleos y 4 HyperThreads, los menos de 10 minutos de pruebas unitarias se convertirán en menos de 2 minutos. Entonces, ¿tal vez podría hacer cumplir una política de que todos deberían ejecutar las pruebas unitarias antes de comprometerse?
Sobre la falla de la prueba que detiene las pruebas adicionales: ¡no haga eso en el servidor de compilación! Desea tanta información como sea posible sobre la falla, y las pruebas adicionales pueden revelar algo importante. Por supuesto, si la construcción en sí falla, no puede ejecutar pruebas unitarias. Si el desarrollador ejecuta pruebas unitarias en su propia máquina, es posible que desee abortar en el primer fallo.
No veo ninguna conexión entre Scrum y tus problemas. Los problemas realmente podrían ocurrir con cualquier proceso de desarrollo.
fuente
¿No es posible tener más instalaciones de Jenkins y que los desarrolladores verifiquen una instancia de Jenkins separada?
Creo que la mejor solución aquí es hacer que el código pase todas las pruebas antes de que sea revisado en la rama maestra y compilado / probado por la instancia principal de Jenkins. No permita que la gente registre el código que rompe la compilación.
Verifico mi código en la rama de desarrollo, veo si pasa las pruebas y creo una solicitud de extracción. Pero obviamente podría hacer que Jenkins extraiga una rama de características y pruebe esa.
fuente
El punto (2) parece ser el punto más doloroso, así que me enfocaré en eso.
Tal vez sea hora de dividir el proyecto en múltiples módulos.
https://en.wikipedia.org/wiki/Dependency_inversion_principle
Si un módulo no puede compilarse, la compilación para otros módulos podrá continuar, siempre y cuando esos otros módulos puedan depender de una interfaz, y el código que conforma esa interfaz se compiló con éxito.
Esto le dará retroalimentación sobre qué otras fallas de compilación podrían ocurrir, de modo que tenga tiempo para reparar más de un módulo roto antes de que ocurra la próxima compilación.
En general, los principios SOLID están concebidos para tratar con bibliotecas y generar problemas. En otras palabras, este conjunto de principios está concebido para resolver el tipo exacto de problemas que enfrenta.
Como nota al margen (vea la respuesta de juhist), no puede hacer que la compilación se ejecute más rápido (por paralelización) si no divide la compilación en módulos separados.
fuente
Creo que a su equipo le falta uno de los principios clave de scrum: el software hecho y funcionando. Un PBI no debe marcarse como hecho hasta que pase la definición de hecho que su equipo ha establecido. La definición de Done es diferente para cada equipo, pero probablemente incluiría cosas como:
Entonces, esencialmente, lo que está sucediendo es que su equipo está marcando cosas que de hecho no se han hecho. Eso es un problema en sí mismo.
Aparte de eso, se reduce a la gestión adecuada del control de versiones. Si está utilizando Git, todo el trabajo se realiza en el repositorio local del desarrollador y no deberían empujar nada al control remoto a menos que esté "hecho" y sea potencialmente liberable. El trabajo incompleto nunca debe ser empujado a su repositorio principal. Si el desarrollador necesita trabajar en una rama de características más longeva y quiere pasar al control remoto para asegurarse de que no pierdan su trabajo, entonces debería estar trabajando en una bifurcación, y luego fusionaría esa bifurcación en main cuando el la función está "terminada" y es potencialmente liberable, no antes.
Para TFVC, es un poco más complicado porque todo sucede en "remoto". Eso significa que, por lo tanto, los desarrolladores siempre deberían estar trabajando fuera de las ramas, a menos que sea una solución rápida. Sin embargo, las mismas reglas se aplican aquí que con Git: el software incompleto no se compromete. Período. En el control de versión administrado adecuadamente, "main" siempre debe ser liberable. Si se ha realizado una confirmación que borks "main", entonces no lo estás haciendo bien.
fuente