TDD experiencia negativa [cerrado]

93

¿Cuál es el lado negativo de tu experiencia TDD? ¿Le parecen molestos e inútiles los pasos de bebé (la solución más simple para hacer que la prueba sea verde)? ¿Encuentra que las pruebas sin valor (cuando la prueba tiene sentido inicialmente pero en la implementación final verifica la misma lógica que otras pruebas) es fundamental el mantenimiento? etc.

Las preguntas anteriores se refieren a cosas con las que me siento incómodo durante mi experiencia con TDD. Así que me interesa si otros desarrolladores tienen sentimientos similares y qué piensan de ellos.

Agradecería los enlaces a los artículos que describen los aspectos negativos de TDD (Google está lleno de artículos positivos ya menudo fanáticos).

    
pregunta Idsa 04.08.2011 - 09:04
fuente

16 respuestas

93

Al igual que todo lo que viene bajo la bandera "Agile", TDD es algo que suena bien en teoría, pero en la práctica no está tan claro qué tan bueno es (y también como la mayoría de las cosas "Agile", se le dice que si no te gusta, lo estás haciendo mal).

La definición de TDD no está grabada en piedra: tipos como Kent Beck exigen que una prueba de no compilación se escriba antes de una sola línea de código y que cada línea de código se escriba para aprobar una prueba que falla. El diseño frontal es mínimo y todo está dirigido por las pruebas. Simplemente no funciona. He visto una aplicación de gran empresa desarrollada utilizando esa metodología y espero que sea el peor código que veo en mi carrera (no estará muy lejos, y eso fue a pesar de que algunos desarrolladores talentosos trabajaron en ella). Por lo que he visto, resulta en una gran cantidad de pruebas mal pensadas que validan principalmente que se producen las llamadas de función, que se lanzan excepciones cuando las variables son nulas y el marco de burla obtiene un entrenamiento completo (whoop-de-whoop); su código de producción se acopla en gran medida a estas pruebas y el sueño de una refactorización constante y fácil no aparece; de hecho, es menos probable que las personas solucionen un código incorrecto debido a toda la prueba que se romperá. En este tipo de entorno, los administradores de software prefieren tener un software malo con pruebas de aprobación y una alta cobertura de código que un software bueno con menos pruebas.

A la inversa, he escuchado a personas argumentar que TDD significa diseñar las pruebas por adelantado en un nivel alto como parte de la fase de planificación, junto con el diseño arquitectónico. Estas pruebas pueden cambiar durante el desarrollo a medida que haya más información disponible, pero se han considerado cuidadosamente y ofrecen una buena guía sobre lo que realmente debería hacer el código. Para mí eso tiene perfecto sentido.

    
respondido por el 3 revs, 2 users 90%user23157 28.10.2011 - 16:39
fuente
65

Este ( Clojure autor) La entrevista de Rich Hickey contiene lo siguiente. Me siento 100% simpático:

  

La vida es corta y solo hay un número finito de horas en un día. Entonces, tenemos que tomar decisiones sobre cómo gastamos nuestro tiempo. Si lo gastamos escribiendo pruebas, ese es el tiempo que no estamos gastando haciendo otra cosa. Cada uno de nosotros debe evaluar la mejor manera de invertir nuestro tiempo para maximizar nuestros resultados, tanto en cantidad como en calidad. Si las personas piensan que gastar el cincuenta por ciento de su tiempo escribiendo las pruebas maximiza sus resultados, está bien para ellos. Estoy seguro de que eso no es cierto para mí, prefiero pasar ese tiempo pensando en mi problema. Estoy seguro de que, para mí, esto produce mejores soluciones, con menos defectos, que cualquier otro uso de mi tiempo. Un mal diseño con un conjunto de pruebas completo sigue siendo un mal diseño.

Otra declaración similar de Donald Knuth en la entrevista del libro Coders at Work , copiada de here :

  

Seibel: Hablando de trabajo práctico, en medio de trabajar en El arte de la programación por computadora, tomaste lo que se convirtió en una pausa de diez años para escribir tu sistema de composición TeX. Tengo entendido que escribiste la primera versión de TeX completamente lejos de la computadora.

     

