Pregunta ¿Vale la pena el esfuerzo de las pruebas unitarias? [cerrado]


Estoy trabajando para integrar pruebas unitarias en el proceso de desarrollo en el equipo en el que trabajo y hay algunos escépticos. ¿Cuáles son algunas buenas maneras de convencer a los desarrolladores escépticos en el equipo del valor de Unit Testing? En mi caso específico, estaríamos agregando Pruebas unitarias a medida que agregamos funcionalidad o corrigimos errores. Lamentablemente, nuestra base de códigos no se presta a pruebas fáciles.


573


origen


Respuestas:


Todos los días en nuestra oficina hay un intercambio que va más o menos así:

"Hombre, me encantan las pruebas unitarias, solo he podido hacer un montón de cambios en la forma en que algo funciona, y luego pude confirmar que no había roto nada volviendo a ejecutar la prueba otra vez ..."

Los detalles cambian a diario, pero el sentimiento no. Las pruebas unitarias y el desarrollo basado en pruebas (TDD) tienen tantos beneficios ocultos y personales como los más obvios que uno no puede explicar a alguien hasta que lo hace por sí mismo.

Pero, ignorando eso, ¡aquí está mi intento!

  1. Unit Tests le permite hacer grandes cambios al código rápidamente. Sabe que funciona ahora porque ha realizado las pruebas, cuando realiza los cambios que necesita realizar, necesita que las pruebas vuelvan a funcionar. Esto ahorra horas.

  2. TDD te ayuda a darte cuenta de cuándo detener la codificación. Sus pruebas le dan la confianza de que ya ha hecho lo suficiente por ahora y puede dejar de retocar y pasar a lo siguiente.

  3. Las pruebas y el código trabajan juntos para lograr un mejor código. Su código podría ser malo / con errores. Su PRUEBA podría estar mal / con errores. En TDD, usted está confiando en las posibilidades de ambos siendo malo / con errores siendo bajo. A menudo es la prueba la que debe corregirse, pero sigue siendo un buen resultado.

  4. TDD ayuda a codificar el estreñimiento. Cuando te enfrentas a un gran y abrumador trabajo antes de escribir las pruebas, te pondrás en movimiento rápidamente.

  5. Las pruebas unitarias lo ayudan a comprender realmente el diseño del código en el que está trabajando. En lugar de escribir código para hacer algo, usted está comenzando por delinear todas las condiciones a las que está sometiendo el código y qué salidas esperaría de eso.

  6. Las pruebas unitarias le dan una respuesta visual instantánea, a todos nos gusta la sensación de todas esas luces verdes cuando lo hemos hecho. Es muy satisfactorio También es mucho más fácil continuar donde lo dejaste después de una interrupción porque puedes ver dónde llegaste, esa próxima luz roja que necesita ser reparada.

  7. Contrariamente a las pruebas de unidades de creencias populares, no significa escribir el doble de código, o la codificación más lenta. Es más rápido y más robusto que codificar sin pruebas una vez que lo dominas. El código de prueba en sí mismo es relativamente trivial y no agrega una gran sobrecarga a lo que está haciendo. Este es uno que solo creerás cuando lo estés haciendo :)

  8. Creo que fue Fowler quien dijo: "Las pruebas imperfectas, ejecutarse con frecuencia, son mucho mejores que las pruebas perfectas que nunca se escriben en absoluto". Interpreto que esto me da permiso para escribir pruebas donde creo que serán más útiles, incluso si el resto de la cobertura de mi código es tristemente incompleto.

  9. Las buenas pruebas unitarias pueden ayudar a documentar y definir qué se supone que debe hacer algo

  10. Las pruebas unitarias ayudan con la reutilización del código. Migra tu código y tus pruebas a tu nuevo proyecto. Ajusta el código hasta que las pruebas se ejecuten nuevamente.

Mucho trabajo con el que estoy involucrado no funciona bien con la Unidad (interacciones del usuario de la aplicación web, etc.), pero aún así todos estamos infectados con la prueba en esta tienda, y más felices cuando tenemos nuestras pruebas atadas. No puedo recomendar el enfoque lo suficiente.


722



Las pruebas unitarias se parecen mucho a ir al gimnasio.  Sabes que es bueno para ti, todos los argumentos tienen sentido, entonces comienzas a ejercitarte. Hay una prisa inicial, que es genial, pero después de unos días empiezas a preguntarte si vale la pena. Te estás tomando una hora del día para cambiarte de ropa y correr con una rueda de hámster y no estás seguro de que estés ganando algo más que piernas y brazos adoloridos.

