- Estoy hablando de pruebas unitarias en el sentido TDD. (No es una "integración" automatizada, o lo que le gusta llamar pruebas).
- Código heredado como en: código (C ++) sin pruebas. (ver: Michael Feathers ' Trabajando efectivamente con código heredado )
- Pero también el código heredado como en: Código con el que nuestro equipo ha estado trabajando durante los últimos 10-5 años, por lo que a menudo tenemos una muy buena idea de dónde poner las cosas para cambiar algo.
- Tenemos pruebas unitarias (a través de Boost.Test) para algunos módulos que vinieron más tarde o que han sido "naturales" para pruebas unitarias (contenedores específicos de aplicaciones comunes, elementos de cadena, ayudantes de red, etc.)
- Todavía no tenemos pruebas de aceptación automatizadas adecuadas.
Ahora, recientemente tuve el "placer" de implementar 3 nuevas funciones orientadas al usuario.
Cada uno de ellos me tomó aproximadamente 1-2 horas para ponerme al día con las partes del código que necesitaba cambiar, 1-2 horas para implementar el (pequeño) código que necesitaba cambiar y otras 1-2 horas para asegurarme de que la aplicación funcionó correctamente después e hizo lo que se suponía que debía hacer.
Ahora, realmente agregué un pequeño código. (Creo que hay un método y algunas líneas de llamada para cada función).
Factorizar el código (a través de cualquiera de los métodos sugeridos en WEwLC ), de modo que una unidad de prueba hubiera algún sentido (y no ha sido una tautología completa) habría fácilmente tomado otras 2-4 horas, si no más. Esto habría agregado un 50% -100% de tiempo a cada función, sin beneficio inmediato, ya que
- No necesitaba la prueba unitaria para entender nada sobre el código
- La prueba manual es la misma cantidad de trabajo, ya que aún necesito probar si el código está integrado correctamente en el resto de la aplicación.
De acuerdo, si , más adelante, "alguien" vino y tocó ese código, teóricamente podría obtener algún beneficio de esa prueba de unidad. (Solo teóricamente, ya que esa isla de código probada viviría en un océano de código no probado).
Entonces, "esta vez" decidí no hacer el trabajo duro de agregar una prueba unitaria: los cambios en el código para obtener esas cosas bajo prueba habrían sido significativamente más complejos que los cambios en el código para implementar la función correctamente (y limpiamente).
¿Es esto algo típico para código heredado fuertemente acoplado? ¿Soy flojo / establecemos las prioridades equivocadas como equipo? ¿O soy prudente, solo probando cosas donde la sobrecarga no es demasiado alta?
fuente
Respuestas:
Tienes que ser pragmático sobre estas situaciones. Todo tiene que tener un valor comercial, pero la empresa tiene que confiar en usted para juzgar cuál es el valor del trabajo técnico. Sí, siempre hay un beneficio en tener pruebas unitarias, pero ¿es ese beneficio lo suficientemente bueno como para justificar el tiempo dedicado?
Yo diría siempre en el nuevo código, sino, por el código heredado, lo que tiene que hacer un juicio.
¿Estás en esta área de código a menudo? Luego hay un caso para la mejora continua. ¿Estás haciendo un cambio significativo? Luego hay un caso de que ya es un código nuevo. Pero si está creando un código de una línea en un área compleja que probablemente no se volverá a tocar durante un año, por supuesto, el costo (sin mencionar el riesgo) de la reingeniería es demasiado grande. Simplemente ingrese su línea de código y báñese rápidamente.
Regla general: siempre piense: " ¿Creo que el negocio se beneficia más de este trabajo técnico que creo que debo hacer que el trabajo que me pidieron que se retrasará como resultado? "
fuente
La ganancia de las pruebas unitarias en el sentido TDD es obtener algo que se mantenga por sí mismo, sin necesidad de una tradición oral construida durante años por un equipo estable.
Es una gran suerte que el mismo equipo haya estado en el mismo proyecto durante tanto tiempo. Pero esto eventualmente cambiará. Las personas se enferman, aburren o ascienden. Se mueven, se retiran o mueren. Los nuevos vienen con nuevas ideas y la necesidad de refactorizar todo de la forma en que aprendieron en la escuela. Las empresas se venden y compran. Las políticas de gestión cambian.
Si desea que su proyecto sobreviva, debe prepararlo para los cambios.
fuente
Escribir pruebas unitarias es una prueba futura de su código. Si la base del código no tiene pruebas, entonces debe agregar nuevas pruebas para todas las características nuevas porque hace que ese fragmento de código sea un poco más robusto.
Encuentro que agregar pruebas, incluso en código heredado, es beneficioso a mediano y largo plazo. Si su empresa no se preocupa por el mediano a largo plazo, buscaría otra empresa. Además, no creo que lleve más tiempo probarlo manualmente que escribir una prueba unitaria establecida. Si lo hace, entonces necesita practicar código kata enfocado en escribir pruebas.
fuente
Ciertamente, las mejores prácticas dictan que debe realizar una prueba unitaria de cualquier código que cambie. Sin embargo, la codificación del mundo real implica muchos compromisos, el tiempo y los materiales son limitados.
Lo que debe hacer es evaluar el costo en términos reales de corregir errores y realizar modificaciones sin pruebas unitarias. Entonces puede evaluar la inversión en la creación de esas pruebas. Las pruebas unitarias reducen en gran medida el costo del trabajo futuro, pero ahora tienen un precio.
La conclusión es que si su sistema rara vez cambia, entonces puede que no valga la pena escribir pruebas unitarias, pero si está sujeto a cambios regulares, entonces valdrá la pena.
fuente
Todas estas pequeñas decisiones racionales para no crear pruebas están acumulando una deuda técnica paralizante que volverá a atormentarte cuando alguien se vaya y un nuevo empleado tiene que entrar y ponerse al día.
Sí, podría haber costado otras 2-3 horas escribir las pruebas unitarias, pero si el código se devuelve después de las pruebas, tendrá que probar manualmente todo nuevamente y documentar sus pruebas nuevamente, ¿lo hace, no? De lo contrario, ¿cómo sabe alguien lo que probó y qué valores utilizó?
Las pruebas unitarias documentan el comportamiento esperado del código que usaron los datos de prueba para verificar la funcionalidad y les da a los nuevos codificadores una confianza razonable de que no han roto algo al hacer cambios.
Cuesta un par de horas hoy más que las pruebas manuales, pero luego está probando cada vez que realiza algún cambio, ahorrando horas durante la vida útil del código.
Sin embargo, si sabe que el código será retirado en un par de años, todo lo que he dicho cambia porque no terminará de poner las pruebas en el código y nunca pagará.
fuente
El valor de las pruebas unitarias no solo radica en probar una nueva característica cuando se desarrolla. El beneficio de las pruebas unitarias se obtiene principalmente en el futuro.
Sí, es posible que tenga que pasar lo que parece una cantidad excesiva de tiempo para hacer que su código heredado sea comprobable.
Pero si no lo hace, pasará, o ciertamente debería , pasar muchas, muchas, muchas más horas probando la función. No solo en su desarrollo inicial, sino con cada nueva versión de su software. Sin las pruebas unitarias y otras formas de pruebas automatizadas, no tiene otra opción que pasar muchas horas de pruebas manuales para asegurarse de que su función no se haya roto accidentalmente, incluso cuando esa función en sí no se modificó.
fuente