¿Desventajas del desarrollo impulsado por pruebas? [cerrado]


192

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

Enumere solo los negativos; no enumere los beneficios escritos en forma negativa.


Agregué una respuesta que indica que BDD puede aliviar algunos de estos aspectos negativos. Le insto a que considere este factor al recopilar su entrada negativa, ya que parte de ella puede eliminarse y dejar de considerarse negativa.
Kilhoffer

25
Para aclaraciones, no estoy en contra o a favor. Estoy tratando de tomar una decisión informada sobre el asunto, pero la mayoría de las personas que abogan por TDD no entienden o no admiten los aspectos negativos.
IanL

1
El título menciona "Test Driven Development", pero el cuerpo de la pregunta menciona "Test Driven Design". ¿De cuál de los dos es esta pregunta? Hay diferencias importantes, pero sutiles entre los dos. El diseño basado en pruebas consiste en dejar que las pruebas conduzcan el diseño del software. El desarrollo basado en pruebas generalmente se asocia con la escritura de pruebas antes del código de producción (pero no necesariamente dejando que las pruebas influyan en el diseño).
Jim Hurne

3
TDD es una jaula que detiene la creatividad del desarrollador.
Lewis

13
por favor deja de cerrar preguntas importantes, djesus
Casper Leon Nielsen

Respuestas:


129

