it-swarm-es.tech

Desventajas del desarrollo de prueba?

¿Qué pierdo al adoptar un diseño basado en pruebas?

Lista solo los negativos; No enumere los beneficios escritos en forma negativa.

191
IanL

Varias desventajas (y no estoy diciendo que no haya beneficios, especialmente al escribir los cimientos de un proyecto, le ahorraría mucho tiempo al final):

  • Gran inversión de tiempo. Para el caso simple, pierde aproximadamente el 20% de la implementación real, pero para los casos complicados, pierde mucho más.
  • Complejidad adicional. Para casos complejos, sus casos de prueba son más difíciles de calcular, sugiero en casos como este, que intenten usar un código de referencia automático que se ejecutará en paralelo en la versión de depuración/prueba, en lugar de la prueba unitaria de los casos más simples.
  • Impactos de diseño. A veces el diseño no está claro al principio y evoluciona a medida que avanza, lo que obligará a rehacer su prueba, lo que generará una gran pérdida de tiempo. Yo sugeriría posponer las pruebas unitarias en este caso hasta que tenga una idea del diseño en mente.
  • Ajustes continuos. Para las estructuras de datos y los algoritmos de caja negra, las pruebas unitarias serían perfectas, pero para los algoritmos que tienden a ser modificados, modificados o ajustados, esto puede causar una gran inversión de tiempo que uno podría afirmar que no está justificado. Por lo tanto, úselo cuando crea que realmente se ajusta al sistema y no obligue al diseño a ajustarse a TDD.
124
Adi

Si desea hacer un TDD "real" (lea: pruebe primero con los pasos de refactor rojo, verde), entonces también debe comenzar a usar simulacros/talones, cuando desee probar los puntos de integración.

Cuando empiece a usar simulacros, después de un tiempo, deseará comenzar a usar la inyección de dependencia (DI) y un contenedor de Inversión de control (IOC). Para hacer eso necesitas usar interfaces para todo (que tienen muchos escollos).

Al final del día, tienes que escribir un código mucho más, que si solo lo haces de la "manera antigua". En lugar de solo una clase de cliente, también necesita escribir una interfaz, una clase simulada, alguna configuración de IoC y algunas pruebas.

Y recuerde que el código de prueba también se debe mantener y cuidar. Las pruebas deben ser tan legibles como todo lo demás y se necesita tiempo para escribir un buen código.

Muchos desarrolladores no entienden muy bien cómo hacer todo esto "de la manera correcta". Pero como todo el mundo les dice que TDD es la única forma verdadera de desarrollar software, solo intentan lo mejor que pueden.

Es mucho más difícil de lo que uno podría pensar. A menudo, los proyectos realizados con TDD terminan con una gran cantidad de código que nadie realmente entiende. Las pruebas unitarias a menudo prueban la cosa incorrecta, la manera incorrecta. Y nadie está de acuerdo en cómo debería ser una buena prueba, ni siquiera los llamados gurús.

Todas estas pruebas hacen que sea mucho más difícil "cambiar" (al contrario de refactorizar) el comportamiento de su sistema y los cambios simples se vuelven demasiado difíciles y consumen mucho tiempo.

Si lees la literatura de TDD, siempre hay algunos ejemplos muy buenos, pero a menudo en las aplicaciones de la vida real, debes tener una interfaz de usuario y una base de datos. Aquí es donde TDD se pone realmente difícil, y la mayoría de las fuentes no ofrecen buenas respuestas. Y si lo hacen, siempre implica más abstracciones: objetos simulados, programación a una interfaz, patrones MVC/MVP, etc., que de nuevo requieren mucho conocimiento, y ... tienes que escribir aún más código.

Así que tenga cuidado ... si no tiene un equipo entusiasta y al menos un desarrollador experimentado que sepa escribir buenas pruebas y también sepa algunas cosas sobre la buena arquitectura, realmente tiene que pensárselo dos veces antes de ir por el camino de TDD .

184
Thomas Jespersen

Cuando llegue al punto en el que tiene una gran cantidad de pruebas, cambiar el sistema puede requerir volver a escribir algunas o todas sus pruebas, dependiendo de cuáles hayan sido invalidadas por los cambios. Esto podría convertir una modificación relativamente rápida en una muy lenta.