Knuth: Cuando escribí TeX originalmente en 1977 y 78, por supuesto, no tenía una programación alfabetizada, pero sí una programación estructurada. Lo escribí en un cuaderno grande a mano, a lápiz. Seis meses después, después de haber pasado por todo el proyecto, comencé a escribir en la computadora. Y hice la depuración en marzo del 78 mientras yo comenzaba a escribir el programa en octubre del 77. El código para eso está en los archivos de Stanford, todo está a lápiz, y por supuesto volvería y cambiaría una subrutina a medida que aprendía lo que debía ser. Este era un sistema de primera generación, por lo que muchas arquitecturas diferentes eran posibles y debían ser descartadas hasta que viviera con él por un tiempo y supiera lo que había allí. Y era un problema de la gallina y el huevo: no podías tipografiar hasta tener fuentes, pero no podías tenerlas hasta que podías tipear. Pero la programación estructurada me dio la idea de invariantes y saber cómo hacer cajas negras que pudiera entender. Así que tenía la confianza de que el código funcionaría cuando finalmente lo depurara. Sentí que estaría ahorrando mucho tiempo si esperara seis meses antes de probar algo. Tenía suficiente confianza en que el código era aproximadamente correcto.

     

Seibel: ¿Y el ahorro de tiempo sería porque no gastaría tiempo en construir andamios y talones para probar el código incompleto?

     

Knuth: a la derecha.

    
respondido por el Joonas Pulakka 04.08.2011 - 23:00
fuente
55

Mi experiencia negativa con TDD fue la primera. TDD me sonaba muy bien, había hecho control de calidad durante años y todavía tenía los horrores frescos en mi mente. Quería aplastar cada error antes de que se convirtiera en una compilación. Desafortunadamente, el uso de TDD no garantiza que escribirás buenas pruebas. De hecho, mi predisposición inicial era escribir pruebas simples que generaran código simple. Código realmente simple que contenía pocas abstracciones. Pruebas realmente simples que se entrelazaron con las partes internas de la clase. Y una vez que haya realizado unos pocos miles de pruebas de Bitty Bitty, no se sentirá como si se estuviera moviendo más rápido cuando tenga que cambiar cientos de ellos para refactorizar su código y utilizar el concepto de dominio muy importante X.

La luz se encendió para mí: TDD no es una habilidad de prueba. Es una habilidad de diseño. Solo puede llevarlo a un código bueno, simple y viable con práctica y un conocimiento constante de las instrucciones de diseño que lo guían. Si está escribiendo pruebas por el bien de la cobertura del código, creará pruebas frágiles. Si estás escribiendo pruebas para ayudarte a diseñar tus abstracciones, entonces es solo una forma más rigurosa de escribir código de arriba a abajo. Primero puede ver el código desde la perspectiva de la persona que llama, lo que lo alienta a hacer su vida más fácil, en lugar de reflejar los aspectos internos de una clase en su borde exterior.

Creo que TDD es útil, pero no soy dogmático al respecto. Si esas "pruebas sin valor" dificultan el mantenimiento, ¡elimínelas! Trato las pruebas de la misma manera que el resto del código. Si puede ser refaccionado y simplificar las cosas, ¡entonces hágalo!

No lo he visto personalmente, pero he oído que algunos lugares rastrean la cobertura de códigos y los conteos de pruebas. Entonces, si la recopilación de métricas es un efecto secundario de TDD, también podría verlo como negativo. Eliminaré con entusiasmo 1000 líneas de código, y si eso deja obsoletas 20 pruebas y deja caer el% de cobertura de mi código, bueno.

    
respondido por el Steve Jackson 05.08.2011 - 13:39
fuente
40

Voy a arriesgarme aquí y declararé con brutal honestidad que es literalmente una pérdida ritual de tiempo. (En la mayoría de las situaciones.)

Compré un libro sobre Pruebas unitarias en el que también se hablaba de TDD, y aunque estoy de acuerdo con los beneficios de UT, después de unas cien horas de probar TDD, lo dejé por un sinfín de razones. Estoy tipo de publicación cruzada aquí, pero TDD:

  1. No hay mejor documentación que la documentación real.
  2. No detecta errores ni regresiones .
  3. Realmente no hace que mis diseños sean mejores de lo que son si aplico algunos conceptos de programación funcional y composability .
  4. Es el tiempo que podría gastarse mejor haciendo revisiones de código o puliendo documentación y especificaciones.
  5. Da a los administradores una falsa sensación de seguridad cuando ven una lista de cientos de iconos verdes.
  6. Mejora la productividad en la implementación de algoritmos con asignaciones de entrada-salida limitadas.
  7. Es torpe porque puedes saber lo que estás haciendo como resultado de TDD, pero no estás obteniendo ningún entendimiento de por qué funciona tan bien. por qué tus diseños salen como lo hacen ellos.