Varias desventajas (y no estoy afirmando que no haya beneficios, especialmente al escribir la base de un proyecto, 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, sugeriría en casos como ese que intente utilizar un código de referencia automático que se ejecutará en paralelo en la versión de depuración / ejecución de 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; esto lo obligará a rehacer su prueba, lo que generará una gran pérdida de tiempo. Sugeriría posponer las pruebas unitarias en este caso hasta que tenga alguna idea del diseño en mente.
  • Ajustes continuos. Para las estructuras de datos y los algoritmos de recuadro negro, las pruebas unitarias serían perfectas, pero para los algoritmos que tienden a modificarse, ajustarse o ajustarse, esto puede causar una gran inversión de tiempo que uno podría afirmar que no está justificado. Así que úselo cuando piense que realmente se ajusta al sistema y no fuerce el diseño para que se ajuste al TDD.

77
El punto principal (4) es: cualquier sistema que no esté bien definido y que pueda seguir cambiando para adaptarse a un comportamiento visual en evolución, diferentes especificaciones de inteligencia artificial, algoritmos de comportamiento, etc. causará una gran inversión de tiempo en definiciones de prueba repetidas ya que mantenemos en cambiar los resultados deseados de la prueba.
Adi

12
Es cierto, pero ¿no sería lo mismo sin TDD? Sin él, tendrías que hacer más pruebas manuales, que sufrirían el mismo problema.
sleske

50
¿La "inversión a lo grande" no le ahorrará tiempo más adelante mientras desarrolla su solución? ¿Especialmente con uno complejo? Supongo que debería ahorrarte tiempo. No pensar en la fase de mantenimiento, donde pequeños cambios pueden dañar fácilmente el sistema. ( o tal vez solo estoy siendo ingenuo acerca de las pruebas de unidad + regresión que previenen futuros errores )
Robert Koritnik

66
Sergio / Robert, estoy muy a favor de realizar pruebas unitarias para sistemas genéricos y definitivamente para componentes que representan la base de los sistemas. Dicho esto, agregaría que es necesario diferenciar entre estos casos y simplificar demasiado la vida real al tratar de afirmar que cada sistema puede ser tratado de esta manera. No todos los sistemas pueden generalizarse y simplificarse para las pruebas unitarias y si intenta forzar la naturaleza de las pruebas unitarias en dichos sistemas, puede terminar fácilmente pasando mucho más tiempo corrigiendo las pruebas unitarias que realmente probando resultados reales.
Adi

3
@Adi: Creo que te equivocas. En mi opinión, cada sistema se puede probar de esa manera, solo es cuestión de autodisciplina.
BlueLettuce16

189

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

Cuando comience a usar simulacros, después de un tiempo, querrá comenzar a usar la Inyección de dependencia (DI) y un contenedor de Inversión de control (IoC). Para hacer eso, necesita usar interfaces para todo (que tienen muchos escollos).

Al final del día, tienes que escribir mucho más código, que si lo hicieras "a la antigua usanza". 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 debe mantenerse y cuidarse. Las pruebas deben ser tan legibles como todo lo demás y lleva tiempo escribir un buen código.

Muchos desarrolladores no entienden cómo hacer todo esto "de la manera correcta". Pero debido a que todos les dicen que TDD es la única forma verdadera de desarrollar software, simplemente 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 entiende realmente. 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 esas pruebas hacen que sea mucho más difícil "cambiar" (opuesto a la refactorización) el comportamiento de su sistema y los cambios simples simplemente se vuelven demasiado difíciles y requieren mucho tiempo.

Si lee la literatura de TDD, siempre hay algunos ejemplos muy buenos, pero a menudo en las aplicaciones de la vida real, debe 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: simulacros de objetos, programación a una interfaz, patrones MVC / MVP, etc., que nuevamente 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 cómo escribir buenas pruebas y también sabe algunas cosas sobre una buena arquitectura, realmente tiene que pensar dos veces antes de seguir el camino TDD .


77
Usando herramientas como Pex & Moles , puede evitar fácilmente escribir interfaces para cada pequeña cosa. Los lunares te ayudarán enormemente con eso.
Robert Koritnik el

24
Parece una crítica de las pruebas unitarias y la programación orientada a objetos, no TDD.
plmaheu

55
Realmente correcto ** prueba de unidad ** - no solo TDD - requiere simulacros / trozos. Y programar contra una interfaz es a menudo una buena idea, lo mismo ocurre con los patrones. Si mezclas UI y lógica, te lo pasarás mal. Si tiene que probar la interacción de la base de datos, aún puede burlarse de su DAO para las pruebas unitarias y usar lo real para una prueba de integración.
TheMorph

1
Estoy de acuerdo con el hecho de que una niebla tiene conocimiento del diseño y las pruebas antes de saltar a tdd. Esto es crítico en proyectos con nuevos empleados, ya que son nuevos para ambos.
Hitesh Sahu

vote por la Sabiduría
sabsab

66

Cuando llegue al punto en el que tiene una gran cantidad de pruebas, cambiar el sistema puede requerir reescribir algunas o todas sus pruebas, dependiendo de cuáles fueron 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 principios de diseño realmente buenos. Si bien puede haber tenido una solución muy simple y fácil que es imposible de probar la forma en que TDD lo exige, ahora tiene un sistema mucho más complejo que en realidad es más propenso a errores.


3
Definitivamente puede ser un problema, sin embargo, encuentro que estoy viendo una diferencia notable en cuánto me afecta esto. Todo se reduce a "escribir código comprobable", supongo.
Rob Cooper

2
Scott, el ejemplo que suelo dar es un SqlDataSource incrustado en una página ASPX. No puede automatizar una prueba para eso. Es simple y hace el trabajo, con solo 1 archivo. El componente comprobable es el objeto SqlDataSource de MSFT, y eso ya está hecho para nosotros. No es necesario que hagamos más.
Eric Z Beard

8
+1 "puede comenzar a tomar decisiones de diseño basadas más en TDD que en principios de diseño realmente buenos", el mayor escollo de TDD IMHO.
András Szepesházi

2
@ScottSaad El problema de la OMI es que el diseño debe describirse primero y luego debe validarse escribiendo pruebas y corregirse si es necesario. He visto numerosos casos en que las personas estaban poniendo en peligro un buen diseño solo para poder escribir una prueba. Como resultado, la mayoría del sistema estaba cubierto por pruebas, pero el diseño era realmente feo. Creo que esto sucede porque TDD se empuja a las masas como metodología muy sencilla con la siguiente error : if part of the system is covered by tests and they pass, then everything is fine (including design).
Yuriy Nakonechnyy

3
@Yura: Es interesante lo que dices que la gente estaba poniendo en peligro un buen diseño solo para poder escribir pruebas. En mi opinión, si hubiera un buen diseño, no sería necesario ponerlo en peligro. Una vez vi un proyecto así y la base de código fue una pesadilla, pero la gente pensó lo mismo: que el diseño es excelente. Estoy de acuerdo solo con la parte de que TDD es empujado a las masas como una metodología muy simple, sin embargo, es exactamente lo contrario. En mi opinión, cuando el código está bien diseñado, entonces cuando haces un pequeño cambio, no hay posibilidad de frenar todas las pruebas o una gran cantidad de ellas.
BlueLettuce16

54

Creo que el mayor problema para mí es la enorme pérdida de tiempo que lleva "entrar". 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 he pasado horas comenzando.

Lleva mucho tiempo poner su cerebro en "modo de prueba" y escribir "código comprobable" es una habilidad en sí misma.

TBH, estoy respetuosamente en desacuerdo con los comentarios de Jason Cohen sobre hacer públicos los métodos privados, de eso no se trata. No he hecho más métodos públicos en mi nueva forma de trabajar que antes . Sin embargo, sí implica cambios arquitectónicos y le permite "conectar en caliente" módulos de código para hacer que todo lo demás sea más fácil de probar. Usted debe no estar haciendo la parte interna de su código sea más accesible para hacer esto. De lo contrario, volvemos al punto de partida con todo siendo público, ¿dónde está la encapsulación en eso?

Entonces, (OMI) en pocas palabras:

  • La cantidad de tiempo necesario para pensar (es decir, realmente pruebas de grok'ing ).
  • El nuevo conocimiento requerido para saber cómo escribir código comprobable.
  • Comprender los cambios arquitectónicos necesarios para que el código sea comprobable.
  • Aumenta tu habilidad de "TDD-Coder" mientras intentas mejorar todas las otras habilidades requeridas para nuestra gloriosa habilidad de programación :)
  • Organice su base de código para incluir código de prueba sin atornillar su código de producción.

PD: Si desea enlaces a aspectos positivos, le he preguntado y respondido varias preguntas al respecto, consulte mi perfil .


1
Lamentablemente, la primera respuesta razonable que vi ...
Daniel C. Sobral

55
Muy práctico y simple respuesta - 1 para el "ajuste de la Mente" parte
ha9u63ar

50

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

Venderlo a la gerencia

TDD se realiza mejor en parejas. Por un lado, es difícil resistir el impulso de simplemente escribir la implementación cuando SABES cómo escribir una declaración if / else . Pero un par te mantendrá en la tarea porque tú lo mantienes en la tarea. Lamentablemente, muchas compañías / gerentes no piensan 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 deben hacerse al mismo tiempo?

Venderlo a otros desarrolladores.

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

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

Idealmente, sus pruebas solo se romperán cuando tome una mala decisión de código. Es decir, usted pensó que el sistema funcionaba de una manera, y resulta que no lo hizo. Al romper una prueba o un conjunto (pequeño) de pruebas, esta es realmente una buena noticia. Sabe exactamente cómo afectará su nuevo código al sistema. Sin embargo, si sus pruebas están mal escritas, bien acopladas o, peor aún, generadas ( prueba de tos VS), entonces mantener sus pruebas puede convertirse en un coro rápidamente. Y, después de que suficientes pruebas comienzan a causar más trabajo que el valor percibido que están creando, entonces las pruebas serán lo primero que se eliminará cuando los horarios se compriman (por ejemplo, llega el momento de la crisis)

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

Idealmente, de nuevo, si se adhiere a la metodología, su código se probará al 100% de forma predeterminada. Por lo general, pensé, termino con una cobertura de código de más del 90%. Esto generalmente ocurre cuando tengo una arquitectura de estilo de plantilla, y la base se prueba, y trato de cortar esquinas y no probar las personalizaciones de la plantilla. Además, descubrí que cuando encuentro una nueva barrera que no había encontrado anteriormente, tengo una curva de aprendizaje al probarla. Admitiré escribir algunas líneas de código a la antigua manera de skool, pero realmente me gusta tener ese 100%. (Supongo que fui muy exitoso en la escuela, er skool).

Sin embargo, con eso diría que los beneficios de TDD superan con creces los 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 a todas, lo hará podrá seguir agregando nuevas funciones en el día 300 de su proyecto como lo hizo en 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 lleno de errores, y por eso piensan que puede No funciona, punto.

Personalmente, descubrí que con TDD, escribo un código más simple, paso menos tiempo debatiendo si una solución de código en particular funcionará o no, y que no tengo miedo de 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, y he estado en esto durante algunos años, y todavía aprendo nuevas técnicas de prueba todo el tiempo. Es una inversión de tiempo enorme por adelantado, pero, a largo plazo, su sostenibilidad será mucho mayor que si no tuviera pruebas unitarias automatizadas. Ahora, si solo mis jefes pudieran resolver esto.


77
¿Cuál era el resto de la oración que terminaba con "(tos VS Test), luego principal"?
Andrew Grimm

+1 por el problema de venta. :) Ahora mismo estoy en una nueva empresa y estoy pensando en cómo crear una cultura que permita que las habilidades se propaguen libremente.
Esko Luontola

