Pruebas de unidades antiguas / heredadas rotas

13

Trabajo para una gran empresa y soy responsable de una gran aplicación de Java con miles de pruebas junit. Desde que me mudé a este rol, ha habido 200-300 pruebas rotas (probablemente rotas por años). Las pruebas son antiguas y frágiles y son un desastre de dependencias de espagueti que generalmente terminan con datos de sandbox en vivo.

Mi objetivo es pasar el 100% de las pruebas para que podamos romper la construcción en las fallas de las pruebas unitarias, pero no puedo hacerlo hasta que aborde las pruebas rotas. Tengo muy poco presupuesto porque el presupuesto de mantenimiento es principalmente para soporte, pero mi equipo ha identificado y reparado las pruebas frutales de bajo perfil (en su mayoría problemas de configuración / recursos locales) y tenemos 30-40 pruebas realmente feas.

¿Cuáles son algunas opiniones sobre las mejores prácticas? No creo que las pruebas sean valiosas, pero tampoco sé qué están probando o por qué no funcionan sin excavar, lo que lleva tiempo y dinero que probablemente no tengamos.

Estoy pensando que deberíamos documentar los estados de las pruebas rotas con todo lo que sabemos, luego eliminar o ignorar las pruebas rotas por completo e ingresar un elemento de trabajo / error de menor prioridad para investigar y corregirlos. Entonces estaremos al 100% y comenzaremos a obtener un valor real de las otras pruebas y si tenemos una ganancia inesperada de mantenimiento / refactorización podremos retomarlas nuevamente.

¿Cuál sería el mejor enfoque?

Editar: Creo que esta es una pregunta diferente a esta pregunta porque tengo una dirección clara para las pruebas que deberíamos escribir en el futuro, pero heredé las pruebas de fallas heredadas para abordar antes de que el gran conjunto actual de pruebas se vuelva significativo.

Grenth
fuente
1
Definitivamente de acuerdo en que debe deshacerse de 30-40 pruebas feas. Sin embargo, "si tenemos una ganancia inesperada de mantenimiento / refactorización podremos recogerlos de nuevo" parece una ilusión. No estoy seguro de que haya algún beneficio real al documentarlos como un elemento de baja prioridad, ya que estos elementos tienen la costumbre de nunca ser accionados.
David Arno
1
Recomiendo revisar este libro: Trabajando efectivamente con código heredado . Una recomendación de libro no es una respuesta a su pregunta, pero encontrará muchos buenos consejos sobre las pruebas unitarias.
44
Esto puede ser un duplicado de algo, pero es no esa pregunta. No se trata de cómo evitar escribir pruebas unitarias frágiles, sino cómo administrar una base de código heredada con pruebas unitarias ya escritas que están fallando.
1
Parece que ya has encontrado tu solución.
Doc Brown el
2
@gnat no estoy de acuerdo. Por experiencia personal, hay una gran diferencia entre "algo rompió muchas de mis pruebas unitarias anoche" y "Heredé mucho código antiguo con las pruebas unitarias que fallaron el tiempo suficiente, nadie sabe por qué". Uno es un problema con el desarrollo actual, otro es un problema con el software heredado. Se necesitan dos enfoques diferentes aquí. La respuesta principal en la pregunta vinculada no aborda los aspectos heredados.

Respuestas:

17

Lo que haría es deshabilitar primero las pruebas que fallan y siempre han fallado.

Haz que una prueba que falle sea importante.

A medida que investigas, podrías preguntarles a las personas que han estado con tu compañía más tiempo sobre ellos, puede haber un gran conocimiento tribal sobre ellos que puedes documentar / capturar. Tal vez de sus registros de VCS. "Oh, esa prueba siempre ha fallado desde que actualizamos a X" u otra información puede ser útil.

Una vez que sepa cuál fue la funcionalidad que se está probando, puede determinar:

  • ¿Nos importa que esto sea probado?
  • ¿Qué tan importante es esto para ser probado?

Y luego haga una lista de prioridades.

Probablemente nada en esta lista es lo suficientemente importante como para tener más tiempo más tarde, ya que ha sido ignorado durante años. Así que no pasaría demasiado tiempo / recursos documentando y analizando todas estas pruebas rotas.

Enderland
fuente
1
Me gusta la idea de deshabilitar las pruebas por adelantado, pero un entorno conservador podría preferir movimientos incrementales más pequeños. ¿Supongo que depende de tu empresa?
Aaron Hall el
1
@AaronHall: creo que si observa sus necesidades de cambio de código inmediato (correcciones y mejoras) e identifica las pruebas rotas que están asociadas con ellas, puede activar todo esto, evaluar y corregir las pruebas, realizar los cambios de codificación con la comprensión que las pruebas pasan, se arreglan o se eliminan.
JeffO
6

Yo haría lo siguiente:

  1. Intente determinar exactamente qué pruebas fallidas intentan validar.

  2. Triaje: si algunas pruebas intentan probar cosas sin importancia como (un antiguo) estado del mundo, elimínelas. Si se da cuenta de que algunos de ellos están intentando validar algo importante, trate de determinar si esas pruebas lo están haciendo correctamente. Si están probando incorrectamente, haz que prueben correctamente.

  3. Arregle lo que está mal con su código de producción ahora que tiene buenas pruebas.

Recuerde contabilidad, cada línea de código es un pasivo, pero puede valorarse incorrectamente como un activo. La deleteclave puede crear mucho valor para su empresa.