Otra preocupación es el grado de perfección debatido al cual se debe hacer TDD para hacerlo con éxito. Algunos insisten en que si TDD no se realiza de manera persistente por parte de todos en el equipo desde el inicio del proyecto, solo sufrirá. Otros insisten en que nadie hace TDD por el libro. Si ambos son verdaderos, entonces se deduce que los practicantes de TDD están sufriendo, se den cuenta o no.

Por supuesto, si se argumenta que al hacer las cosas de manera similar a una TDD, llegará a diseños que pueden funcionar fácilmente con TDD, bueno, hay formas mucho más rápidas de lograrlo, es decir, estudiando realmente Los conceptos de composabilidad. Hay muchos recursos por ahí, incluso mucha teoría matemática rigurosa (en gran parte en programación funcional pero también en otros campos). ¿Por qué no gastar todo su tiempo TDD aprendiendo ?

Culturalmente, TDD muestra síntomas de ser una práctica ritualista. Se monta en la culpa; alienta el procedimiento sobre la comprensión; tiene toneladas de doctrinas y eslóganes ("simularlo hasta que lo logres" es realmente bastante alarmante si lo miras objetivamente). La definición de Wikipedia de la palabra "ritual" es de hecho bastante apropiada:

  

En psicología, el término ritual se usa a veces en un sentido técnico   Para un comportamiento repetitivo utilizado sistemáticamente por una persona para   neutralizar o prevenir la ansiedad; Es un síntoma de obsesivo-compulsivo.   desorden.

    
respondido por el Rei Miyasaka 12.04.2017 - 09:31
fuente
17

Para agregar, otra preocupación con TDD que noté es:

¡TDD provoca un cambio involuntario en el enfoque del equipo de desarrollo de Código de Calidad a Testcases y Cobertura de Código! Personalmente, no me gustó TDD, ya que me hace menos creativo y hace que el desarrollo de software sea un proceso mecánico aburrido . Los estuches de prueba de unidades son útiles cuando se utilizan con criterio, pero se convierten en una carga cuando se los trata el objetivo del desarrollo de software.

Conozco a un chico que es gerente y es técnicamente aburrido una vez que se obsesionó con TDD. Para él era algo tan mágico que creía que aportaría soluciones mágicas a todos los problemas en su software de arquitectura deficiente con el código menos mantenible. Por no decir lo que le pasó a ese proyecto, fracasó miserablemente en sus manos, mientras que todos sus casos de prueba eran verdes. Supongo que TDD lo ayudó a obtener algún tipo de información estadística como "99/100 de mis casos son ecológicos", etc., y ese fue el motivo de su obsesión, ya que nunca podría evaluar la calidad ni sugerir mejoras en el diseño.

    
respondido por el Kiran Ravindranathan 10.08.2011 - 07:16
fuente
14

Mi experiencia negativa primaria es tratar de usar TDD para editar el código de otro programador que no tiene pruebas, o pruebas de integración muy, muy básicas. Cuando voy a agregar una característica, o solucionar un problema con dicho código; Preferiría escribir una prueba primero (la forma TDD). Desafortunadamente, el código está estrechamente acoplado y no puedo probar nada sin mucha refactorización.

De todos modos, la refactorización es un gran ejercicio, pero se requiere para que el código tenga un estado comprobable. Y después de este paso, no tengo controles ni balances para ver si mis cambios se rompieron; menos de ejecutar la aplicación y examinar cada caso de uso.

Por otro lado, agregar características / corregir errores a un proyecto TDD se vuelve muy sencillo. Por naturaleza, el código escrito con TDD suele estar bastante desacoplado con piezas pequeñas para trabajar.

En cualquier caso, TDD es una guía. Síguelo hasta el punto donde encuentre que obtiene la máxima eficacia. Cobertura de prueba decente y código desacoplado, código bien escrito.

    
respondido por el Sheldon Warkentin 04.08.2011 - 17:38
fuente
12

Hice la experiencia de que a veces confío demasiado en mis pruebas cuando se trata del diseño del sistema. Básicamente soy demasiado bajo en los detalles de la implementación del meñido para dar el paso atrás para ver el panorama general. Esto a menudo resulta en un diseño innecesariamente complejo. Lo sé, se supone que debo refactorizar el código, pero a veces tengo la impresión de que puedo ahorrar mucho tiempo retrocediendo el paso con más frecuencia.

Dicho esto, si tiene un marco como rieles donde sus decisiones arquitectónicas son muy limitadas, estos problemas son básicamente inexistentes.

Otro problema es cuando confías ciegamente en tus pruebas. La verdad es que, como cualquier otro código, sus pruebas también pueden tener errores. Entonces, sea tan crítico con sus pruebas como con su implementación.

    
respondido por el sebastiangeiger 12.11.2018 - 18:58
fuente
11

