¿Debería romper intencionalmente la compilación cuando se encuentra un error en la producción?

410

Me parece razonable que si los usuarios finales encuentran un error grave en la producción, se debe agregar una prueba unitaria fallida para cubrir ese error, rompiendo así la compilación intencionalmente hasta que se solucione el error. Mi razón para esto es que la compilación debería haber fallado todo el tiempo , pero no se debió a una cobertura de prueba automatizada inadecuada.

Varios de mis colegas no están de acuerdo con decir que una prueba de unidad que falla no debe registrarse. Estoy de acuerdo con este punto de vista en términos de prácticas normales de TDD, pero creo que los errores de producción deben manejarse de manera diferente, después de todo, ¿por qué querría permitir ¿Una construcción para tener éxito con defectos conocidos?

¿Alguien más tiene estrategias comprobadas para manejar este escenario? Entiendo que romper la compilación intencionalmente puede ser perjudicial para otros miembros del equipo, pero eso depende completamente de cómo esté utilizando las ramas.

MattDavey
fuente
75
+1; Una pregunta muy provocativa. Puedo ver ambos lados.
Carl Manaster
28
Utiliza el término "la compilación" para incluir "las pruebas", que no es una comprensión universal.
Jay Bazuzi
19
Si está haciendo TDD, escribiría la prueba fallida, luego corregirá el código y luego se registrará . Así evitas una construcción rota.
dietbuddha
77
Por la misma lógica, debe cerrar las instancias en vivo de los clientes hasta que solucione el problema. No, no deberías romper la construcción. Deje que el desarrollador que maneja el error agregue la prueba unitaria y el código cambie juntos. No es necesario cerrar todo el proceso.
Thanos Papathanasiou

Respuestas:

412

Nuestra estrategia es:

Verifica en una prueba que falla, pero anótala con @Ignore("fails because of Bug #1234").

De esa manera, la prueba está ahí, pero la construcción no se rompe.

Por supuesto, observa la prueba ignorada en el error db, por lo que @Ignorese elimina una vez que se corrige la prueba. Esto también sirve como una verificación fácil para la corrección de errores.

El punto de romper la construcción en las pruebas fallidas no es presionar al equipo de alguna manera, es alertarlos de un problema. Una vez que el problema se identifica y se archiva en la base de datos de errores, no tiene sentido hacer que se ejecute la prueba para cada compilación: sabe que fallará.

Por supuesto, el error aún debe corregirse. Pero programar la solución es una decisión comercial y, por lo tanto, no es realmente una preocupación del desarrollador ... Para mí, una vez que se registra un error en la base de datos de errores, ya no es mi problema, hasta que el cliente / propietario del producto me dice que quiere que se solucione .

sleske
fuente
150
+1 Creo que has dado en el clavo con "programar la solución es una decisión comercial" . Como desarrollador, no es mi criterio decidir si un error rompe la compilación.
MattDavey
22
Creo que esta es una solución muy sensata. Especialmente si el próximo tipo que revisa algún código menor, de repente recibe un aviso de "prueba fallida" y piensa que es algo que ha hecho.
Holger
14
"Para mí, una vez que se registra un error en la base de datos de errores, ya no es mi problema" ... +1
Jake Berger
20
@anon Exept en Toyota. Un trabajador de línea ve un defecto, luego tira del cable andon y toda la planta se detiene y la administración se detiene y la línea no se reinicia hasta que se soluciona el problema. Google Andon Cord. No es un concepto nuevo. ver: startuplessonslearned.com/2008/09/…
Christopher Mahan
44
@AndresJaanTack: Esto, por supuesto, dependerá de su metodología, pero en general no estoy de acuerdo. Al menos en un entorno empresarial, la programación del trabajo es una decisión empresarial, y eso incluye la corrección de errores . A veces, una nueva característica (o lanzamiento en una fecha determinada) puede ser más valiosa que corregir un error (menor); en ese caso, la corrección del error debe diferirse. "Reparar el error ahora" sería inapropiado en esa situación, porque retrasa el trabajo más importante.
sleske
106

¿Por qué querría permitir que una compilación tenga éxito con defectos conocidos?

Porque a veces, tienes limitaciones de tiempo. O el error es tan pequeño que realmente no vale la pena retrasar el envío del producto por unos días necesarios para probarlo y arreglarlo.

Además, ¿cuál es el punto de romper la compilación intencionalmente cada vez que encuentras un error? Si lo encontró, arréglelo (o asígnelo a la persona que lo arreglará), sin molestar a todo su equipo. Si desea recordar corregir un error, debe marcarlo como muy importante en su sistema de seguimiento de errores.

