Si TDD se trata de diseño, ¿por qué lo necesito? [cerrado]

10

Los gurús de TDD nos dicen cada vez más que TDD no se trata de pruebas, sino de diseño . Así que conozco algunos desarrolladores que crean un diseño realmente excelente sin TDD. ¿Deberían practicar TDD entonces?

SiberianGuy
fuente
14
Si lo están haciendo bien sin él, entonces no lo necesitan. No todas las "mejores prácticas" funcionan para todos.
Torre
1
Mi respuesta a una pregunta similar: programmers.stackexchange.com/questions/98485/…
Rei Miyasaka

Respuestas:

18

TDD no solo me ayuda a llegar al mejor diseño final, sino que me ayuda a lograrlo en menos intentos.

Solía ​​tener dos o tres puñaladas en un problema antes de decidir qué diseño creía que era mejor. Ahora, ese mismo tiempo lo paso escribiendo pruebas y enfocando mi mente en el diseño correcto. Y, como beneficio adicional, me deja con un conjunto de pruebas repetibles. ¡Ganar!

Dicho esto, inevitablemente habrá personas para quienes TDD no ofrece nada. Siempre que tengan pruebas automatizadas y repetibles al final, está bien.

pdr
fuente
44
en menos intentos, de verdad?
SiberianGuy
3
Sí, en serio. TDD me obliga a pensar en una clase en términos del código de llamada, así como de su funcionalidad, porque comienzas escribiendo el código que esperas poder escribir para consumir la clase. Cuando escribo una clase "a ciegas", tiendo a centrarme en lo que hace más de lo que la clase que llama, lo que casi siempre es un error.
pdr
44
Ver, hay esa palabra otra vez, forced. No sé por qué las personas no se molestan con más frecuencia por la frecuencia de la palabra "forzado" como ocurre en las discusiones sobre TDD. Uno no debería necesitar ser forzado a diseñar algo correctamente; deben aprender cómo diseñar las cosas correctamente, y luego continuar a hacerlo sin ser obligado a hacerlo, sobre todo cuando ese acto de forzar es tan increíblemente mucho tiempo.
Rei Miyasaka
3
@Rei: Las personas no se molestan más a menudo porque saben que la otra persona realmente quiere decir "empujada" o "guiada" o ... y aquí hay una revelación cuando se habla de Desarrollo guiado por pruebas ... quizás "impulsado" . Y sí, algunos podrían encontrar que piensan de esa manera naturalmente, sin ser conducidos, lo dije en la publicación. Pero aún debe probar su software para que no esté mucho mejor.
pdr
3
Cuando alguien dice "fuerza diseño modular", de hecho se ve obligado. Es muy difícil (si no imposible) hacer un diseño no composable con TDD, y eso es algo bueno. El problema no es este resultado final de ser contundente; es la cantidad de esfuerzo servil y rutinario que se necesita. El diseño adecuado es una habilidad que se puede enseñar y aprender, y se debe dedicar tiempo a aprender. Además, las pruebas escritas para TDD no se parecen mucho a las pruebas escritas para detectar errores. Si lo hacen, algo está mal .
Rei Miyasaka
12

Lo que este gurú de TDD en particular realmente está tratando de decir no es que TDD es un proceso de diseño (aunque desafortunadamente varias personas lo han interpretado de esa manera). El mensaje aquí es que el uso de un proceso como TDD, si lo hace bien , tenderá a mejorar su diseño general.

El concepto fundamental es mucho más antiguo que TDD; diseñando para la comprobabilidad . Si se adhiere rigurosamente a los principios SÓLIDOS , especialmente al Principio de responsabilidad única , encontrará que el código es muy fácil de probar. Por otro lado, si tiende a ser un poco más descuidado en su diseño, probablemente encontrará el proceso de escribir pruebas unitarias para obligarlo a hacer esto con más frecuencia, para evitar la frustración de (a) descubrir qué necesita ser probado y (b) pasar más tiempo configurando dependencias que escribiendo las pruebas reales.

Usted no tiene que seguir TDD para obtener los beneficios de esto, pero lo hace ayuda a escribir las pruebas principios - de preferencia muy pronto después de implementar una clase, si no antes o durante. Si espera demasiado, corre el riesgo de las pruebas de "híbrido sucio" de las que habla el autor, que no tienen mucho valor porque son frágiles y tienden a romperse durante la refactorización inofensiva, sin mencionar que se hacen más grandes -escala rediseña un proceso terriblemente difícil.

No puede saber si realmente está diseñando para la capacidad de prueba si no escribe pruebas, y las "pruebas de características" al azar con solo un 15% de cobertura de código no cuentan.

Por supuesto, puedes crear buenos diseños sin tener que escribir una sola prueba, pero ¿estás seguro de que son diseños geniales? ¿Cómo lo sabes, si no están claramente especificados por las pruebas? Las pruebas descubren muchos problemas y, si bien un proceso de control de calidad puede encontrar errores visibles, no descubrirán malas decisiones de diseño.

Aaronaught
fuente
1
El objetivo de un buen diseño no es solo ser probado. Pero sí, TDD es una buena herramienta para detectar diseños defectuosos.
deadalnix
4

Respuesta simplista de alguien que se esfuerza por aprender TDD: no lo necesita , pero el principal beneficio que le brinda es, simplemente, confianza : confianza en que su aplicación funciona. Confianza en que los casos de uso están satisfechos. Confianza en que su lógica es sólida para el módulo "Foobar". Confianza en que su código está estructurado adecuadamente para ser mantenible y extensible seis meses más adelante cuando el CEO quiere agregar alguna nueva característica loca sobre la que leyó. Confianza en que, cuando su aplicación crezca, se han sentado las bases para que la arquitectura no se desmorone o requiera muchos trucos desordenados para armar nuevas funciones.