Además, puede comenzar a tomar decisiones de diseño basadas más en TDD que en los buenos directores de diseño. Si bien es posible que haya tenido una solución muy simple y fácil que es imposible de probar de la manera que exige TDD, ahora tiene un sistema mucho más complejo que en realidad es más propenso a cometer errores.

66
Eric Z Beard

Creo que el mayor problema para mí es la enorme pérdida de tiempo que lleva "meterse". Todavía estoy muy al comienzo de mi viaje con TDD (vea mi blog para ver las actualizaciones de mis aventuras de prueba si está interesado) y literalmente pasé horas empezando.

Se necesita mucho tiempo para poner a tu cerebro en "modo de prueba" y escribir "código verificable" es una habilidad en sí misma.

TBH, discrepo respetuosamente con los comentarios de Jason Cohen sobre cómo hacer públicos los métodos privados, no se trata de eso. No he hecho más métodos públicos en mi nueva forma de trabajar que antes . Sin embargo, sí implica cambios en la arquitectura y le permite "conectar en caliente" módulos de código para que todo lo demás sea más fácil de probar. Debería no hacer que los elementos internos de su código sean más accesibles para hacer esto. De lo contrario, volvemos a la cuadratura con todo siendo público, ¿dónde está la encapsulación en eso?

Entonces, (IMO) en pocas palabras:

  • La cantidad de tiempo que se tarda en pensar (es decir, en realidad grok'ing testing).
  • El nuevo conocimiento requerido de saber escribir código verificable.
  • Comprender los cambios arquitectónicos necesarios para hacer que el código sea verificable.
  • Aumentar tu habilidad de "TDD-Coder" mientras intentas mejorar todas las otras habilidades requeridas para nuestro glorioso oficio de programación :)
  • Organice su base de código para incluir el código de prueba sin dañar su código de producción.

PD: Si desea enlaces a positivos, le he preguntado y respondido varias preguntas, revise mi perfil .

54
Rob Cooper

En los pocos años que llevo practicando Test Driven Development, debo decir que las mayores desventajas son:

Venderlo a la dirección.

TDD se hace mejor en pares. Por un lado, es difícil resistir la tentación de simplemente escribir la implementación cuandoSABEcómo escribir una declaración si/else . Pero un par te mantendrá en la tarea porque tú lo mantienes en la tarea. Lamentablemente, muchas empresas/gerentes no creen que este sea un buen uso de los recursos. ¿Por qué pagar para que dos personas escriban una función, cuando tengo dos funciones que se deben hacer al mismo tiempo?

Venderlo a otros desarrolladores.

Algunas personas simplemente no tienen la paciencia para escribir pruebas unitarias. Algunos están muy orgullosos de su trabajo. O, a algunos les gusta ver métodos/funciones complicadas desangrándose al final de la pantalla. TDD no es para todos, pero realmente lo deseo. Haría mucho más fácil mantener las cosas para aquellas almas pobres que heredan el código.

Mantener el código de prueba junto con su código de producción

Idealmente, sus pruebas solo se interrumpirán cuando tome una decisión errónea sobre el código. Es decir, pensaste que el sistema funcionaba de una manera, y resultó que no. Al romper una prueba, o un (pequeño) conjunto de pruebas, esto es realmente una buena noticia. Usted sabe exactamente cómo su nuevo código afectará al sistema. Sin embargo, si sus pruebas están mal escritas, estrechamente relacionadas o, peor aún, generadas ( tos VS Prueba), el mantenimiento de sus pruebas puede convertirse rápidamente en un coro. Y, después de que suficientes pruebas comiencen a generar más trabajo que el valor percibido que están creando, entonces las pruebas serán lo primero que se eliminará cuando los programas se compriman (por ejemplo, llega al momento crítico)

Escribiendo pruebas para que cubras todo (100% de cobertura de código)

De manera ideal, nuevamente, si se adhiere a la metodología, su código se probará al 100% de manera predeterminada. Normalmente, pensé, termino con una cobertura de código de más del 90%. Esto suele suceder cuando tengo alguna arquitectura de estilo de plantilla, y se prueba la base, y trato de cortar esquinas y no probar las personalizaciones de la plantilla. Además, he encontrado que cuando me encuentro con una nueva barrera que no había encontrado anteriormente, tengo una curva de aprendizaje para probarla. Admito que escribí algunas líneas de código a la manera antigua skool, pero realmente me gusta tener ese 100%. (Supongo que era un gran triunfador en la escuela, er skool).