Arseni Mourzenko
fuente
Veo su punto, y en general estoy de acuerdo, pero en este caso estamos hablando de un error grave que entró en producción y fue encontrado por los usuarios finales: s
MattDavey
3
Ver el segundo párrafo de mi respuesta.
Arseni Mourzenko
8
Entiendo, creo que el punto se resume en su primer párrafo: no depende del desarrollador juzgar la gravedad del error, o si se trata de un obstáculo, esa es una decisión para el negocio en general.
MattDavey
44
La pregunta es ¿cuál es la prioridad de este error? Podría ser un OMG ARREGLO AHORA, podría ser Sí, eso es molesto, deberíamos solucionarlo en algún momento, podría ser algo en el medio. Pero no todos los errores llegarán al mismo lugar en ese espectro.
Zachary K
55

Las pruebas están ahí para garantizar que no (re) presente problemas. La lista de pruebas fallidas no sustituye a un sistema de seguimiento de errores. Hay una cierta validez en el POV de que las pruebas fallidas no son solo una indicación de errores, sino que también son una indicación de falla en el proceso de desarrollo (desde el descuido hasta la dependencia mal identificada).

Un programador
fuente
20
"La lista de pruebas
fallidas
1
Sugeriría que las pruebas de unidad de regresión ingresen la base del código como parte de la corrección de errores, no antes.
yrk
66
@yarek: Las pruebas de regresión pueden ir a la base de código en cualquier momento, solo deben ignorarse hasta que se solucione el error. Por lo general, los desarrollo mientras diagnostico el problema, porque luego pueden funcionar como ayuda para la depuración.
sleske
Este es un buen ejemplo de por qué "romper la construcción" se convierte en una parte tóxica de un lugar de trabajo donde CI se convierte en simplemente "Desarrollo impulsado por la culpa". Me he sentado en muchas reuniones donde el PHB comienza a quejarse de "descuido" como si por eso la construcción se rompiera. En dicho entorno, difícilmente registraría algo que rompiera la compilación. De lo contrario, el PHB se enojará. Rompe la construcción, usa el cono de la vergüenza. Que mala práctica.
Warren P
@WarrenP, a veces hay otros problemas, pero seamos claros, el descuido es la primera razón por la cual las construcciones se rompen. Si sabe que algo rompe la compilación, ¿por qué registrarlo?
Programador del
23

"Romper la compilación" significa evitar que una compilación se complete con éxito . Una prueba fallida no hace eso. Es una indicación de que la compilación tiene defectos conocidos, lo cual es exactamente correcto.

La mayoría de los servidores de compilación rastrean el estado de las pruebas a lo largo del tiempo y asignarán una clasificación diferente a una prueba que ha fallado desde que se agregó frente a una regresión (prueba que solía pasar y ya no lo hace), y también detectan la revisión en la que La regresión tuvo lugar.

Ben Voigt
fuente
12
Esto no siempre es correcto, a menudo los equipos consideran una prueba fallida como una construcción rota; de hecho, la mayoría de los equipos que he visto últimamente lo hacen (es una práctica ágil típica). Con la mayoría de los equipos ágiles, una prueba fallida es un caso en el que se detiene la línea: todo el equipo ataca el problema y lo resuelve. Supongo que podría considerar que su publicación significa que la respuesta debe basarse en sus prácticas, en cuyo caso es totalmente precisa.
Bill K
2
Siempre considero que una prueba fallida significa que la compilación ha fallado.
John Saunders
@ JohnSaunders: Pero eso no es lo que significa. Como dije en mi respuesta, significa "la compilación tiene defectos conocidos".
Ben Voigt
1
@ho dijo que no había pruebas? ¿De dónde sacas eso? Quiero decir que mi primer paso después de encontrar el error no es evitar que la compilación tenga éxito, sino crear un informe detallado del error. Cuando se repara el error, primero debe haber una prueba de unidad fallida.
John Saunders
1
Tengo poco problema con la creación inmediata de una prueba fallida. Simplemente no quiero que se registre en el conjunto de pruebas que se ejecutarán al compilar. También quiero que el desarrollador que corrige el error pueda ignorar esa prueba. En la mayoría de los lugares donde he trabajado, las personas que crean el informe de error no crearán pruebas unitarias.
John Saunders
16

Yo diría que la prueba de falla debe agregarse, pero no explícitamente como "una prueba de falla".

Como @BenVoigt señala en su respuesta , una prueba fallida no necesariamente "rompe la construcción". Supongo que la terminología puede variar de un equipo a otro, pero el código aún se compila y el producto aún puede enviarse con una prueba fallida.

Lo que debes preguntarte en esta situación es:

¿Cuáles son las pruebas destinadas a lograr?

Si las pruebas están ahí solo para que todos se sientan bien con el código, entonces agregar una prueba fallida solo para que todos se sientan mal por el código no parece productivo. Pero entonces, ¿qué tan productivas son las pruebas en primer lugar?

