Eu descobri que o TDD tem um desempenho ruim quando se trata de sistemas emergentes. Sou desenvolvedor de videogames e recentemente usei o TDD para criar um sistema que usa vários comportamentos simples para criar um movimento realista para uma entidade.
Por exemplo, existem comportamentos responsáveis por afastá-lo de áreas perigosas de diferentes tipos e responsáveis por movê-lo para áreas interessantes de diferentes tipos. Amalgamar a saída de cada comportamento cria um movimento final.
As tripas do sistema foram implementadas facilmente, e o TDD foi útil aqui para especificar o que cada subsistema deve ser responsável.
No entanto, tive problemas ao especificar como os comportamentos interagem e, mais importante, como eles interagem com o tempo. Muitas vezes, não havia resposta certa e, embora meus testes iniciais estivessem passando, o controle de qualidade continuava encontrando casos extremos onde o sistema não funcionava. Para encontrar a solução correta, eu tive que repetir vários comportamentos diferentes e, se eu atualizasse os testes a cada vez para refletir os novos comportamentos antes de verificar se eles funcionavam no jogo, talvez eu acabasse jogando fora os testes várias vezes. Então eu apaguei esses testes.
Eu deveria ter tido testes mais fortes que capturaram os casos extremos que o controle de qualidade descobriu, mas quando você tem um sistema como esse que fica no topo de muitos sistemas de física e jogabilidade, e está lidando com comportamentos ao longo do tempo, isso se torna um pouco pesadelo para especificar exatamente o que está acontecendo.
Eu quase certamente cometi erros na minha abordagem e, como disse para o interior do sistema, o TDD funcionou brilhantemente e até apoiou alguns refatores otimizadores.