Entonces, después de tal vez una o dos semanas, justo cuando el dolor se va, comienza una gran fecha límite. Debes pasar cada hora despierta tratando de hacer un trabajo "útil", para que elimines las cosas extrañas, como ir al gimnasio. Pierdes el hábito, y para el momento en que termine Big Deadline, vuelves al punto de partida. Si logras regresar al gimnasio, te sientes tan dolorida como la primera vez que fuiste.

Lees algo para ver si estás haciendo algo mal. Comienzas a sentir un poco de rencor irracional hacia todas las personas en forma, felices exaltando las virtudes del ejercicio. Te das cuenta de que no tienes mucho en común. No tienen que conducir 15 minutos fuera del camino para ir al gimnasio; hay uno en su edificio. No tienen que discutir con nadie sobre los beneficios del ejercicio; es solo algo que todos hacen y aceptan como importante. Cuando se acerca una gran fecha límite, no se les dice que el ejercicio es innecesario más de lo que su jefe le pedirá que deje de comer.

Por lo tanto, para responder a su pregunta, las Pruebas unitarias generalmente valen la pena, pero la cantidad de esfuerzo requerido no será la misma para todos.  Las pruebas unitarias pueden requerir una enorme cantidad de esfuerzo si se trata de una base de código de espaguetis en una empresa que no actualmente valorar la calidad del código. (Muchos gerentes cantarán los elogios de Unit Testing, pero eso no significa que lo defenderán cuando sea importante).

Si estás tratando de introducir Pruebas unitarias en tu trabajo y no estás viendo todos los rayos del sol y el arco iris que te han hecho esperar, no te culpes a ti mismo. Es posible que necesite encontrar un nuevo trabajo para que realmente funcione la prueba de unidad.


421



La mejor forma de convencer ... encuentra un error, escribe una prueba unitaria para él, arregla el error.

Es poco probable que ese error en particular vuelva a aparecer, y puedes probarlo con tu prueba.

Si haces esto lo suficiente, otros se darán cuenta rápidamente.


136



thetalkingwalnut pregunta:

¿Cuáles son algunas buenas maneras de convencer a los desarrolladores escépticos en el equipo del valor de Unit Testing?

Todos aquí van a acumular muchas razones por las que las pruebas unitarias son buenas. Sin embargo, me parece que a menudo la mejor manera de convencer a alguien de algo es escucha a su argumento y lo abordan punto por punto. Si los escucha y los ayuda a expresar verbalmente sus inquietudes, puede abordarlos y tal vez convertirlos a su punto de vista (o al menos, dejarlos sin una pierna para pararse). ¿Quién sabe? Tal vez lo convencerán por qué las pruebas unitarias no son apropiadas para su situación. No es probable, pero es posible. Tal vez si publica sus argumentos en pruebas unitarias, podemos ayudar a identificar los argumentos en contra.

Es importante escuchar y comprender ambos lados del argumento. Si tratas de adoptar pruebas unitarias con celo sin tener en cuenta las preocupaciones de las personas, terminarás con una guerra religiosa (y probablemente pruebas de unidad realmente inútiles). Si lo adoptas lentamente y comienzas aplicándolo donde verás el mayor beneficio al menor costo, podrías demostrar el valor de las pruebas unitarias y tener una mejor oportunidad de convencer a las personas. Me doy cuenta de que esto no es tan fácil como parece, por lo general requiere un poco de tiempo y métricas cuidadosas para elaborar un argumento convincente.