Aaron Hall
fuente
¡Una idea de triaje estilo equipo es muy agradable!
Buenas ideas, pero OP ya dijo que no tiene recursos para realizar un análisis exhaustivo, por lo que desafortunadamente no podrá usarlas.
TMN
El triaje se trata de racionar recursos limitados para crear el mayor valor. Aquí hay una publicación de blog relevante sobre el tema de triaje y software: softwaretestingclub.com/profiles/blogs/…
Aaron Hall
5

200-300 pruebas rotas (probablemente rotas por años).

¡Ay! Me enfrenté a una situación similar una vez, pero con 7 pruebas fallidas en las que el equipo comenzó a ignorar el hecho de que fallaron durante meses debido a la mentalidad de "crisis".

Mi objetivo es pasar el 100% de las pruebas para que podamos romper la construcción en las fallas de las pruebas unitarias, pero no puedo hacerlo hasta que aborde las pruebas rotas.

Estaba obsesionado con un objetivo similar a pesar de que solo era un desarrollador junior en el equipo porque noté una acumulación en la que fallaban más pruebas a lo largo de los meses. Quería que convirtiéramos esos de "advertencias" en errores de compilación (quizás algo desagradable para el resto del equipo).

Estoy pensando que deberíamos documentar los estados de las pruebas rotas con todo lo que sabemos, luego eliminar o ignorar las pruebas rotas por completo e ingresar un elemento de trabajo / error de menor prioridad para investigar y corregirlos. Entonces estaremos al 100% y comenzaremos a obtener un valor real de las otras pruebas y si tenemos una ganancia inesperada de mantenimiento / refactorización podremos retomarlas nuevamente.

Estos son mis pensamientos también. Puede deshabilitar temporalmente todas estas pruebas defectuosas y visitarlas lentamente y corregirlas con el tiempo. Sin embargo, es importante programar esas soluciones si las considera realmente importantes, incluso si son de baja prioridad, ya que es fácil que dichos elementos simplemente no se fijen. La prioridad para mí es asegurarme de que no se introduzcan nuevas pruebas que fallen.

Como cualquier tipo de advertencia, si no rompen la construcción, tienden a acumularse rápidamente. Esto supone que ese tipo de dinámica de equipo donde el hábito de ignorar las advertencias (pruebas fallidas en este caso) puede conducir rápidamente a la introducción de más advertencias y reducir la tentación de mantener esas advertencias a cero.

Un equipo muy concienzudo podría no sufrir estos problemas y evitar la introducción de nuevas advertencias (nuevas fallas en las pruebas), pero definitivamente es más seguro ir un poco más duro y ejercer una estrategia de prevención convirtiéndolos en errores que deben corregirse antes de un proceso de fusión

Por lo tanto, mi sugerencia es la misma que la suya (aunque solo sea una opinión sólida, tal vez algo pueda respaldar esto con métricas y una respuesta más científica). Deshabilite esas pruebas anteriores y póngalo en el cronograma para eventualmente arreglarlas. La primera prioridad es asegurarse de que este problema no se acumule y comience a empeorar asegurándose de que las pruebas que actualmente tienen éxito no terminen siendo ignoradas si comienzan a fallar.


fuente
4

En cierto modo tienes suerte. Es mejor tener pruebas que fallen y no deberían (le dan una advertencia al menos de que algo está mal) que tener pruebas que pasen y no deberían (que le dan una falsa sensación de seguridad).
Por supuesto, si tiene el primero, es muy probable que también tenga el último (por lo que las pruebas pasan pero deberían fallar).

Como ya se dijo, por ahora deshabilite esas pruebas que fallan pero haga que impriman un mensaje en su registro de prueba como un recordatorio constante sobre ellas.
Pero definitivamente debe encontrar los recursos para revisar todo su conjunto de pruebas con el fin de encontrar y eliminar las pruebas que pasan y no deberían, porque cada una de ellas significa que hay un error en su código que actualmente no está detectando en su ciclos de prueba

Usando esa nube oscura que se cierne sobre la base del código, es posible que pueda obtener un presupuesto para una revisión completa de sus pruebas, si lo juega bien y no solo les dice que cree que algunas pruebas deberían examinarse porque parecen fallar cuando no deberían, pero que no confía en que sus pruebas están detectando errores en su código correctamente, que no se puede confiar en que el conjunto de pruebas haga su trabajo.
Cuando hice eso en una compañía anterior en la que estaba trabajando para tal revisión, encontré que cientos de pruebas fueron escritas con suposiciones incorrectas sobre lo que DEBE hacer el código, lo que llevó a que el código (que fue escrito usando las mismas suposiciones incorrectas) pasara las pruebas cuando Realmente no debería haberlo hecho. Solucionar esto solucionó muchos errores desagradables que (aunque la mayoría no eran críticos) podrían haber derribado algunos sistemas importantes.

jwenting
fuente
3

Cualquier prueba unitaria fallida debería hacer que la construcción se rompa. Bien por ti para darte cuenta y establecer esa meta. La mente humana difícilmente puede ignorar algo más que la fuente de una falsa alarma persistente .

Deseche estas pruebas y no mire hacia atrás. Si han fallado durante años y no se han abordado hasta ahora, entonces no son una prioridad.

En cuanto al conocimiento tribal, si las personas con el conocimiento tribal todavía están cerca, ya deberían haber reparado las pruebas fallidas. Si no, entonces nuevamente, estos no son una prioridad.

Si no hay conocimiento tribal, usted y su equipo deben tomar posesión de la lógica. Las pruebas fallidas pueden ser más engañosas que útiles: el mundo puede haber avanzado.

Cree nuevas pruebas que sean relevantes y continúe escribiendo un gran código.

Shmoken
fuente