2
Como considero, algunas empresas consultoras están aprovechando la programación de pares y TDD solo para obtener más dinero de sus clientes. Es bastante decepcionante cómo estos clientes pagan por ideas que parecen razonables a primera vista, como dos personas piensan mucho mejor que 2 o que TDD asegura que cada línea de código se prueba, pero al final son solo excusas para hacer que un cliente pague más por algo que solo una persona puede hacer.
lmiguelvargasf

24

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

Pierdes tiempo porque:

  • La creación de un conjunto de pruebas de unidad y aceptación integrales, refactorizadas y mantenibles agrega un tiempo importante a la primera iteración del proyecto. Esto 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 básico de herramientas. Una herramienta de prueba de unidad debe complementarse con algún tipo de marco de simulación y ambos deben formar parte de su sistema de construcción automatizado. También desea elegir y generar métricas apropiadas.

Pierdes la libertad personal porque:

  • TDD es una forma muy disciplinada de escribir código que tiende a rozar a 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 continua por pares puede asustar a sus peores y mejores desarrolladores e incluso provocar la pérdida de personal.
  • La mayoría de los métodos ágiles que incorporan TDD requieren que hable con el cliente continuamente sobre lo que se propone lograr (en esta historia / día / lo que sea) y cuáles son las compensaciones. Una vez más, esta no es la taza de té de todos, tanto del lado de los desarrolladores como de los clientes.