Sin embargo, con eso diría que los beneficios de TDD superan con creces los aspectos negativos de la simple idea de que si puede lograr un buen conjunto de pruebas que cubran su aplicación pero no sean tan frágiles que un cambio las rompa todas, podrá seguir agregando nuevas funciones el día 300 de su proyecto como lo hizo el día 1. Esto no sucede con todos los que prueban TDD pensando que es una bala mágica para todo su código cargado de errores, por lo que piensan que puede No trabajes, punto.

Personalmente, descubrí que con TDD, escribo un código más simple, dedico menos tiempo a debatir si una solución de código en particular funcionará o no, y no temo cambiar ninguna línea de código que no cumpla con los criterios establecidos por el equipo.

TDD es una disciplina difícil de dominar, he estado trabajando durante algunos años y todavía aprendo nuevas técnicas de prueba todo el tiempo. Es una gran inversión de tiempo por adelantado, pero, a largo plazo, su sostenibilidad será mucho mayor que si no tuviera pruebas de unidad automatizadas. Ahora, si solo mis jefes pudieran resolver esto.

49
casademora

En su primer proyecto TDD hay dos grandes pérdidas, tiempo y libertad personal

Pierdes tiempo porque:

  • La creación de un conjunto completo, refactorizado y mantenible de pruebas unitarias y de aceptación agrega mayor tiempo a la primera iteración del proyecto. Este puede ser un ahorro de tiempo a largo plazo, pero igualmente puede ser un tiempo que no tiene que perder.
  • Debe elegir y convertirse en experto en un conjunto de herramientas básicas. Una herramienta de prueba de unidad debe complementarse con algún tipo de marco de burla y ambos deben formar parte de su sistema de compilación automatizado. También desea seleccionar y generar métricas adecuadas.

Pierdes la libertad personal porque:

  • TDD es una forma muy disciplinada de escribir código que tiende a rozar contra los que están en la parte superior e inferior de la escala de habilidades. Escribir siempre el código de producción de una manera determinada y someter su trabajo a una revisión por pares continua puede asustar a sus peores y mejores desarrolladores e incluso llevar a la pérdida de personal.
  • La mayoría de los métodos ágiles que incorporan TDD requieren que hables con el cliente continuamente sobre lo que te propones lograr (en esta historia/día/lo que sea) y cuáles son las compensaciones. Una vez más, esto no es una taza de té para todos, tanto para los desarrolladores como para los clientes.

Espero que esto ayude

24
Garth Gilmour

TDD requiere que planifiques cómo funcionarán tus clases antes de escribir código para aprobar esas pruebas. Esto es tanto un plus como un menos.

Me resulta difícil escribir pruebas en un "vacío", antes de que se haya escrito cualquier código. En mi experiencia, tiendo a tropezar con mis exámenes cada vez que inevitablemente pienso en algo mientras escribo mis clases que olvidé al escribir mis exámenes iniciales. Entonces es hora de no solo refactorizar mis clases, sino TAMBIÉN mis pruebas. Repita esto tres o cuatro veces y puede ser frustrante.

Prefiero escribir un borrador de mis clases primero, luego escribir (y mantener) una batería de pruebas unitarias. Después de tener un borrador, TDD funciona bien para mí. Por ejemplo, si se reporta un error, escribiré una prueba para explotar ese error y luego corregiré el código para que la prueba pase.

14
Chrass

La creación de prototipos puede ser muy difícil con TDD: cuando no está seguro de qué camino tomará para encontrar una solución, escribir las pruebas por adelantado puede ser difícil (aparte de las muy amplias). Esto puede ser un dolor.

Honestamente, no creo que para el "desarrollo central" para la gran mayoría de los proyectos haya un verdadero inconveniente; se ha criticado mucho más de lo que debería ser, generalmente por personas que creen que su código es lo suficientemente bueno como para no necesitar pruebas (nunca lo es) y personas que simplemente no pueden molestarse en escribirlas.

