Tenemos tres conjuntos de suites de prueba:
- Una suite "pequeña", que tarda solo un par de horas en ejecutarse
- Una suite "mediana" que toma varias horas, generalmente se ejecuta todas las noches (todas las noches)
- Una suite "grande" que tarda una semana o más en ejecutarse
También tenemos un conjunto de conjuntos de pruebas más cortos, pero no me estoy centrando en ellos aquí.
La metodología actual es ejecutar el conjunto pequeño antes de cada confirmación en el enlace troncal. Luego, la suite mediana funciona todas las noches, y si por la mañana resultó que falló, tratamos de aislar cuál de las confirmaciones de ayer fue la culpable, revertir esa confirmación y volver a intentar las pruebas. Se realiza un proceso similar, solo en una frecuencia semanal en lugar de nocturna, para la suite grande.
Desafortunadamente, la suite mediana falla con bastante frecuencia. Eso significa que el tronco a menudo es inestable, lo cual es extremadamente molesto cuando desea realizar modificaciones y probarlas. Es molesto porque cuando salgo del baúl, no puedo saber con certeza si es estable, y si una prueba falla, no puedo saber con certeza si es mi culpa o no.
Mi pregunta es, ¿hay alguna metodología conocida para manejar este tipo de situaciones de una manera que deje el tronco siempre en la mejor forma? por ejemplo, "comprometerse en una rama especial de precompromiso que luego actualizará periódicamente el tronco cada vez que pase la noche"
¿Importa si es un sistema de control de fuente centralizado como SVN o uno distribuido como git?
Por cierto, soy un desarrollador junior con una capacidad limitada para cambiar las cosas, solo estoy tratando de entender si hay una manera de manejar este dolor que estoy experimentando.
Respuestas:
La única forma de corregir la causa raíz de la inestabilidad es desacoplar el código para que los cambios estén más aislados, como han sugerido otras respuestas.
Sin embargo, como desarrollador individual, si desea una construcción más estable para que trabaje personalmente, es relativamente fácil de resolver. En lugar de trabajar fuera de la punta, solo extrae la última compilación que pasó el conjunto de pruebas durante la noche en su árbol de trabajo. Si puede crear ramas de características para cada cambio, bifurquese de la última versión estable.
Sí, su árbol estará retrasado unos días, pero la mayoría de las veces eso no importa. Haga su trabajo contra la compilación estable, para que sepa que sus cambios son los que rompieron cualquier prueba, luego, antes de registrarse, actualice a la última versión y realice su integración normal. Luego, después de registrarse, vuelva a la última versión estable.
Todavía tiene que hacer el trabajo de integración desordenado, pero lo que me gusta de este método es que aísla el trabajo de integración en un momento más conveniente para mí y me da una base de código estable para el desarrollo cuando no es conveniente. Tengo una idea mucho mejor cuando son mis cambios los que probablemente rompieron la compilación frente a los de otra persona.
fuente
Sé que está tratando de evitar esto, pero la idea real aquí es darse cuenta de que algo está muy mal con su base de código: ¡necesita ejecutar un conjunto completo de pruebas que lleva una semana solo para asegurarse de que su código sea estable!
La forma más ventajosa de solucionar este problema es comenzar a separar la base de código y las pruebas en subunidades (independientes).
Hay grandes ventajas en esto:
En el reverso, el manejo de su estructura VCS se volverá más complicado, pero en una semana completa para su prueba completa, ¡creo que puede soportar el dolor!
Todavía recomiendo usar una estrategia de sucursales "estable" y de "desarrollo" de una forma u otra, pero hay muchas maneras de hacerlo y puede elegir la que mejor funcione para su organización (meta-repositorios con revisiones fijas que apuntan a repositorios separados para cada unidad, una rama estable y una rama de desarrollo, ramas de características ...)
fuente
Para SVN, no sé acerca de algo como "pre-commit". Creo que es probable que produzca confirmaciones y retrocesos cuando la prueba falla. Como dice doc-brown, la única forma es comprometerse en una rama temporal y fusionarla con el tronco más adelante.
Usando uno distribuido como git o mercurial, creo que sería posible. Usando un repositorio de "prueba" y un repositorio "estable". Presiona el representante de prueba, lo prueba todas las noches y, si todo funciona bien, pasa de prueba a estable. De lo contrario, revierte el representante de prueba. No estoy seguro de cómo se vería el historial de versiones cuando se pasa de la prueba a la estable, pero creo que es posible excluir las cosas rotas al hacer esto. Experimentar un poco primero sería lo más seguro.
Una alternativa también sería probar el tronco local de cada persona todas las noches. Luego, las personas con pruebas aprobadas pueden enviarlo al servidor central por la mañana.
fuente
En mi humilde opinión esto no tiene nada que ver con el VCS que está utilizando. El uso de una rama "bajo prueba" puede ser una solución, que también puede realizarse con VCS centralizado o distribuido. Pero honestamente, creo que lo mejor en su situación es tratar de optimizar el conjunto de pruebas medianas (parece que contiene las pruebas más importantes) para que se ejecute mucho más rápido, de modo que pueda usarlo para pre-commit-to-trunk pruebas, tal como lo hace ahora con su "suite pequeña".
fuente
Las pruebas del medio que fallaron: ¿Es cierto que la mayoría de las veces las mismas pruebas fallan?
Si hay una falla, ¿hay siempre las mismas pruebas relacionadas que fallan?
Si es cierto: puede seleccionar selectivamente algunas pruebas medianas que a menudo fallan (una prueba para cada clase de error) y ejecutarlas dentro del conjunto pequeño.
¿La mayoría de las pruebas son pruebas de integración que usan una base de datos real? Si es así, ¿es posible reemplazarlos con una prueba de unidad que tenga una base de datos simulada?
fuente
Necesita hacer que sus pruebas se ejecuten más rápido, no hay otra forma de cuadrar este círculo.
Considere el problema: desea asegurarse de que cuando salga, tenga un código que funcione. Claro, puede retrasar las confirmaciones y hacer ramificaciones hasta antes del lanzamiento, pero eso solo retrasará la aparición del problema hasta la integración. Como en, ¿tendrá que ejecutar la suite de una semana después de cada fusión? La metodología no es la solución, la solución es puramente técnica.
Esto es lo que sugiero:
1) Haga que las pruebas sean lo más atómicas posible y maximice la reutilización del entorno.
2) Obtenga una granja de prueba-suite para ejecutarlos. Si en lugar de 8 módulos grandes terminas con 50, puedes girar un montón de instancias puntuales de Amazon EC2 y ejecutar todo el conjunto en paralelo. Estoy seguro de que esto costará algo de dinero, pero ahorrará grandes cantidades de tiempo de desarrollador.
fuente
Lo clave que está dando por sentado en su pregunta es que todos los commits deben pasar las pruebas. Si bien esta es una buena regla a seguir y parece tener sentido, a veces no es práctica. Su caso es un ejemplo (aunque MadKeithV hace un punto), y me imagino que mantener una rama VCS tan prístina podría ser difícil si no hay suficiente cooperación entre los desarrolladores.
En realidad, lo que quiere es saber de alguna manera qué confirmaciones pasan o no. Una "rama previa a la confirmación", como usted sugirió, funcionaría, pero eso podría requerir un esfuerzo adicional de los desarrolladores cuando realizan las confirmaciones, lo que puede ser difícil de vender.
Un enfoque similar que podría ser más fácil es dejar el tronco para que las personas se rompan como quieran, y tener una rama para los compromisos que no están rotos. Una secuencia de comandos automatizada podría pasar por confirmaciones a medida que se realizan en el tronco, ejecutar las pruebas en ellas y agregarlas a la rama si pasan.
O podría ser absurdamente simplista y tener un script que enumere las confirmaciones de paso en un archivo de texto (que puede o no ser controlado por la versión).
O tenga un sistema por lotes que acepte solicitudes de ramas / revisiones para probar (desde cualquier parte del árbol), y las pruebe y las confirme en el tronco (u otra rama) si pasan.
fuente