Espero que esto ayude


1
No sé si es porque soy el peor o el mejor ... pero TDD me molesta. Es porque me obliga al modo de mantenimiento dual demasiado pronto. Cada vez que cambio el diseño de una clase, ahora también tengo que cambiar los casos de prueba. ¡Espero y acepto eso de una clase madura, pero no de una clase que acabo de escribir la semana pasada! También puedo decir que DI y TDD no son compatibles con lenguajes como Java y C #. Alguien realmente necesita crear un nuevo lenguaje para que el costo de TDD y DI sea literalmente cero . Entonces ya no tendremos esta conversación.
John Henckel

14

TDD requiere que planifiques cómo funcionarán tus clases antes de escribir el 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 ningún 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 refactorizar no solo mis clases, sino TAMBIÉN mis exámenes. Repita esto tres o cuatro veces y puede ser frustrante.

Prefiero escribir un borrador de mis clases primero y 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 informa un error, escribiré una prueba para explotar ese error y luego corregiré el código para que pase la prueba.


1
Si bien debe tener una idea de cómo se verá la arquitectura de su sistema, no tiene que saber mucho antes de hacer TDD. TDD significa que las pruebas CONDUCEN el diseño, por lo que cambiará a medida que implemente más escenarios de prueba
casademora

44
Estoy de acuerdo con el vacío. Los tutoriales originales de TDD donde escribirás la prueba sin NINGÚN código, y obtendrás un error de compilación, son una locura.
mparaz

Es una suposición errónea que puede escribir las pruebas una vez y no cambiarlas. Son códigos y cada código requiere una refactorización eventual después de que realice los cambios. Las pruebas no son una excepción. Las pruebas de refactorización son imprescindibles si desea mantenerlas mantenibles.
Roman Konoval

12

