Qual é o lado negativo da sua experiência no TDD? Você acha os passos do bebê (a solução mais simples para tornar o teste verde) irritante e inútil? Você acha que a manutenção de testes sem valor (quando o teste tem sentido inicialmente, mas na implementação final verifica a mesma lógica dos outros testes) é essencial? etc.
As perguntas acima são sobre coisas com as quais me sinto desconfortável durante minha experiência no TDD. Então, estou interessado em saber se outros desenvolvedores têm sentimentos semelhantes e o que eles pensam deles.
Ficaria grato pelos links para os artigos que descrevem os lados negativos do TDD (o Google é preenchido por artigos positivos e muitas vezes fanáticos).
Respostas:
Como tudo o que vem sob o banner "Agile", o TDD é algo que soa bem na teoria, mas na prática não é tão claro o quão bom é (e também como a maioria das coisas "Agile", você é informado de que, se não o fizer, você está fazendo errado).
A definição de TDD não está gravada em pedra: caras como Kent Beck exigem que um teste não-compilador seja escrito antes de uma única linha de código e toda linha de código seja escrita para passar em um teste com falha. O design inicial é mínimo e tudo é impulsionadopelos testes. Simplesmente não funciona. Eu vi um grande aplicativo corporativo desenvolvido usando essa metodologia e espero que seja o pior código que vejo na minha carreira (não será muito distante; e isso apesar de ter alguns desenvolvedores talentosos trabalhando nisso). Pelo que vi, resulta em um grande número de testes mal pensados que validam principalmente que ocorrem chamadas de função, que exceções são lançadas quando as variáveis são nulas e a estrutura de zombaria recebe um treino completo (whoop-de-whoop); seu código de produção fica muito acoplado a esses testes e o sonho de refatoração constante e fácil não aparece - na verdade, as pessoas têm ainda menos probabilidade de corrigir códigos incorretos por causa de todos os testes que serão interrompidos.
Por outro lado, ouvi pessoas argumentarem que TDD significa projetar os testes antecipadamente em alto nível como parte da fase de planejamento - juntamente com o projeto arquitetônico. Esses testes podem mudar durante o desenvolvimento à medida que mais informações se tornam disponíveis, mas foram cuidadosamente considerados e oferecem um bom guia sobre o que o código realmente deve fazer. Para mim, isso faz todo o sentido.
fonte
Esta entrevista com Rich Hickey ( autor do Clojure ) contém o seguinte. Sinto-me 100% solidário:
Outra declaração semelhante de Donald Knuth na entrevista do livro Coders at Work , copiada e colada a partir daqui :
fonte
Minha experiência negativa com TDD foi minha primeira. O TDD me pareceu ótimo, eu fiz controle de qualidade por anos e ainda tinha os horrores frescos em minha mente. Eu queria esmagar todos os erros antes que ele se tornasse uma compilação. Infelizmente, o uso do TDD não garante que você escreva bons testes. De fato, minha predisposição inicial era escrever testes simples que gerassem código simples. Código realmente simples que continha poucas abstrações. Testes realmente simples que foram interligados com os internos da turma. E depois que você tiver alguns milhares de testes, você certamente não se sentirá mais rápido quando precisar alterar centenas deles para refatorar seu código e usar o conceito de domínio X muito importante.
A luz acendeu para mim - TDD não é uma habilidade de teste. É uma habilidade de design. Ele só pode levar você a um código bom, simples e viável, com prática e um conhecimento constante das instruções de design em que ele o leva. Se você estiver escrevendo testes para garantir a cobertura do código, criará testes frágeis. Se você estiver escrevendo testes para ajudá-lo a projetar suas abstrações, é apenas uma maneira mais rigorosa de escrever código de cima para baixo. Você vê o código da perspectiva do interlocutor primeiro, o que o incentiva a facilitar a vida dele, em vez de espelhar os componentes internos de uma classe para a borda externa.
Eu acho que o TDD é útil, mas não sou dogmático. Se esses "testes sem valor" estiverem dificultando a manutenção - exclua-os! Trato testes da mesma maneira que o resto do código. Se puder ser refatorado e tornar as coisas mais simples, faça-o!
Não o vi pessoalmente, mas ouvi dizer que alguns lugares rastreiam a cobertura do código e a contagem de testes. Portanto, se a coleta de métricas é um efeito colateral do TDD, também pude ver isso como negativo. Vou excluir com entusiasmo 1000 linhas de código e, se isso obsoleta 20 testes e diminui a minha cobertura de código%, tudo bem.
fonte
Eu vou sair por aqui e declarar com honestidade brutal que é literalmente uma perda de tempo ritualística. (Na maioria das situações.)
Comprei um livro sobre testes de unidade que também discutia o TDD e, embora eu concorde com os benefícios da UT, depois de cem horas experimentando o TDD, desisti dele por uma infinidade de razões. Eu sou tipo de postagem cruzada aqui, mas TDD:
Outra preocupação é o grau de perfeição debatido com o qual é preciso fazer TDD para fazê-lo com sucesso. Alguns insistem que, se o TDD não for feito persistentemente por todos da equipe desde o início do projeto, você só sofrerá. Outros insistem que ninguém faz TDD pelo livro. Se ambos são verdadeiros, segue-se que os praticantes de TDD estão sofrendo, percebendo ou não.
Obviamente, se estiver sendo argumentado que, ao fazer as coisas de maneira semelhante ao TDD, você encontrará projetos que podem funcionar facilmente com o TDD, bem, existem maneiras muito mais rápidas de conseguir isso - ou seja, estudando realmente os conceitos de composição. Existem muitos recursos por aí, muita teoria matemática rigorosa (em grande parte em programação funcional, mas também em outros campos). Por que não gastar todo o seu tempo TDD aprendendo ?
Culturalmente, o TDD mostra sintomas de ser uma prática ritualística. Ele cavalga por culpa; incentiva o procedimento acima da compreensão; ele tem toneladas de doutrinas e slogans ("fingir até que você faça" é realmente muito alarmante se você olhar objetivamente). A definição da Wikipedia da palavra "ritual" é de fato bastante apropriada:
fonte
Para acrescentar, outra preocupação com o TDD que notei é:
O TDD causa uma mudança inadvertida no foco da equipe de desenvolvimento de Código de Qualidade para Casos de Teste e Cobertura de Código! Pessoalmente, não gostei do TDD, pois me torna menos criativo e torna o desenvolvimento de software um processo mecânico monótono ! Os casos de teste de unidade são úteis quando usados criteriosamente, mas se tornam um fardo quando tratados como o objetivo do desenvolvimento de software.
Conheço um cara que é gerente e tecnicamente monótono uma vez ficou obcecado por TDD. Foi uma coisa tão mágica para ele que ele acreditava que traria soluções mágicas para todos os problemas em seu software mal arquitetado, com código menos sustentável. Para não dizer o que aconteceu com esse projeto - ele falhou miseravelmente em suas mãos, enquanto todas as suas caixas de teste eram verdes. Eu acho que o TDD o ajudou a obter algum tipo de informação estatística como "99/100 dos meus casos são verdes" etc. e esse foi o motivo de sua obsessão, pois ele nunca seria capaz de avaliar a qualidade ou sugerir melhorias no design.
fonte
Minha principal experiência negativa é tentar usar o TDD para editar o código de outro programador que não possui testes ou testes de integração muito, muito básicos. Quando vou adicionar um recurso ou corrigir um problema com o referido código; Eu preferiria escrever um teste primeiro (da maneira TDD). Infelizmente, o código está fortemente associado e não posso testar nada sem muita refatoração.
De qualquer forma, a refatoração é um ótimo exercício, mas é necessário que o código fique em um estado testável. E após esta etapa, não tenho freios e contrapesos para ver se minhas alterações quebraram alguma coisa; falta de executar o aplicativo e examinar todos os casos de uso.
Por outro lado, adicionar recursos / corrigir bugs a um projeto TDD se torna muito simples. Por natureza, o código escrito com TDD geralmente é bastante dissociado com pequenos pedaços para trabalhar.
De qualquer forma, o TDD é uma diretriz. Siga-o até o ponto em que você obtém a máxima eficácia. Cobertura de teste decente e código desacoplado, código bem escrito.
fonte
Fiz a experiência de que às vezes confio demais nos meus testes quando se trata do design do sistema. Eu sou basicamente muito baixo nos detalhes da implementação, para dar um passo atrás e olhar para o cenário mais amplo. Isso geralmente resulta em um design desnecessariamente complexo. Eu sei, devo refatorar o código, mas às vezes tenho a impressão de que poderia economizar muito tempo dando o passo para trás com mais frequência.
Dito isto, se você tiver uma estrutura como trilhos em que suas decisões de arquitetura são muito limitadas, esses problemas são basicamente inexistentes.
Outro problema é quando você confia cegamente em seus testes. A verdade é - como qualquer outro código - seus testes também podem ter erros. Portanto, seja tão crítico em relação aos seus testes quanto em sua implementação.
fonte
Como um grande fã de TDD, às vezes vejo essas desvantagens
Custos de manutenção do código de teste para testes semelhantes, que variam apenas um pouco (criados através da duplicação de código (também conhecida como herança de copiar e colar)). Se você já possui um, é fácil criar um semelhante. Mas se você não refatorar o código de teste, eliminando a duplicação de código em métodos auxiliares, poderá ser necessário algum tempo para corrigir os testes se os detalhes de implementação do seu código de negócios forem alterados.
Se você estiver sob pressão do tempo, pode ser tentado a eliminar testes quebrados (ou comentá-los) em vez de corrigi- los. Dessa forma, você perde o investimento nos testes
fonte
Ainda tenho que encontrar mais de um cenário como desenvolvedor de jogos em que o TDD valeu a pena. E o exemplo em que estava, era um pedaço de código puramente matemático por natureza e precisava de uma abordagem sólida para testar um grande número de casos extremos simultaneamente - uma necessidade rara.
Talvez alguma coisa, algum dia, mude de idéia, mas, entre as práticas do XP, a idéia de refatorar impiedosamente e de código que desenvolve sua própria forma é muito mais importante e leva à maior produtividade para mim, cf. uma citação de um artigo de James Newkirk :
Os conceitos de coragem e de apertar laços de feedback que ele menciona também são, na minha opinião, essenciais para a produtividade.
fonte
Minha experiência negativa no TDD, por mais limitada que seja, é simplesmente saber por onde começar! Por exemplo, tentarei fazer algo TDD e não tenho idéia de onde começar a barrar o teste de coisas triviais (posso criar um
Foo
objeto novo , posso passar umQuux
para oBaz
e assim por diante . Testes que não testam nada ) ou se estou tentando implementá-lo em um projeto existente, acho que precisaria reescrever várias classes para poder usá-las no TDD. O resultado final é que eu rapidamente abandono completamente a noção.Provavelmente não ajuda que muitas vezes eu seja a única pessoa em toda a empresa que saiba o que é o teste de unidade (TDD ou não) e por que é uma coisa boa.
fonte
Foo
com objetos Mock em vez deQuux
eBaz
diretamente, então você poderá chamar a função que deseja testar e verificar se os mock foram chamados com as funções que você espera. Objetos simulados são a tecnologia capacitadora que ajuda a desacoplar unidades e torná-las testáveis. É por isso que os singletons são maus, pois muitas vezes você não pode simplesmente zombar deles. * 8 ')Fanáticos de TDD.
Para mim, eles são apenas uma de uma longa fila de loucos religiosos batendo na minha porta, tentando provar que minha maneira de fazer as coisas é irreparavelmente quebrada e o único caminho para a salvação é Jesus, Kent Back ou Unit Testing.
Na IMO, a maior mentira é que o TDD levará você a
salvarum melhor design de algoritmo. Veja o famoso solucionador de Soduku escrito em TDD: aqui , aqui , aqui , aqui e aquiE compare-o com o solucionador de Peter Norvig sudoku, não usando TDD, mas usando engenharia antiquada: http://norvig.com/sudoku.html
fonte
Se você usar o TDD desses artigos "fanáticos", ficará com a segurança errada, sentindo que o seu software não possui erros.
fonte
TDD tem alguns benefícios:
TDD é sobre investimento de longo prazo. O esforço compensa quando você alcança o modo de manutenção do seu aplicativo e, se o aplicativo não estiver planejado para atingir esse ponto, você nunca poderá recuperar o investimento.
Considero o ciclo vermelho-verde do TDD com os pequenos passos semelhantes a uma lista de verificação para um avião. É chato e tedioso verificar tudo no avião antes da decolagem, especialmente se for trivialmente simples (os passos do bebê TDD), mas foi constatado que aumenta a segurança. Além de verificar se tudo funciona, redefine essencialmente o avião . Em outras palavras, um avião é reiniciado antes de cada decolagem.
fonte
Minha experiência negativa sobre TDD é algo que sinto com muitas coisas novas e sensacionalistas. Na verdade, eu gosto do TDD porque ele garante a validade do meu código e ainda mais importante: eu reconheço os testes com falha depois de adicionar um novo código ou qualquer tipo de refatoração.
O que me incomoda no TDD é o fato de que existem muitas regras ou diretrizes sobre isso. Como ainda é bastante novo, muitos de nós experimentamos ser iniciantes no TDD. Então, o que funciona bem para alguns de nós pode não funcionar para outros. O que eu quero dizer é que não existe uma maneira "certa ou errada" real de executar o TDD: existe a maneira que funciona para mim - e minha equipe, se eu tiver uma.
Portanto, desde que você escreva testes - antes ou depois do código de produção não importa realmente o IMHO -, não tenho certeza se o teste conduzido realmente significa que você deve seguir todas as diretrizes indicadas agora, uma vez que elas ainda não foram comprovadas. a solução ideal para o trabalho diário. Se você encontrar uma maneira melhor de escrever testes, publique-o em um blog, discuta-o aqui ou escreva um artigo sobre ele. Assim, em dez anos ou mais, poderíamos ter compartilhado experiência suficiente para poder dizer qual regra do TDD pode ser considerada boa ou não em uma determinada situação.
fonte
Em mais de uma ocasião, escrevi um código que descartei no dia seguinte, uma vez que era desajeitado. Eu reiniciei com TDD e a solução era melhor. Então, eu não tive muito na linha de experiência negativa no TDD. No entanto, dito isso, passei um tempo pensando em um problema e encontrando uma solução melhor fora do espaço TDD.
fonte
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.
fonte