Mi afirmación es que las pruebas deben ser un reflejo de los requisitos comerciales . Por lo tanto, si un "error" se ha encontrado que indica un requisito no se cumple adecuadamente, entonces es también una indicación de que las pruebas no reflejan correctamente o totalmente los requerimientos del negocio.

Ese es el error que se debe solucionar primero. No estás "agregando una prueba fallida". Estás corrigiendo las pruebas para ser un reflejo más preciso de los requisitos del negocio. Si el código no pasa esas pruebas, eso es algo bueno. Significa que las pruebas están haciendo su trabajo.

La prioridad de arreglar el código será determinada por la empresa. Pero hasta que se arreglen las pruebas, ¿se puede determinar realmente esa prioridad? El negocio debe estar armado con el conocimiento de exactamente qué está fallando, cómo está fallando y por qué está fallando para poder tomar sus decisiones con prioridad. Las pruebas deberían indicar esto.

Tener pruebas que no pasan completamente no es algo malo. Crea un gran artefacto de problemas conocidos que deben priorizarse y manejarse en consecuencia. Sin embargo, tener pruebas que no prueban completamente es un problema. Pone en duda el valor de las pruebas mismas.

Para decirlo de otra manera ... La construcción ya está rota. Todo lo que está decidiendo es si llamar o no la atención sobre ese hecho.

David
fuente
1
Su afirmación es incorrecta, las pruebas unitarias no necesariamente se asignan directamente a los requisitos comerciales, mientras que las pruebas funcionales o de extremo a extremo probablemente sí, pero el OP estaba hablando de pruebas unitarias / TDD.
John Buchanan
@JohnBuchanan: ¿Cuáles son las pruebas destinadas a validar, si no es que el software está haciendo lo que se supone que debe hacer? (Es decir, que cumple con los requisitos). Hay, como usted dice, otras formas de pruebas fuera de las pruebas unitarias. Pero no veo el valor en las pruebas unitarias que no validan que ese software satisfaga las necesidades del negocio.
David
1
@JohnBuchanan: no dijo "las pruebas SON un reflejo de los requisitos comerciales", dijo "DEBE SER". Lo cual es cierto, pero discutible. Tiene razón al afirmar que este no es siempre el caso, algunas personas escriben pruebas unitarias que no se corresponden con los requisitos comerciales, aunque (en mi opinión) están equivocados al hacerlo. Si quiere afirmar que la afirmación de David es incorrecta, podría decir algo sobre por qué cree que sí.
Dawood ibn Kareem
13

En nuestro equipo de automatización de pruebas, verificamos las pruebas fallidas siempre que fallen debido a un defecto en el producto en lugar de un defecto en la prueba. De esa forma tenemos pruebas para el equipo de desarrollo de que, bueno, lo rompieron. Romper la compilación está muy mal visto, pero eso no es lo mismo que registrarse en pruebas perfectamente compilables pero que fallan.

Yamikuronue
fuente
44
Creo que la idea de @ MattDavey es excelente, y lo he defendido en el pasado. Siempre me he encontrado con un muro de piedra de resistencia: "¡nunca debes romper la construcción!". La idea de que la construcción ya está rota en esta situación parece imposible de comprender para las personas. Lamentablemente, este es solo otro caso en el que una buena idea (pruebas automáticas y construcciones limpias) se ha convertido en una práctica de culto de carga cuyos adherentes conocen la regla pero no la razón.
Tom Anderson
3
Una idea que se me ocurrió es que al equipo de control de calidad (si son lo suficientemente técnicos como para escribir pruebas) se les debería permitir escribir pruebas fallidas para detectar errores y verificarlas. La obsesión de los desarrolladores con la barra verde conduciría a absolutamente priorizando la corrección de errores sobre la adición de características, que es la forma correcta de hacer desarrollo
Tom Anderson
Pero estas no deberían ser pruebas unitarias que se ejecutarán durante la compilación. Si su entorno contiene un sistema de administración de pruebas para el control de calidad (como Microsoft Test Manager), entonces, sin duda, uno o más casos de prueba deben agregarse y vincularse al error, pero esto no evitará que la compilación tenga éxito, simplemente sería una prueba caso que tiene que pasar antes de que el error se considere "Listo".
John Saunders
7

Escribir una prueba que sabe que fallará hasta que se solucione el error es una buena idea, es la base de TDD.

Romper la construcción es una mala idea. ¿Por qué? Porque significa que nada puede avanzar hasta que se arregle. Esencialmente bloquea todos los demás aspectos del desarrollo.

Ejemplo 1
¿Qué sucede si su aplicación es grande, con muchos componentes? ¿Qué pasa si esos componentes son trabajados por otros equipos con su propio ciclo de lanzamiento? ¡Difícil! ¡Tienen que esperar su corrección de errores!