Las pruebas unitarias son una herramienta, como cualquier otra, y se deben aplicar de tal manera que los beneficios (detectar errores) superen los costos (el esfuerzo al escribirlos). No los use si / donde no tienen sentido y recuerde que solo son parte de su arsenal de herramientas (por ejemplo, inspecciones, afirmaciones, analizadores de código, métodos formales, etc.). Lo que les digo a mis desarrolladores es esto:

  1. Pueden omitir escribir una prueba para un método si tienen un buen argumento sobre por qué no es necesario (por ejemplo, demasiado simple para valer la pena o demasiado difícil para valer la pena) y cómo se verificará el método (por ejemplo, inspección, afirmaciones). , métodos formales, pruebas interactivas / de integración). Deben considerar que algunas verificaciones, como inspecciones y pruebas formales, se realizan en un momento determinado y luego deben repetirse cada vez que cambia el código de producción, mientras que las pruebas y afirmaciones unitarias pueden usarse como pruebas de regresión (escritas una vez y ejecutadas repetidamente a partir de entonces). ) A veces estoy de acuerdo con ellos, pero con mayor frecuencia debatiré sobre si un método es realmente demasiado simple o demasiado difícil de probar por separado.

    • Si un desarrollador argumenta que un método parece demasiado simple para fallar, ¿no vale la pena tomar los 60 segundos necesarios para escribir una prueba simple de 5 líneas para ello? Estas 5 líneas de código se ejecutarán todas las noches (realiza compilaciones nocturnas, ¿no?) Durante el próximo año o más y valdrá la pena si incluso una vez detecta un problema que puede haber llevado 15 minutos o más para identificarlo. y depurar Además, escribir las sencillas pruebas unitarias aumenta el número de pruebas unitarias, lo que hace que el desarrollador se vea bien.

    • Por otro lado, si un desarrollador argumenta que un método parece demasiado difícil para la prueba unitaria (no vale la pena el esfuerzo significativo requerido), tal vez sea una buena indicación de que el método debe dividirse o refactorizarse para probar las partes fáciles. Por lo general, estos son métodos que dependen de recursos inusuales como singletons, la hora actual o recursos externos como un conjunto de resultados de la base de datos. Por lo general, estos métodos deben refactorizarse en un método que obtiene el recurso (por ejemplo, llamadas getTime ()) y un método que toma el recurso como argumento (por ejemplo, toma la marca de tiempo como parámetro). Les dejo omitir las pruebas del método que recupera el recurso y, en su lugar, escriben una prueba unitaria para el método que ahora toma el recurso como argumento. Por lo general, esto hace que escribir la prueba unitaria sea mucho más simple y, por lo tanto, valga la pena escribir.

  2. El desarrollador debe dibujar una "línea en la arena" sobre cuán completas deberían ser sus pruebas unitarias. Más adelante en el desarrollo, cada vez que encontremos un error, deberían determinar si las pruebas unitarias más completas habrían captado el problema. Si es así y si esos errores surgen repetidamente, necesitan mover la "línea" hacia la escritura de pruebas unitarias más completas en el futuro (comenzando con agregar o expandir la prueba unitaria para el error actual). Necesitan encontrar el equilibrio correcto.

Es importante darse cuenta de que las pruebas unitarias no son una bala de plata y hay es tal cosa como demasiada unidad de prueba. En mi lugar de trabajo, cada vez que hacemos una lección aprendida, inevitablemente escucho "tenemos que escribir más pruebas unitarias". La gerencia asiente de acuerdo porque ha sido golpeada en sus cabezas que "pruebas unitarias" == "bueno".

Sin embargo, debemos entender el impacto de "más pruebas unitarias". Un desarrollador solo puede escribir ~ N líneas de código a la semana y necesita averiguar qué porcentaje de ese código debería ser el código de prueba de la unidad frente al código de producción. Un lugar de trabajo laxo puede tener un 10% del código como pruebas unitarias y un 90% del código como código de producción, lo que da como resultado un producto con muchas características (aunque con muchos errores) (piense en MS Word). Por otro lado, una tienda estricta con 90% de pruebas unitarias y 10% de código de producción tendrá un producto sólido como una roca con muy pocas características (piense en "vi"). Es posible que nunca escuche informes sobre la falla de este último producto, pero es probable que tenga tanto que ver con que el producto no se venda tanto como tiene que ver con la calidad del código.

Peor aún, tal vez la única certeza en el desarrollo de software es que "el cambio es inevitable". Supongamos que el taller estricto (90% de pruebas unitarias / 10% de código de producción) crea un producto que tiene exactamente 2 características (suponiendo 5% del código de producción == 1 función). Si el cliente aparece y cambia una de las características, ese cambio destruye el 50% del código (45% de las pruebas unitarias y 5% del código de producción). La tienda laxa (10% de pruebas unitarias / 90% de código de producción) tiene un producto con 18 características, ninguna de las cuales funciona muy bien. Su cliente completamente renova los requisitos para 4 de sus características. Aunque el cambio es 4 veces más grande, solo la mitad de la base de códigos se destruye (~ 25% = ~ 4,4% de pruebas de unidades + 20% del código de producción).

Mi punto es que tienes que comunicar que entiendes ese equilibrio entre muy poca y demasiada unidad de pruebas, esencialmente que has pensado en ambos lados del problema. Si puede convencer a sus colegas y / o a su administración de eso, ganará credibilidad y tal vez tenga una mejor oportunidad de conquistarlos.


