El enfoque de "prueba de escritura + refactorización hasta pasar" parece increíblemente anti-ingeniería.
Parece tener una idea errónea sobre la refactorización y TDD.
La refactorización de código es el proceso de cambiar el código fuente de un programa de computadora sin modificar su comportamiento funcional externo para mejorar algunos de los atributos no funcionales del software.
Por lo tanto, no puede refactorizar el código hasta que pase.
Y TDD, específicamente las pruebas unitarias (que considero la mejora central, ya que otras pruebas me parecen plausibles), no se trata de rediseñar un componente hasta que funcione. Se trata de diseñar un componente y trabajar en la implementación hasta que el componente funcione como se diseñó.
También es importante comprender realmente que las pruebas unitarias se tratan de probar unidades . Debido a la tendencia a escribir siempre muchas cosas desde cero, es importante probar tales unidades. Un ingeniero civil ya conoce las especificaciones de las unidades que usa (los diferentes materiales) y puede esperar que funcionen. Estas son dos cosas que a menudo no se aplican a los ingenieros de software, y es muy profesional para probar las unidades antes de usarlas, porque significa usar componentes probados y de alta calidad.
Si un ingeniero civil tuvo la idea de usar un nuevo tejido de fibra para hacer un techo para cubrir un estadio, esperaría que lo pruebe como una unidad, es decir, defina las especificaciones necesarias (por ejemplo, peso, permeabilidad, estabilidad, etc.) y luego pruebe y refínelo hasta que los encuentre.
Por eso funciona TDD. Porque si crea software de unidades probadas, es mucho mejor que funcione, cuando las conecta y si no es así, puede esperar que el problema esté en su código de pegamento, suponiendo que sus pruebas tengan una buena cobertura.
editar:
Refactorización significa: sin cambios en la funcionalidad. Un punto de la prueba de la unidad de escritura es asegurarse de que la refactorización no rompa el código. Entonces, TDD tiene la intención de asegurar que la refactorización no tenga efectos secundarios.
La granularidad no es un tema de perspectiva, porque como dije, la unidad prueba las unidades de prueba y no los sistemas, por lo que la granularidad se define exactamente.
TDD fomenta la buena arquitectura. Requiere que defina e implemente especificaciones para todas sus unidades, lo que le obliga a diseñarlas antes de la implementación, lo cual es todo lo contrario de lo que parece pensar. TDD dicta la creación de unidades, que se pueden probar individualmente y, por lo tanto, se desacoplan por completo.
TDD no significa que arroje una prueba de software al código de espagueti y revuelva la pasta hasta que pase.
En contraposición a la ingeniería civil, en ingeniería de software un proyecto generalmente evoluciona constantemente. En ingeniería civil, tiene el requisito de construir un puente en la posición A, que pueda transportar x toneladas y sea lo suficientemente ancho para n vehículos por hora.
En ingeniería de software, el cliente básicamente puede decidir en cualquier momento (posiblemente después de la finalización), quiere un puente de dos pisos, y quiere que esté conectado con la autopista más cercana, y que le gustaría que fuera un puente de elevación, porque su compañía Recientemente comenzó a utilizar veleros.
Los ingenieros de software tienen la tarea de cambiar los diseños. No porque sus diseños sean defectuosos, sino porque ese es el modus operandi. Si el software está bien diseñado, se puede rediseñar a alto nivel, sin tener que reescribir todos los componentes de bajo nivel.
TDD se trata de construir software con componentes altamente desacoplados y probados individualmente. Bien ejecutado, lo ayudará a responder a los cambios en los requisitos significativamente más rápido y seguro que sin él.
TDD agrega requisitos al proceso de desarrollo, pero no prohíbe ningún otro método de garantía de calidad. Por supuesto, TDD no proporciona la misma seguridad que la verificación formal, pero, una vez más, la verificación formal es extremadamente costosa e imposible de usar a nivel de sistema. Y aún así, si quisieras, podrías combinar ambos.
TDD también abarca pruebas distintas de las pruebas unitarias, que se realizan a nivel de sistema. Encuentro esto fácil de explicar pero difícil de ejecutar y difícil de medir. Además, son bastante plausibles. Si bien veo absolutamente su necesidad, realmente no los valoro como ideas.
Al final, ninguna herramienta realmente resuelve un problema. Las herramientas solo facilitan la resolución de un problema. Puedes preguntar: ¿Cómo me ayudará un cincel con una gran arquitectura? Bueno, si planeas hacer paredes rectas, los ladrillos rectos son de ayuda. Y sí, claro, si le das esa herramienta a un idiota, probablemente la golpeará con el pie eventualmente, pero eso no es culpa del cincel, por mucho que no sea un defecto de TDD que da falsa seguridad a los novatos, quienes no escriben buenas pruebas.
Entonces, en el fondo, uno puede decir que TDD funciona mucho mejor que ningún TDD.