Ejemplo 2
¿Qué sucede si el primer error es difícil de solucionar y encuentra otro error con mayor prioridad? ¿También rompes la compilación para el segundo error? Ahora no puedes construir hasta que ambos estén arreglados. Has creado una dependencia artificial.

No hay una razón lógica por la que la falla de una prueba deba detener una compilación. Esta es una decisión que el equipo de desarrollo debe tomar (quizás con una discusión administrativa) sopesando los pros y los contras de lanzar una compilación con errores conocidos. Esto es muy común en el desarrollo de software, casi todo el software principal se lanza con al menos algunos problemas conocidos.

Qwerky
fuente
5

Depende del papel que se supone que juegan las pruebas y de cómo se supone que sus resultados afectan el sistema / proceso de compilación adoptado. Mi comprensión de romper la compilación es la misma que la de Ben, y al mismo tiempo, no debemos verificar a sabiendas el código que rompe las pruebas existentes. Si esas pruebas llegaron "más tarde", podría estar "bien" ignorarlas solo para que sea menos innecesariamente perjudicial para los demás, pero encuentro esta práctica de ignorar las pruebas reprobadas (para que parezcan aprobadas) bastante inquietante (especialmente para pruebas unitarias), a menos que haya una manera de indicar tales pruebas como ni rojo ni verde.

Prusswan
fuente
"a menos que haya una manera de indicar que las pruebas no son rojas ni verdes" Solo para el registro: la mayoría de los marcos de pruebas unitarias distinguen las pruebas rojas, verdes e ignoradas. Al menos JUnit y TestNG lo hacen (informan "xx test, x falló, x ignorado").
sleske
@sleske sería ideal, solo quiero asegurarme de que ignorar las fallas no se convierta automáticamente en un éxito
Prusswan
¿No hay construcciones AMARILLAS? (Rojo / Verde / Amarillo) en Hudson / Jenkins, Cruise Control y todos los otros grandes?
Warren P
@Warren P funciona cuando las personas ignoran las pruebas correctamente, pero algunas ignoran las pruebas haciéndolas verdes
Prusswan
5

Depende del error, por supuesto, pero en general si algo salió mal que no se identificó durante las pruebas manuales o automáticas, eso implica que hay una brecha en su cobertura. Definitivamente, me gustaría animar a descubrir la causa raíz y poner un caso de prueba de unidad además del problema.

Si se trata de un problema de producción que está planificado para una reparación en caliente de una rama de mantenimiento, también debe asegurarse de que la solución funcione en la línea principal y que un desarrollador no pueda eliminar la solución por error con una resolución de conflicto de fusión excesivamente entusiasta .

Además, dependiendo de su política de lanzamiento, la presencia de pruebas unitarias recientemente actualizadas puede ayudar a confirmar que un desarrollador realmente ha solucionado el problema, en lugar de simplemente cambiarlo [(¿el problema o las pruebas?)], Aunque esto depende de haber codificado el requisitos correctos en las nuevas pruebas unitarias.

Keith trae
fuente
5

Un problema al agregar una prueba de saber fallar a la compilación es que su equipo puede acostumbrarse a ignorar las pruebas fallidas porque esperan que la compilación falle. Depende de su sistema de compilación, pero si una prueba fallida no siempre significa "algo acaba de romperse", entonces es fácil prestar menos atención a las pruebas fallidas.

No quieres ayudar a tu equipo a tener esa mentalidad.

Por lo tanto, estoy de acuerdo con Sleske en que debe agregar la prueba, pero marcarla como 'ignorada' a los efectos de la compilación automática, hasta que se solucione el error.

Wilka
fuente
1
Su software de prueba debería indicarle cuándo algo se ha roto recientemente, en comparación con una prueba que ya no se realizó correctamente.
Ben Voigt
4

Si bien creo que de alguna manera deberías 'revisar' el error como prueba, para que cuando lo arregles no vuelva a ocurrir, y de alguna manera priorizarlo, creo que es mejor no romper la compilación (/ las pruebas) . La razón es que las confirmaciones de ruptura de compilación posteriores se ocultarán detrás de su prueba interrumpida. Entonces, al registrar una prueba rota para este error, usted exige que todo el equipo deje de lado su trabajo para solucionar este error. Si eso no sucede, puede terminar rompiendo confirmaciones que no son rastreables como tales.

Por lo tanto, diría que es mejor cometerlo como una prueba pendiente y hacer que sea una prioridad en su equipo no tener pruebas pendientes.

markijbema
fuente
4

Otra opción es verificar la prueba fallida en una rama separada en su sistema de control de fuente. Dependiendo de sus prácticas, esto puede ser factible o no. A veces abrimos una nueva rama para el trabajo en curso, como arreglar un error que no es trivial.

Ola Eldøy
fuente