69



He jugado varias veces con pruebas unitarias, y todavía estoy convencido de que vale la pena el esfuerzo dada mi situación.

Desarrollo sitios web, donde gran parte de la lógica implica la creación, recuperación o actualización de datos en la base de datos. Cuando he intentado "burlarme" de la base de datos para realizar pruebas de unidades, se ha vuelto muy complicado y parece un tanto inútil.

Cuando escribí pruebas unitarias sobre lógica de negocios, en realidad nunca me ha ayudado a largo plazo. Debido a que trabajo principalmente solo en proyectos, tiendo a saber intuitivamente qué áreas de código pueden verse afectadas por algo en lo que estoy trabajando, y pruebo estas áreas manualmente. Quiero ofrecerle una solución a mi cliente lo más rápido posible, y las pruebas unitarias a menudo parecen una pérdida de tiempo. Enumero pruebas manuales y las reviso yo mismo, marcándolas mientras voy.

Puedo ver que puede ser beneficioso cuando un equipo de desarrolladores está trabajando en un proyecto y actualizando el código de cada uno, pero aun así creo que si los desarrolladores son de alta calidad, una buena comunicación y un código bien escrito deberían ser suficientes. .


38



Una gran ventaja de las pruebas unitarias es que sirven como documentación de cómo debe comportarse el código. Las buenas pruebas son como una implementación de referencia, y los compañeros de equipo pueden verlas para ver cómo integrar su código con el suyo.


31



Las pruebas unitarias bien valen la inversión inicial. Desde que empecé a usar pruebas unitarias hace un par de años, he encontrado algunos beneficios reales:

  • pruebas de regresión elimina el miedo a haciendo cambios al código (no hay nada como el cálido resplandor de ver el código trabajar o explotar cada vez que un cambio es hecho)
  • ejemplos de código ejecutable para otros miembros del equipo (y usted mismo en seis meses ...)
  • despiadado refactorización - Esto es increíblemente gratificante, pruébalo!

Los fragmentos de código pueden ser de gran ayuda para reducir los gastos generales de creación de pruebas. No es difícil crear fragmentos que permitan la creación de un esquema de clase y un accesorio de prueba de unidad asociado en segundos.


26



¡Debes probar lo menos posible!

lo que significa que debes escribir suficientes pruebas unitarias para revelar la intención. Esto a menudo se pasa por alto. Las pruebas unitarias le cuestan Si realiza cambios y tiene que cambiar las pruebas, será menos ágil. Mantenga las pruebas unitarias cortas y dulces. Entonces tienen mucho valor.

Demasiado a menudo veo muchas pruebas que nunca se romperán, son grandes y torpes y no ofrecen mucho valor, simplemente terminan por desacelerarte.


25



No vi esto en ninguna de las otras respuestas, pero una cosa que noté es que Podría depurar mucho más rápido. No necesita profundizar en su aplicación con solo la secuencia correcta de pasos para llegar al código que está arreglando, solo para descubrir que ha cometido un error booleano y debe volver a hacerlo todo. Con una prueba de unidad, puede simplemente ingresar directamente al código que está depurando.


23



[Tengo un punto para hacer que no puedo ver arriba]

"Todos los exámenes de la unidad, no necesariamente se dan cuenta - HECHO"

Piénselo, usted escribe una función para tal vez analizar una cadena y eliminar nuevos caracteres de línea. Como desarrollador novato, puede ejecutar algunos casos a través de la línea de comandos implementándolo en Main () o puede combinar una interfaz visual con un botón, asociar su función a un par de cuadros de texto y un botón y ver lo que pasa.

Se trata de pruebas unitarias, básicas y mal integradas, pero se prueba el código para algunos casos.

Escribes algo más complejo. Arroja errores cuando lanza algunos casos (pruebas unitarias) y depura en el código y rastrea. Miras los valores a medida que avanzas y decides si están correctos o equivocados. Esta es la prueba unitaria en cierto grado.

Las pruebas unitarias aquí realmente toman ese comportamiento, formalizándolo en un patrón estructurado y guardándolo para que pueda volver a ejecutar fácilmente esas pruebas. Si escribe un caso de prueba unitaria "adecuada" en lugar de probarlo manualmente, lleva la misma cantidad de tiempo, o tal vez menos a medida que tenga experiencia, y lo tiene disponible para repetir una y otra vez


21