unitarias unitaria una software que pruebas prueba las ejemplo desventajas unit-testing testing refactoring

unit testing - unitaria - ¿Qué harías cuando estés a punto de agregar algunas características nuevas a una base de código grande(y sucia) que tiene prácticamente un código de prueba de la unidad*NO*?



que es una prueba unitaria de software (14)

Martin Fowler dice que deberíamos refactorizar antes de agregar nuevas características (dado que el programa original no está bien estructurado).

Entonces, todos queremos refactorizar esta sucia base de código, eso es seguro. También sabemos que sin código de prueba unitaria es muy fácil introducir errores sutiles.

Pero es una gran base de código. Agregar un conjunto completo de pruebas parece impracticable.

¿Qué haría usted en este caso?


Me encuentro en esta situación con bastante frecuencia, ya que es más o menos con lo que he estado atrapado durante los últimos dos años.

El enfoque correcto realmente depende más de los aspectos sociales y organizacionales que del aspecto técnico de las cosas. Tu trabajo es generar valor para tu organización. Si la refacturación generará más valor de lo que cuesta, entonces debería poder venderlo. En mi caso, los factores clave incluyen:

  1. Propiedad esperada del proyecto en cuestión. Si espera ser una parte interesada significativa en esta pieza de software en particular para el futuro previsible, ese es un argumento a favor de hacer modificaciones más extensas a una base de códigos erróneos porque va a pagar más a medida que la mantiene en el futuro. Si está agregando una función de conducción, adopte un enfoque más práctico.

  2. Complejidad de los cambios que se están realizando. Si está realizando cambios muy complejos en la base de código (un caso típico en una base de código "sucia", dado que dicha fuente generalmente está estrechamente acoplada e incoherente), es probable que se requiera alguna refactorización. Dichos cambios no son el resultado de ser un código ninja, ya que son necesarios para que usted simplemente razone sobre los cambios que está realizando. Esto también está relacionado con la "maldad" de la base de código que está modificando. Es prácticamente imposible crear incluso las pruebas unitarias más simples para un desorden incohesivo estrechamente acoplado. (Hablo por experiencia. Uno de los proyectos a los que casi me atoraba mantener era de aproximadamente 20k líneas de longitud, excluyendo código generado, en doce archivos. Toda la aplicación era una clase única llamada "Form1". Este es un ejemplo de un desarrollador que abusó del característica de clase parcial.)

  3. Supervisión organizacional La fuerza y ​​el rigor de la supervisión de su organización entran en juego aquí. Si su grupo realmente realiza algunas de las mejores prácticas centrales, como las revisiones de códigos, y no solo les rinde culto, estaría más inclinado a no realizar refactorizaciones extensas. La compensación de valor probablemente pesó más a favor de tocar lo menos posible porque tienes otro par de ojos frescos revisando para asegurarte de que ninguno de los pocos cambios que hiciste tenga efectos secundarios indeseables. Del mismo modo, es más probable que una supervisión más estricta frunza el ceño ante las tácticas del código "guerrillero" de hacer cambios que no están estrictamente solicitados en la solicitud de cambio.

  4. Su jefe. Si su jefe está de su lado, es mucho más probable que pueda mejorar su base de código a largo plazo, especialmente si puede justificar el aumento en el costo ahora en términos de horas presupuestarias más adelante. Recuerde que su gerente tiene una mejor perspectiva de la función de este software en el panorama general que usted. Si se trata de un software que solo utilizan diez o veinte personas, no requiere el tipo de mejoras de mantenimiento a largo plazo que requiere un software utilizado por diez o veinte mil personas.

La pregunta central que debe responder al considerar cualquier tipo de inversión de tiempo como esta es "¿Dónde se encuentra el valor?" Entonces necesitas perseguir ese valor.


Mucho depende de tu idioma. Si está en un lenguaje estáticamente tipado, probablemente pueda escapar sin pruebas unitarias. He trabajado en muchos trabajos que hicieron exactamente lo que describes.

Si es una buena cantidad de trabajo (digamos, un año hombre o 3 personas durante 4 meses), entonces es probable que desee que alguien rompa el código y lo analice primero.

Si se trata de un lenguaje dinámico, será más problemático: necesitará un poco de nivel de pruebas unitarias. Tal vez podría agregar pruebas unitarias a las áreas que necesita tocar.

Solo diferencio entre lenguajes estáticos y dinámicos porque es mucho más fácil hacer refactorizaciones en un lenguaje estáticamente tipado, tienden a ser mucho más predecibles. No estoy odiando a Ruby ni nada, también pasé un año en ROR. Solo creo que necesitan diferentes enfoques.


Primero, agregue pruebas para las partes que va a cambiar. Segundo, refactorice el código hasta que tenga sentido para una persona cuerda. En tercer lugar, realice los cambios necesarios.


Tienes que empezar en alguna parte. Puede comenzar agregando pruebas donde pueda y desarrollar su conjunto de pruebas a medida que avanza. Incluso si tienes algunas pruebas "tontas" que no hacen más que decirte que solo puedes probar alguna parte del código, te dice algo.


Agregue pruebas unitarias al código que va a refactorizar.



Mi sugerencia es que toque lo menos posible y agregue lo que necesita. He descubierto que es mejor dejarlo solo, especialmente si tiene un plazo ajustado.

Si hubieras tenido pruebas unitarias, esa sería una historia diferente, pero cuando cambias el código puede ser como tocar una telaraña. Cambiar una cosa puede afectar a todo lo demás.


No pienses en esto como una proposición cualquiera. Se agrega valor al agregar pruebas unitarias; no es necesario agregar un conjunto completo para obtener los beneficios de agregar algunas pruebas.


Permítanme recomendar el libro Working effective with legacy code de Michael Feathers. Contiene muchos ejemplos realistas y muestra buenas técnicas para abordar la bestia del código heredado.


Si agregar un conjunto de pruebas no es práctico, entonces tiene un problema grave con la base de código.

Agregar código nuevo y esperar que Just Works sea malo.

Escriba las pruebas, refactorice la base y agregue un nuevo código. Si no puede probarlo, nunca sabrá si es correcto.


Fowler también sugiere que nunca se refactorice sin la seguridad de las pruebas. Pero, ¿cómo haces esas pruebas en su lugar? Y, ¿qué tan lejos vas?

El libro recomendado anteriormente ( Working Effectively with Legacy Code por Michael Feathers) es el trabajo definitivo sobre el tema.

¿Necesita una lectura más rápida? Eche un vistazo al artículo anterior de Michael (PDF) del mismo nombre.


Cuando las pruebas unitarias no existen o son terriblemente difíciles de agregar con la cobertura adecuada en el marco de tiempo dado, tendrá que confiar en las pruebas regulares. En teoría, esta base de código grande y sucia de la que hablas ha sido considerada apta para usarse desde hace un tiempo. Para hacer esa determinación, hubo pruebas de programador, pruebas de control de calidad o algún tipo de prueba realizada por el cliente. Desea saber cómo se hizo, qué se hizo, si es suficiente para cubrir los cambios que realizará, y luego obtener el compromiso de volver a hacerlo, además de las pruebas necesarias para el nuevo código hasta que el producto sea bueno. suficiente.

Las pruebas unitarias son un gran servicio para un programador, pero no son el único tipo de prueba que existe.


Estoy de acuerdo con los demás, toque lo menos posible. Pero, también, siempre puede comenzar a escribir pruebas de unidades para nuevas funcionalidades y / o funciones existentes que tocará. Nadie dijo que necesitas escribir pruebas unitarias para probar el 100% de la base de códigos existente para empezar.


toca lo menos posible. Y reza.