12
Calum

Bueno, y este estiramiento, necesitas depurar tus pruebas. Además, hay un cierto costo a tiempo para escribir las pruebas, aunque la mayoría de las personas están de acuerdo en que es una inversión inicial que se amortiza durante la vida útil de la aplicación, tanto en la depuración como en la estabilidad.

Sin embargo, el mayor problema que he tenido personalmente con este problema es mejorar la disciplina para escribir las pruebas. En un equipo, especialmente un equipo establecido, puede ser difícil convencerlos de que el tiempo empleado vale la pena.

9
Tim Sullivan

La desventaja de TDD es que, por lo general, está estrechamente asociada con la metodología 'Agile', que otorga no importancia a la documentación de un sistema, más bien a la comprensión de por qué una prueba "debería" devolver un valor específico en lugar de cualquier otra opción. Solo en la cabeza del desarrollador.

Tan pronto como el desarrollador abandona u olvida la razón por la que la prueba devuelve un valor específico y no otro, estás equivocado. TDD está bien SI está documentado adecuadamente y está rodeado de documentación legible por humanos (es decir, un gerente de pelo puntiagudo) que se puede consultar en 5 años cuando el mundo cambia y su aplicación también necesita hacerlo.

Cuando hablo de documentación, esto no es una propaganda en el código, se trata de un escrito oficial que existe de manera externa a la aplicación, como casos de uso e información de antecedentes a los que pueden referirse los gerentes, abogados y los pobres que tienen que actualizar Su código en 2011.

7
Ron McMahon

Si sus pruebas no son muy exhaustivas, podría caer en una falsa sensación de que "todo funciona" simplemente porque las pruebas pasan. Teóricamente si sus pruebas pasan, el código está funcionando; pero si pudiéramos escribir código perfectamente la primera vez no necesitaríamos pruebas. La moraleja aquí es asegurarse de hacer una revisión de la cordura por su cuenta antes de llamar a algo completo, no solo confíe en las pruebas.

En esa nota, si su comprobación de validez encuentra algo que no se ha probado, asegúrese de volver y escribir una prueba para ello.

7
Aaron Lee

He encontrado varias situaciones en las que el TDD me vuelve loco. Para nombrar algunos:

  • Mantenimiento de caso de prueba:

    Si está en una gran empresa, hay muchas posibilidades de que no tenga que escribir los casos de prueba usted mismo o que al menos la mayoría de ellos estén escritos por otra persona cuando ingrese a la empresa. Las características de una aplicación cambian de vez en cuando y si no tiene un sistema implementado, como HP Quality Center, para rastrearlas, se volverá loco en poco tiempo.

    Esto también significa que los nuevos miembros del equipo tardarán bastante tiempo en captar lo que está pasando con los casos de prueba. A su vez, esto puede traducirse en más dinero necesario.

  • Automatización de pruebas de complejidad:

    Si automatiza algunos o todos los casos de prueba en scripts de prueba ejecutables por máquina, tendrá que asegurarse de que estos scripts de prueba estén sincronizados con sus casos de prueba manuales correspondientes y en línea con los cambios de la aplicación.

    Además, dedicará tiempo a depurar los códigos que lo ayudan a detectar errores. En mi opinión, la mayoría de estos errores provienen de la falla del equipo de pruebas para reflejar los cambios de la aplicación en el script de prueba de automatización. Los cambios en la lógica empresarial, la GUI y otras cosas internas pueden hacer que sus scripts dejen de ejecutarse o ejecutarse de forma poco fiable. A veces los cambios son muy sutiles y difíciles de detectar. Una vez que todos mis scripts informaron un error porque basaron su cálculo en la información de la tabla 1, mientras que la tabla 1 ahora era la tabla 2 (porque alguien cambió el nombre de los objetos de la tabla en el código de la aplicación).

6
Martin08