La creación de prototipos puede ser muy difícil con TDD: cuando no está seguro de qué camino va a tomar para 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" de la gran mayoría de los proyectos haya ningún inconveniente real; se habla 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.


9

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

Sin embargo, el mayor problema que tuve personalmente con él es levantar la disciplina para escribir las pruebas. En un equipo, especialmente en un equipo establecido, puede ser difícil convencerlos de que el tiempo dedicado vale la pena.


13
Ajá, pero ahí es donde entra TDTDD. Test Driven Test Driven Development.
Snowcrash

3
Todavía ocasionalmente encuentro errores en mis pruebas de prueba. Así que ahora practico TDTDTDD.
HorseloverFat

@SnowCrash +1 Estaba buscando en Google para ver cuánto tiempo pasan las personas probando sus pruebas, y luego vi esta respuesta. Oficialmente encontré esto porque me preguntaba acerca de TDTDTDD.
BalinKingOfMoria Reinstate CMs

1
Creo que el futuro es (TD) <sup> ∞ </sup> TDD. Tengo un archivo hasta ahora: contiene la letra "x".
Mike roedor

Estoy de acuerdo con @Tim. Convencer a los miembros para que lo adopten es la parte más difícil.
Olu Smith

7

Si sus pruebas no son muy exhaustivas, puede caer en una falsa sensación de "todo funciona" simplemente porque pasa las pruebas. 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 verificación de cordura por su cuenta antes de llamar a algo completo, no solo confiar en las pruebas.

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


No creo en ninguna cláusula de cordura desde que crecí.
Mike roedor

7

La desventaja de TDD es que generalmente está estrechamente asociado con la metodología 'Agile', que no da importancia a la documentación de un sistema, sino que la comprensión detrás de por qué una prueba 'debería' devolver un valor específico en lugar de cualquier otro reside solo en el desarrollador cabeza.

Tan pronto como el desarrollador se vaya o se olvide de la razón por la que la prueba devuelve un valor específico y no otro, estás jodido. TDD está bien SI está adecuadamente documentado y rodeado de documentación legible para humanos (es decir, gerente de cabello puntiagudo) a la que se puede hacer referencia en 5 años cuando el mundo cambia y su aplicación también lo necesita.

Cuando hablo de documentación, esto no es una propaganda en el código, se trata de una escritura oficial que existe fuera de la aplicación, como casos de uso e información de fondo a la que pueden referirse los gerentes, abogados y el pobre savia que tiene que actualizar su código en 2011


1
Perfectamente puesto. No podría estar mas de acuerdo. Para mí, las pruebas ciertamente no ayudan a describir definiciones de problemas de alto nivel en el mundo real. Una buena documentación ha demostrado su valía una y otra vez. Como la tecnología. edades de la industria, las nociones probadas con el tiempo deben prescindirse con precaución cada vez mayor. El código autodocumentado es una noción ridícula. Creo en la creación de prototipos, la refactorización y la agilidad que conlleva no definir nunca un problema al principio. Sin embargo, irónicamente, no definir en exceso el problema al principio hace que el tropezado para TDD sea un campo minado.
wax_lyrical

1
Creo que esto es injusto. Las buenas prácticas TDD condenan los números mágicos y las pruebas oscuras. Las pruebas deben ser simples y como, o preferiblemente, más legibles que su propio código de producción. Sus pruebas SON la documentación. asegúrese de que se vean así. esta respuesta se siente un poco como decir "la documentación es mala porque a veces las personas escriben documentación realmente mala" o "las clases son malas porque he visto algunas clases de Dios con las que era difícil tratar".
sara

6

