A abordagem "teste de gravação + refatoração até aprovação" parece incrivelmente anti-engenharia.
Você parece ter um equívoco sobre refatoração e TDD.
A refatoração de código é o processo de alterar o código-fonte de um programa de computador sem modificar seu comportamento funcional externo, a fim de melhorar alguns dos atributos não funcionais do software.
Portanto, você não pode refatorar o código até que ele passe.
E o TDD, especificamente o teste de unidade (que considero a melhoria principal, já que outros testes me parecem bastante plausíveis), não se trata de redesenhar um componente até que ele funcione. Trata-se de projetar um componente e trabalhar na implementação até que o componente funcione conforme projetado.
Também é importante entender, que o teste de unidade é sobre unidades de teste . Devido à tendência de sempre escrever muitas coisas do zero, é importante testar essas unidades. Um engenheiro civil já conhece as especificações das unidades que ele usa (os diferentes materiais) e pode esperar que funcionem. Essas são duas coisas que geralmente não se aplicam aos engenheiros de software, e é muito pró-engenharia testar as unidades antes de usá-las, porque significa usar componentes testados e de alta qualidade.
Se um engenheiro civil teve a idéia de usar um novo tecido de fibra para fazer um telhado para cobrir um estádio, seria de esperar que ele o testasse como uma unidade, ou seja, defina as especificações necessárias (por exemplo, peso, permeabilidade, estabilidade etc.) e depois teste e refine-o até encontrá-los.
É por isso que o TDD funciona. Como se você criar um software de unidades testadas, as chances são muito melhores de funcionar. Quando você as conecta e, se não, pode esperar que o problema esteja no seu código de cola, supondo que seus testes tenham uma boa cobertura.
editar:
Refatoração significa: nenhuma alteração na funcionalidade. Um ponto de escrever o teste de unidade é garantir que a refatoração não quebre o código. Portanto, o TDD deve garantir que a refatoração não tenha efeitos colaterais.
A granularidade não é um assunto de perspectiva, porque, como eu disse, a unidade testa unidades de teste e não sistemas, nos quais a granularidade é exatamente definida.
O TDD incentiva uma boa arquitetura. Requer que você defina e implemente especificações para todas as suas unidades, forçando-as a projetá-las antes da implementação, o que é exatamente o contrário do que você pensa. O TDD determina a criação de unidades, que podem ser testadas individualmente e, portanto, completamente dissociadas.
TDD não significa que eu faça um teste de software com código espaguete e mexa a massa até que ela passe.
Ao contrário da engenharia civil, na engenharia de software um projeto geralmente evolui constantemente. Na engenharia civil, você tem a exigência de construir uma ponte na posição A, que pode transportar x toneladas e é larga o suficiente para n veículos por hora.
Na engenharia de software, o cliente pode basicamente decidir, a qualquer momento (possivelmente após a conclusão), que ele quer uma ponte de dois andares e que ela esteja conectada à rodovia mais próxima e que gostaria que fosse uma ponte de elevação, porque sua empresa recentemente começou a usar navios à vela.
Os engenheiros de software têm a tarefa de alterar os projetos. Não porque seus projetos são falhos, mas porque esse é o modus operandi. Se o software for bem projetado, ele poderá ser reprojetado em alto nível, sem precisar reescrever todos os componentes de baixo nível.
TDD é sobre a construção de software com componentes individualmente dissociados e altamente dissociados. Bem executado, ajudará você a responder a alterações nos requisitos significativamente mais rápidas e seguras do que sem.
O TDD adiciona requisitos ao processo de desenvolvimento, mas não proíbe outros métodos de garantia de qualidade. É verdade que o TDD não oferece a mesma segurança que a verificação formal, mas, novamente, a verificação formal é extremamente confortável e impossível de usar no nível do sistema. E ainda assim, se você quiser, poderá combinar os dois.
O TDD também abrange outros testes que não os testes de unidade, que são executados no nível do sistema. Acho isso fácil de explicar, mas difícil de executar e difícil de medir. Além disso, eles são bastante plausíveis. Embora eu veja absolutamente a necessidade deles, não os valorizo realmente como idéias.
No final, nenhuma ferramenta realmente resolve um problema. As ferramentas apenas facilitam a solução de um problema. Você pode perguntar: Como um cinzel vai me ajudar com uma ótima arquitetura? Bem, se você planeja fazer paredes retas, tijolos retos são úteis. E sim, é verdade, se você der essa ferramenta a um idiota, ele provavelmente a enfiará no pé, mas isso não é culpa do cinzel, por mais que não seja uma falha do TDD que dê segurança falsa aos novatos, quem não escreve bons testes.
Então, no final das contas, pode-se dizer que o TDD funciona muito melhor do que nenhum TDD.