El mayor problema son las personas que no saben cómo escribir pruebas unitarias adecuadas. Escriben pruebas que dependen unas de otras (y funcionan muy bien con Ant, pero de repente fallan cuando las ejecuto desde Eclipse, simplemente porque se ejecutan en un orden diferente). Escriben pruebas que no prueban nada en particular; solo depuran el código, verifican el resultado y lo convierten en prueba, llamándolo "prueba1". Amplían el alcance de las clases y los métodos, solo porque será más fácil escribir pruebas unitarias para ellos. El código de las pruebas unitarias es terrible, con todos los problemas de programación clásicos (acoplamiento pesado, métodos de 500 líneas de longitud, valores codificados, duplicación de códigos) y es un infierno de mantener. Por alguna extraña razón, las personas consideran las pruebas de unidad como algo inferior al código "real", y no les importa su calidad en absoluto. :-(

5
rmaruszewski

Se pierde mucho tiempo dedicado a escribir pruebas. Por supuesto, esto podría salvarse al final del proyecto al detectar errores más rápido.

4
Joel Coehoorn

Pierde la capacidad de decir que está "listo" antes de probar todo su código.

Pierde la capacidad de escribir cientos o miles de líneas de código antes de ejecutarlo.

Pierdes la oportunidad de aprender a través de la depuración.

Pierde la flexibilidad para enviar el código del que no está seguro.

Pierdes la libertad de acoplar firmemente tus módulos.

Se pierde la opción de omitir la escritura de documentación de diseño de bajo nivel.

Pierdes la estabilidad que viene con el código que todos temen cambiar.

Se pierde el título de "hacker".

4
Uncle Bob

El mayor inconveniente es que si realmente quieres hacer TDD correctamente, tendrás que fallar mucho antes de tener éxito. Dado el número de empresas de software que funcionan (en dólares por KLOC), eventualmente será despedido. Incluso si su código es más rápido, más limpio, más fácil de mantener y tiene menos errores.

Si está trabajando en una empresa que le paga por los KLOC (o los requisitos implementados, incluso si no están probados), manténgase alejado de TDD (o revisiones de código, programación de pares, integración continua, etc., etc.).

3
Vasco Duarte

Reenfocarse en los requisitos difíciles e imprevistos es la pesadilla constante del programador. El desarrollo guiado por pruebas lo obliga a centrarse en los requisitos mundanos ya conocidos y limita su desarrollo a lo que ya se ha imaginado.

Piénsalo, es probable que termines diseñando para casos de prueba específicos, por lo que no serás creativo y empezarás a pensar que "sería genial si el usuario pudiera hacer X, Y y Z". Por lo tanto, cuando ese usuario comienza a entusiasmarse con los posibles requisitos de enfriamiento X, Y y Z, su diseño puede estar demasiado enfocado en los casos de prueba ya especificados, y será difícil de ajustar.

Esto, por supuesto, es una espada de doble filo. Si pasa todo el tiempo diseñando para cada X, Y y Z concebible e imaginable que un usuario pueda desear, inevitablemente nunca completará nada. Si completas algo, será imposible que alguien (incluyéndote a ti mismo) tenga alguna idea de lo que estás haciendo en tu código/diseño.

2
Doug T.

Segundo la respuesta sobre el tiempo de desarrollo inicial. También pierde la capacidad de trabajar cómodamente sin la seguridad de las pruebas. También me han descrito como un manillar TDD, por lo que podrías perder algunos amigos;)

2
Chris Canal

Se percibe como más lento. A largo plazo, eso no es cierto en términos de la pena que le ahorrará en el futuro, pero terminará escribiendo más código, por lo que podría pasar el tiempo en "probar y no programar". Es un argumento defectuoso, pero lo preguntaste!

1
MarcE

Puede ser difícil y llevar mucho tiempo escribir pruebas para datos "aleatorios" como XML-feeds y bases de datos (no es tan difícil). He pasado algún tiempo últimamente trabajando con feeds de datos meteorológicos. Es bastante confuso escribir pruebas para eso, al menos porque no tengo demasiada experiencia con TDD.

1
Vargen

Se necesita algo de tiempo para comenzar y algo más para comenzar a hacerlo en un proyecto, pero ... Siempre lamento no haber realizado un enfoque de prueba cuando encuentro errores tontos que una prueba automática podría haber encontrado muy rápido. Además, TDD mejora la calidad del código.

1
aerlijman