Me he encontrado con varias situaciones en las que TDD me vuelve loco. Por nombrar algunos:

  • Capacidad de mantenimiento del 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 al menos la mayoría de ellos sean 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 en funcionamiento, como HP Quality Center, para rastrearlas, se volverá loco de inmediato.

    Esto también significa que les tomará a los nuevos miembros del equipo una buena cantidad de tiempo captar lo que está sucediendo con los casos de prueba. A su vez, esto se puede traducir en más dinero necesario.

  • Probar la complejidad de la automatización:

    Si automatiza algunos o todos los casos de prueba en scripts de prueba ejecutables por máquina, deberá 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, pasará tiempo para depurar los códigos que lo ayudan a detectar errores. En mi opinión, la mayoría de estos errores provienen del fracaso del equipo de prueba para reflejar los cambios de la aplicación en el script de prueba de automatización. Los cambios en la lógica de negocios, la GUI y otras cosas internas pueden hacer que sus scripts dejen de ejecutarse o se ejecuten de manera poco confiable. A veces los cambios son muy sutiles y difíciles de detectar. Una vez que todas mis secuencias de comandos informan un error porque basan 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).


Esto no trata en absoluto con TDD. Si alguien en otro departamento está escribiendo sus casos de prueba, no está haciendo TDD. Si tiene casos de prueba manual, no está haciendo TDD. Si el código de su biblioteca se rompe y sus pruebas fallan debido a cambios en la GUI, probablemente tampoco esté haciendo TDD. Esto parece más como argumentos en contra de grandes departamentos ineficientes de control de calidad empresarial.
Sara

5

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, solo porque se ejecutan en un orden diferente). Escriben pruebas que no prueban nada en particular: simplemente depuran el código, verifican el resultado y lo cambian a 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 que tienen 500 líneas de largo, valores codificados, duplicación de código) y es un infierno de mantener. Por alguna extraña razón, las personas tratan las pruebas unitarias como algo inferior al código "real", y no lo hacen No importa su calidad en absoluto. :-(


4

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


¿Es realmente una forma negativa o astuta de decir algo positivo?
IanL

3

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 compañías de software que trabajan (dólares por KLOC), eventualmente lo despedirán. 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 se han probado), manténgase alejado de TDD (o revisiones de código, programación de pares, integración continua, etc., etc.).


3

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.

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

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

Pierdes la libertad de acoplar firmemente tus módulos.

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.


1
Depende de su definición de "entregar una solución a tiempo" - es que "cualquier solución antigua, parcialmente rota a tiempo" o "entregar soluciones de trabajo a tiempo". Ciertamente pierde la capacidad de entregar soluciones parcialmente rotas a tiempo. En cuanto a la velocidad de desarrollo, me gusta la métrica "tiempo transcurrido entre el inicio del desarrollo y una semana de despliegue en vivo sin fallas". Si lo mide de manera justa, es difícil incluso detener el reloj en una pieza copmlex de trabajo que no sea TDD.
Dafydd Rees

47
-1, esto es exactamente lo que el OP dijo que no quería.
erikkallen

1
Muchas afirmaciones verdaderas, pero: lo que dijo erikkallen. -1.
j_random_hacker

@ j_random_hacker dice hacker ... LOL
Dan

solo la tercera declaración es legítima "aprender a través de la depuración se pierde"
YEH

2

Secundo 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 loco de TDD, por lo que podrías perder algunos amigos;)


2

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


2

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

Piénselo, es probable que termine diseñando para casos de prueba específicos, por lo que no será creativo y comenzará a pensar "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 geniales X, Y y Z, su diseño puede estar demasiado rígidamente enfocado en casos de prueba ya especificados, y será difícil de ajustar.

Esto, por supuesto, es una espada de doble filo. Si pasa todo su tiempo diseñando para cada X imaginable, imaginable, X, Y y Z que un usuario pueda desear, inevitablemente nunca completará nada. Si completa algo, será imposible que alguien (incluido usted mismo) tenga alguna idea de lo que está haciendo en su código / diseño.


Piénselo, es probable que termine diseñando para casos de prueba específicos, por lo que no será creativo y comenzará a pensar "sería genial si el usuario pudiera hacer X, Y y Z". - En mi opinión, eso es exactamente lo contrario. Si escribe pruebas unitarias, se pregunta sobre diferentes casos de negocios y eso significa que es creativo y hace posible prever algo imprevisto. Sin embargo, toda esa creatividad no es importante si su implementación tiene errores.
BlueLettuce16

1