Como gran fanático de TDD, a veces veo estos inconvenientes

  • La tentación de escribir demasiadas pruebas en aras de una cobertura de código de casi el 100%. En mi opinión no es necesario escribir pruebas.
    • para captadores / definidores de propiedades simples
    • para cada caso cuando se lanza una excepción
    • que comprueba la misma funcionalidad a través de diferentes capas. (Ejemplo: si tiene una prueba de unidad para verificar la validación de entrada para cada parámetro, entonces no es necesario repetir todas estas pruebas a través de una prueba de integración)
  • Costos de mantenimiento del código de prueba para pruebas similares, que varían solo ligeramente (creado a través de la duplicación de código (también conocida como herencia de copiar y pegar)). Si ya tienes uno, es fácil crear uno similar. Pero si no refactoriza el código de prueba, al eliminar la duplicación de código en los métodos de ayuda, es posible que necesite algo de tiempo para corregir las pruebas si los detalles de la implementación de su código de negocio cambian.

  • Si está bajo presión de tiempo , puede tener la tentación de eliminar exámenes rotos (o comentarlos) en lugar de corregirlos ellos. De esta manera usted pierde la inversión en las pruebas

respondido por el k3b 15.02.2014 - 02:34
fuente
9

Todavía tengo que encontrar más de un escenario como desarrollador de juegos en el que vale la pena TDD. Y la instancia en la que se encontraba era un código que era de naturaleza puramente matemática y necesitaba un enfoque sólido para probar simultáneamente un gran número de casos de borde, una necesidad rara.

Tal vez algo, algún día cambiará de opinión, pero entre las prácticas de XP, la idea de refactorizar sin piedad , y del código en evolución es mucho más importante que su propia forma. a la mayor productividad para mí, cf. una cita de un documento de James Newkirk :

  

Simplicidad: "¿Cuál es la cosa más simple que podría funcionar?"

  El mensaje es muy claro. Dados los requisitos para   Hoy, diseña y escribe tu software. No intentes anticipar el   futuro, deja que el futuro se desarrolle. A menudo hará esto en muy   Formas impredecibles que hacen de la anticipación un costo que a menudo es demasiado   costoso de costear. "

Para mí, los conceptos de coraje y de apretar comentarios que él menciona son también clave para la productividad.

    
respondido por el Arcane Engineer 04.08.2011 - 13:20
fuente
7

Mi experiencia TDD negativa, por muy limitada que sea, ¡es simplemente saber por dónde empezar! Por ejemplo, trataré de hacer algo TDD y no tengo idea de dónde empezar a probar cosas triviales (¿puedo crear un objeto Foo , puedo pasar un Quux al Baz y el Pruebas que no prueban nada), o si estoy tratando de implementarlo en un proyecto existente, encuentro que tendría que reescribir varias clases para poder usarlas en TDD. El resultado final es que rápidamente abandono la noción por completo.

Probablemente no ayude, ya que a menudo soy la única persona en toda la empresa que sabe qué pruebas de unidad (TDD o de otro tipo) es y por qué es algo bueno.

    
respondido por el Wayne Molina 04.08.2011 - 17:00
fuente
7

fanáticos de TDD.

Para mí, son solo uno de una larga fila de locos religiosos que golpean a mi puerta, tratando de demostrar que mi manera de hacer las cosas está irremediablemente quebrada y el único camino hacia la salvación es Jesús, Kent Back o Pruebas de unidad.

En mi opinión, su mayor mentira es que TDD te llevará a salvación con un mejor diseño de algoritmo. Consulte el famoso solucionador de Soduku escrito en TDD: aquí , here , here , here y here

Y compárelo. Peter Norvig solucionador de sudoku no con TDD, sino con ingeniería anticuada: enlace

    
respondido por el Cesar Canassa 04.04.2016 - 13:16
fuente
4

Si utiliza TDD de estos artículos "fanáticos", tendrá una sensación de seguridad errónea de que su software no tiene errores.

    
respondido por el Dainius 04.08.2011 - 09:24
fuente
4

TDD tiene algunos beneficios:

  • Se enfoca en cómo para llamar su código y lo que debe esperar primero (al escribir primero la prueba) en lugar de enfocarse en resolver el problema y luego pegar una llamada desde la aplicación. La modularidad hace que sea más fácil burlarse y envolverse.
  • Las pruebas aseguran que su programa funcione de la misma manera antes y después de una refactorización. Esto no significa que su programa esté libre de errores, sino que sigue funcionando de la misma manera.