Buenas respuestas a todos. Me gustaría añadir algunas formas de evitar el lado oscuro de TDD:

  • He escrito aplicaciones para hacer su propia autoprueba aleatoria. El problema con la escritura de pruebas específicas es que si usted escribe muchas de ellas, solo cubren los casos en los que piensa. Los generadores de pruebas aleatorias encuentran problemas que no se te ocurrieron.

  • El concepto completo de lotes de pruebas unitarias implica que tiene componentes que pueden entrar en estados no válidos, como estructuras de datos complejas. Si se mantiene alejado de estructuras de datos complejas, hay mucho menos que probar.

  • En la medida en que su aplicación lo permita, sea tímido con respecto al diseño que se basa en el orden correcto de notificaciones, eventos y efectos secundarios. Esos pueden ser fácilmente caídos o revueltos, por lo que necesitan muchas pruebas.

1
Mike Dunlavey
  • las pruebas unitarias son más código para escribir, por lo tanto, un mayor costo inicial de desarrollo
  • es mas codigo mantener
  • aprendizaje adicional requerido
1
Bob Dizzle

Perderás clases grandes con múltiples responsabilidades. También es probable que pierda grandes métodos con múltiples responsabilidades. Puede perder cierta capacidad de refactorizar, pero también perderá parte de la necesidad de refactorizar.

Jason Cohen dijo algo como: TDD requiere una cierta organización para su código. Esto podría ser arquitectónicamente incorrecto; por ejemplo, dado que los métodos privados no pueden llamarse fuera de una clase, debe hacer que los métodos no sean privados para que sean verificables.

Digo que esto indica una abstracción perdida: si el código privado realmente necesita ser probado, probablemente debería estar en una clase separada.

Dave Mann

1
Dave Mann

Tienes que escribir las aplicaciones de una manera diferente: una que las haga verificables. Te sorprendería lo difícil que es esto al principio.

Algunas personas encuentran el concepto de pensar en lo que van a escribir antes de escribirlo demasiado. Conceptos como burlarse pueden ser difíciles para algunos también. TDD en aplicaciones heredadas puede ser muy difícil si no fueron diseñadas para pruebas. TDD en torno a marcos que no son compatibles con TDD también puede ser una lucha.

TDD es una habilidad para que los desarrolladores junior puedan tener problemas al principio (principalmente porque no se les ha enseñado a trabajar de esta manera).

En general, aunque las desventajas se resuelven a medida que las personas se vuelven hábiles y terminas abstrayendo el código 'maloliente' y tienes un sistema más estable.

1
Peter Gillard-Moss

La persona que enseñó a mi equipo el desarrollo ágil no creía en la planificación, usted solo escribió tanto para el requisito más pequeño.

Su lema era refactor, refactor, refactor. Llegué a entender que refactor significaba "no planear con anticipación".

0
Jack B Nimble

Permítame agregar que si aplica los principios BDD a un proyecto TDD, puede aliviar algunos de los principales inconvenientes que se enumeran aquí (confusión, malentendidos, etc.). Si no está familiarizado con la BDD, debería leer la introducción de Dan North. Surgió el concepto en respuesta a algunos de los problemas que surgieron de la aplicación de TDD en el lugar de trabajo. La introducción de Dan a BDD se puede encontrar aquí .

Solo hago esta sugerencia porque BDD aborda algunos de estos aspectos negativos y actúa como un punto muerto. Usted querrá considerar esto cuando recoja sus comentarios.

0
Kilhoffer

TDD requiere una cierta organización para su código. Esto puede ser ineficiente o difícil de leer. O incluso arquitectónicamente incorrecto; por ejemplo, dado que los métodos private no pueden llamarse fuera de una clase, debe hacer que los métodos no sean privados para que sean verificables, lo que es incorrecto.

Cuando el código cambia, también tienes que cambiar las pruebas. Con la refactorización esto puede ser una gran cantidad de trabajo extra.

0
Jason Cohen

Debe asegurarse de que sus pruebas estén siempre actualizadas, en el momento en que comience a ignorar las luces rojas es el momento en que las pruebas pierden su significado.

También tiene que asegurarse de que las pruebas sean exhaustivas, o en el momento en que aparece un gran error, el tipo de administración congestionado que finalmente convenció para permitirle dedicar tiempo a escribir más código se quejará.

0
qui