Puede ser difícil y lento escribir pruebas para datos "aleatorios" como fuentes XML y bases de datos (no es tan difícil). Últimamente he pasado algún tiempo trabajando con datos de clima. Es bastante confuso escribir pruebas para eso, al menos porque no tengo mucha experiencia con TDD.


Este es un problema común. Tiendo a burlarme de estos con objetos codificados, luego pruebo la base de datos por separado. Su capa empresarial solo debería funcionar con datos estáticos, su DAL se probará en un entorno controlado (donde puede escribir los datos en ella, etc.)
Rob Cooper

1

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

Jason Cohen dijo algo como: TDD requiere una determinada organización para su código. Esto podría ser arquitectónicamente incorrecto; por ejemplo, dado que los métodos privados no se pueden invocar 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

Debe escribir las aplicaciones de una manera diferente: una que las haga comprobables. 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 duro. 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 por lo que los desarrolladores junior pueden tener dificultades al principio (principalmente porque no se les ha enseñado a trabajar de esta manera).

En general, los inconvenientes 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

Toma un tiempo entrar en él y algo de tiempo para comenzar a hacerlo en un proyecto, pero ... Siempre lamento no haber hecho un enfoque de Test Driven cuando encuentro errores tontos que una prueba automatizada podría haber encontrado muy rápido. Además, TDD mejora la calidad del código.


1
  • Las pruebas unitarias son más código para escribir, por lo tanto, un mayor costo inicial de desarrollo
  • es más código para mantener
  • aprendizaje adicional requerido

1

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

  • He escrito aplicaciones para hacer su propia prueba aleatoria. El problema con escribir pruebas específicas es que incluso si escribes muchas de ellas, solo cubren los casos que piensas. Los generadores de prueba aleatoria encuentran problemas en los que no pensó.

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

  • En la medida en que su aplicación lo permita, tenga cuidado con el diseño que se basa en el orden adecuado de notificaciones, eventos y efectos secundarios. Esos pueden caerse o mezclarse fácilmente, por lo que necesitan muchas pruebas.


Las pruebas aleatorias pueden fallar intermitentemente y dificultar su repetición
David Sykes

@DavidSykes: Cada vez que haces una prueba aleatoria, registras los parámetros, de modo que si falla, puedes repetirlo, o puedes repetirlo más tarde, incluso si no falló. El punto es que no depende de ti pensar en los casos de prueba. Si eres como yo, instintivamente gravitas hacia casos de prueba seguros.
Mike Dunlavey

0

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

Cuando el código cambia, también debe cambiar las pruebas. Con la refactorización, esto puede ser mucho trabajo extra.


9
Todos los métodos privados deben probarse a través de los métodos públicos que existirían de todos modos.
Garry Shutler

Esto no es posible con todas las clases. A veces no desea simular todas las dependencias, etc. y solo desea probar un método de utilidad.
Jason Cohen

+1, muy cierto. Agregue a esto el requisito de agregar a veces getters / setters a campos privados solo para poder configurar y leer el estado correctamente para una prueba unitaria, a pesar de que el estado debe ser privado para la clase.
erikkallen

Considere escribir sus pruebas como si fuera un documento de requisitos de vida. Entonces verías la luz. Lea también los patrones de prueba de XUnit.
Scott Nimrod

0

Permítanme agregar que si aplica los principios BDD a un proyecto TDD, puede aliviar algunos de los principales inconvenientes enumerados aquí (confusión, malentendidos, etc.). Si no está familiarizado con BDD, debería leer la introducción de Dan North. Se le ocurrió el concepto en respuesta a algunos de los problemas que surgieron al aplicar 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 una brecha. Deberá tener esto en cuenta al recopilar sus comentarios.


Absolutamente. Debe considerar BDD al evaluar TDD.
user9991

Parece BDD = desarrollo impulsado por el comportamiento
hayalci

0

Debe asegurarse de que sus pruebas estén siempre actualizadas, el momento en que comienza a ignorar las luces rojas es el momento en que las pruebas dejan de tener sentido.

También debe asegurarse de que las pruebas sean exhaustivas, o en el momento en que aparezca un gran error, el tipo de administración sofocante que finalmente convenció para permitirle pasar tiempo escribiendo más código se quejará.


0

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

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


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.