Me doy cuenta de que lo anterior sonaba un poco evangélico, pero así es como veo el beneficio de TDD. Incluso si puede crear diseños buenos, sólidos y bien diseñados utilizando TDD, obliga a su mano a hacer las cosas bien, y luego demuestra que las cosas se hacen bien, y lo más importante, proporciona una línea de base para mantener las cosas bien. Por lo poco que he incursionado en TDD, usarlo me obligó a limpiar el código y seguir los conceptos de ingeniería de software adecuados, donde de lo contrario haría lo "más rápido posible" que a menudo resultaba en un código "pirateo" desordenado.

Wayne Molina
fuente
+1 TDD es retroalimentación. A medida que avanza la mayoría de las medidas de retroalimentación, es bastante objetivo y completamente automatizado, por lo que puede ser compartido por los miembros del equipo de todos los niveles de habilidad. Antes de TDD, un buen código era algo que "sentía", o que se confirmó en algún momento después de que los usuarios obtuvieron el software. Cuanto más corto sea el bucle, más seguro se sentirá. Desafortunadamente, TDD es propenso al exceso de confianza como "sentir" un buen diseño, pero es mucho más fácil de autocorregir.
Steve Jackson
2

Solo puedo hablar desde mi experiencia. Para mí, TDD trajo varias cosas que no tenía antes en mi caja de herramientas de hábitos de estilo de desarrollo. Sin embargo, vale la pena decir nuevamente que TDD no es la solución para todo. Siempre trato de separar la implementación de exploración y producción. TDD en la fase de exploración no es absolutamente necesario e incluso se está desacelerando. Por otro lado, para el código listo para producción, trae varios beneficios que a corto y largo plazo son muy valiosos para la salud mental de los desarrolladores y el karma del proyecto.

  • TDD me hace pensar antes de implementar, lo que suele ser una muy buena práctica que evita muchas soluciones de disparar y olvidar
  • Me hace pensar en pequeñas porciones de problemas, obligándome a separar la solución de pequeñas piezas que encajan entre sí.
  • Me hace escribir código muy desacoplado porque cada vez que tengo que tropezar / simular / falsificar algo que no encaja en el problema, naturalmente lanzo un "WTF, ¿por qué debería hacer esto si no tengo que estar conectado con él"? . Y me hace darme cuenta de las conexiones entre las cosas mejor.
  • Me da un conjunto de comprobaciones fácilmente ejecutables para mi código, por lo que no tengo que pasar por el doloroso estilo de depuración de código "var_dump", "p", "pp", "echo". Simplemente informa qué está mal, cuándo está mal. Y si todavía no tengo un cheque, solo es cuestión de agregar una prueba simple para verificarlo una y otra vez.
  • Me asegura que mi código funcione si todas las pruebas pasan antes de implementar. Luego, en lugar de comerme las uñas, voy a comer un pastel, tomar café y disfrutar de mis tardes.
  • Las pruebas de alto nivel son muy buenas en los casos en que tienes que refactorizar algo. Si mi módulo tiene que proporcionar alguna funcionalidad al mundo exterior y he desarrollado pruebas funcionales / de integración / de pepino para demostrar que funciona correctamente, seré muy valiente para refactorizar ese código. Varias veces me enfrenté al código que no tenía pruebas y necesitaba refactorizarlo. En ese caso, había dos formas de hacerlo en la práctica. 1) suelte el código 2) omita los cambios y déjelo como está.

Hay una cosa que TDD no soluciona. Si no sabe cómo construir lo que está construyendo, entonces TDD no producirá una solución para usted. Debe tener un "diseño" general o una descripción general del problema y la solución. TDD hará que lo implemente de manera más elegante y fácil de mantener con el código de mayor calidad.

Por último, prefiero pensar en términos de BDD que se apoyan en las prácticas de TDD. BDD me obliga a implementar una solución utilizando el vocabulario del dominio y hacer que el software se adapte mejor al problema.

ivanjovanovic
fuente
1

Puede haber muchas maneras de lograr un gran diseño, y hay indudablemente muchas interpretaciones diferentes de lo que constituye "excelente", o incluso "bueno". Sospecho que la mayoría de los TDDers no estarían de acuerdo con usted acerca de la definición: que si tuviéramos que ver el código que usted siente es excelente, lo consideraríamos menos que excelente. TDD nos lleva a algunas cualidades muy específicas, y estas cualidades rara vez se encuentran en el código no TDD.

La capacidad de prueba, obviamente, es una de esas cualidades, y la principal. Los métodos y clases extremadamente pequeños son quizás una subcaracterística, y esto lleva a una excelente nomenclatura. Quizás conoces a programadores que logran estas cualidades sin hacer TDD, pero yo no.

Carl Manaster
fuente
1
Seguramente encontrará estas mismas cualidades en el código producido por un proceso en cascada, por ejemplo, para el ejército, el espacio, etc. Supongo que es cierto que no son comunes en las versiones a medias de Agile y / o cascada practicadas en La mayoría de las organizaciones para proyectos cotidianos.
Aaronaught
@Aaronaught Dile eso al equipo Mars Climate Orbiter . :-)
Eric King
Tenía cierta experiencia con el proceso de cascada en proyectos militares sin armas en los años 90, y también mucha discusión sobre el enfriamiento del agua con veteranos de otras aplicaciones militares. El consenso general fue que la metodología de cascada y la facturación de costo adicional produjeron sistemas defectuosos que eran muy difíciles de mantener.
Kevin Cline