TDD es una inversión a largo plazo. El esfuerzo se amortiza cuando alcanza el modo de mantenimiento de su aplicación, y si la aplicación no está planeada para llegar a ese punto, nunca podrá recuperar la inversión.

Considero que el TDD ciclo rojo-verde con los pasos de bebé es similar a una lista de verificación para un avión. Es molesto y tedioso revisar todas y cada una de las cosas en el avión antes del despegue, especialmente si es trivialmente simple (los pequeños pasos de TDD) pero se ha encontrado que aumenta la seguridad. Además de verificar que todo funciona, esencialmente restablece el plano . En otras palabras, un avión se reinicia antes de cada despegue.

    
respondido por el 2 revsuser1249 04.08.2011 - 22:17
fuente
3

Mi experiencia negativa sobre TDD es algo que siento con muchas cosas nuevas y promocionadas. De hecho, disfruto de TDD porque garantiza la validez de mi código, y aún más importante: puedo reconocer las pruebas fallidas, después de agregar un nuevo código o cualquier tipo de refactorización.

Lo que me molesta de TDD es el hecho de que existen muchas reglas o directrices al respecto. Como todavía es bastante nuevo, la mayoría de nosotros experimentamos ser principiantes en TDD. Entonces, lo que funciona bien para algunos de nosotros, podría no funcionar para otros. Lo que quiero decir es que no hay una manera real "incorrecta o correcta" de realizar TDD: existe la forma en que funciona para mí, y para mi equipo si tengo una.

Por lo tanto, mientras escriba las pruebas, antes o después de que el código de producción no sea realmente IMHO, no estoy seguro de que las pruebas estén basadas realmente en que debe seguir todas las pautas que se indican en este momento, ya que aún no están Ha demostrado ser la solución ideal para el trabajo diario. Si encuentra una mejor manera de escribir las pruebas, debe publicarlo en un blog, discutirlo aquí o escribir un artículo al respecto. Entonces, en aproximadamente diez años, podríamos haber compartido la experiencia suficiente para poder decir qué regla de TDD se puede asumir como buena o no en una situación determinada.

    
respondido por el Alex 05.08.2011 - 08:42
fuente
3

En más de una ocasión, he escrito un código que descarté al día siguiente porque era torpe. Reinicié con TDD y la solución fue mejor. Así que no he tenido demasiado en la línea de la experiencia TDD negativa. Sin embargo, dicho esto, he dedicado tiempo a pensar en un problema y encontrar una solución mejor fuera del espacio de TDD.

    
respondido por el user23356 05.08.2011 - 11:25
fuente
3

Descubrí que la TDD tiene un bajo rendimiento cuando se trata de sistemas emergentes. Soy desarrollador de videojuegos y recientemente utilicé TDD para crear un sistema que usa múltiples comportamientos simples para crear movimientos de apariencia realista para una entidad.

Por ejemplo, hay comportamientos responsables de alejarlo de áreas peligrosas de diferentes tipos y responsables de moverlo hacia áreas interesantes de diferentes tipos. La fusión de la salida de cada comportamiento crea un movimiento final.

Las agallas del sistema se implementaron fácilmente, y TDD fue útil aquí para especificar de qué debería ser responsable cada subsistema.

Sin embargo, tuve problemas cuando se trataba de especificar cómo interactúan los comportamientos y, lo que es más importante, cómo interactúan a lo largo del tiempo. A menudo no hubo una respuesta correcta, y aunque mis pruebas iniciales fueron aprobadas, el control de calidad pudo seguir encontrando casos en los que el sistema no funcionaba. Para encontrar la solución correcta, tuve que repetir varios comportamientos diferentes, y si actualizaba las pruebas cada vez que reflejaba los nuevos comportamientos antes de verificar que funcionaban en el juego, es posible que haya terminado tirando las pruebas una y otra vez. Así que borré esas pruebas.

Posiblemente debería haber tenido pruebas más sólidas que capturaron los casos de vanguardia que QA descubrió, pero cuando tienes un sistema como este que se encuentra sobre muchos sistemas de juego y física, y estás tratando con comportamientos a lo largo del tiempo, se convierte en una pesadilla para especificar exactamente lo que está sucediendo.

Es casi seguro que cometí errores en mi enfoque, y como dije para las agallas del sistema, el TDD funcionó de manera brillante e incluso apoyó a algunos refactores optimizadores.

    
respondido por el tenpn 09.08.2011 - 09:54
fuente

Lea otras preguntas en las etiquetas