Experiência negativa do TDD [fechada]

93

Qual é o lado negativo da sua experiência com o TDD? Você acha que os passos do bebê (a solução mais simples para tornar o teste verde) são irritantes e inúteis? Você encontra testes sem valor (quando o teste tem sentido inicialmente, mas na implementação final verifica a mesma lógica que outros testes)? etc.

As perguntas acima são sobre coisas com as quais me sinto desconfortável durante a minha experiência com o TDD. Então, estou interessado em saber se outros desenvolvedores têm sentimentos semelhantes e o que pensam sobre eles.

Agradecemos os links para artigos que descrevem os lados negativos do TDD (o Google é preenchido por artigos positivos e muitas vezes fanáticos).

    
por Idsa 04.08.2011 / 09:04
fonte

16 respostas

93

Como tudo o que vem sob o banner "Ágil", TDD é algo que soa bem na teoria, mas na prática não é tão claro como é bom (e também como a maioria das coisas "ágeis", você é informado que se não goste, você está fazendo errado).

A definição de TDD não está gravada na pedra: caras como Kent Beck exigem que um teste de não-compilação deve ser escrito antes de uma única linha de código e cada linha de código deve ser escrita para passar em um teste com falha. O design frontal é mínimo e tudo é dirigido pelos testes. Isso simplesmente não funciona. Eu vi um grande aplicativo corporativo desenvolvido usando essa metodologia e espero que seja o pior código que eu vejo na minha carreira (não vai estar longe; e isso apesar de ter alguns desenvolvedores talentosos trabalhando nisso). Pelo que eu vi isso resulta em um grande número de testes mal pensados que validam principalmente que chamadas de função ocorrem, que exceções são lançadas quando as variáveis são nulas e a estrutura de simulação recebe um treino completo (whoop-de-whoop); seu código de produção fica strongmente acoplado a esses testes e o sonho de refatoração constante e fácil não aparece - na verdade, as pessoas são menos propensas a corrigir códigos ruins por causa de todos os testes que serão quebrados. Nesse tipo de ambiente, os gerentes de software preferem ter software ruim com testes de aprovação e alta cobertura de código do que um bom software com menos testes.

Por outro lado, ouvi pessoas argumentarem que o TDD significa projetar os testes antecipadamente em um 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 deve realmente fazer. Para mim, isso faz todo o sentido.

    
por 28.10.2011 / 16:39
fonte
65

Este ( Clojure autor) Entrevista com Rich Hickey contém o seguinte. Eu me sinto 100% compreensivo:

Life is short and there are only a finite number of hours in a day. So, we have to make choices about how we spend our time. If we spend it writing tests, that is time we are not spending doing something else. Each of us needs to assess how best to spend our time in order to maximize our results, both in quantity and quality. If people think that spending fifty percent of their time writing tests maximizes their results—okay for them. I’m sure that’s not true for me—I’d rather spend that time thinking about my problem. I’m certain that, for me, this produces better solutions, with fewer defects, than any other use of my time. A bad design with a complete test suite is still a bad design.

Outra declaração semelhante de Donald Knuth em Coders no trabalho entrevista em livro, copiada e colada de aqui :

Seibel: Speaking of practical work, in the middle of working on The Art of Computer Programming you took what turned into a ten-year break to write your typesetting system TeX. I understand you wrote the first version of TeX completely away from the computer.

Knuth: When I wrote TeX originally in 1977 and ’78, of course I didn’t have literate programming but I did have structured programming. I wrote it in a big notebook in longhand, in pencil. Six months later, after I had gone through the whole project, I started typing into the computer. And did the debugging in March of ’78 while I had started writing the program in October of ’77. The code for that is in the Stanford archives—it’s all in pencil—and of course I would come back and change a subroutine as I learned what it should be. This was a first-generation system, so lots of different architectures were possible and had to be discarded until I’d lived with it for a while and knew what was there. And it was a chicken-and-egg problem—you couldn’t typeset until you had fonts but then you couldn’t have fonts until you could typeset. But structured programming gave me the idea of invariants and knowing how to make black boxes that I could understand. So I had the confidence that the code would work when I finally would debug it. I felt that I would be saving a lot of time if I waited six months before testing anything. I had enough confidence that the code was approximately right.

Seibel: And the time savings would be because you wouldn’t spend time building scaffolding and stubs to test incomplete code?

Knuth: Right.

    
por 04.08.2011 / 23:00
fonte
55

Minha experiência negativa com o TDD foi minha primeira. TDD soou ótimo para mim, eu fiz QA por anos e ainda tinha os horrores frescos em minha mente. Eu queria esmagar todos os erros antes que ele se transformasse em uma compilação. Infelizmente, usar o TDD não garante que você irá escrever bons testes. Na verdade, 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 entrelaçados com os internos da classe. E uma vez que você tenha alguns milhares de testes, você certamente não sentirá que está se movendo mais rápido quando tiver que mudar uma centena deles para refatorar seu código para usar o conceito de domínio X muito importante.

A luz veio para mim - o 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 uma percepção constante das direções de design que ele leva. Se você está escrevendo testes para obter uma cobertura de código, vai criar testes frágeis. Se você está escrevendo testes para ajudá-lo a projetar suas abstrações, então é apenas uma maneira mais rigorosa de escrever código de cima para baixo. Você consegue ver o código da perspectiva do interlocutor primeiro, o que o encoraja a tornar sua vida mais fácil, em vez de espelhar os aspectos internos de uma classe à sua borda externa.

Eu acho que o TDD é útil, mas eu não sou dogmático sobre isso. Se esses "testes sem valor" dificultam a manutenção - Exclua-os! Eu trato os testes da mesma maneira que o resto do código. Se for possível refatorar e simplificar as coisas, faça isso!

Eu não o vi pessoalmente, mas ouvi dizer que alguns lugares rastreiam a cobertura do código e as contagens de teste. Portanto, se a coleta de métricas é um efeito colateral do TDD, também posso ver isso como negativo. Eu vou com entusiasmo excluir 1000 linhas de código, e se isso obsoleta 20 testes e baixa minha% de cobertura de código, tudo bem.

    
por 05.08.2011 / 13:39
fonte
40

Eu vou sair em um membro aqui e declarar com honestidade brutal que é literalmente um desperdício de tempo ritualístico. (Na maioria das situações.)

Eu comprei um livro sobre Testes Unitários, que também discutia TDD, e embora eu concorde com os benefícios da UT, depois de cerca de cem horas experimentando TDD, desisti disso por uma infinidade de razões. Eu sou tipo de postagem cruzada aqui, mas TDD:

  1. Não é melhor documentação do que documentação real.
  2. Não detecta erros ou regressões .
  3. Realmente não torna meus projetos melhores do que acabam sendo se eu aplicar alguns conceitos de programação funcional e composability .
  4. É o tempo que poderia ser mais bem gasto fazendo revisões de código ou aprimorando a documentação e as especificações.
  5. Dá aos gerentes uma falsa sensação de segurança quando veem uma lista de centenas de ícones verdes.
  6. Aumenta a produtividade na implementação de algoritmos com mapeamentos de entrada-saída limitados.
  7. É desajeitado, pois você pode saber o que está fazendo como resultado do TDD, mas não está entendendo de por que ele funciona tão bem, por que seus designs saem do jeito que eles fazem.
Outra preocupação é o grau de perfeição debatido em que se deve fazer o 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 nunca faz TDD pelo livro. Se ambos são verdadeiros, segue-se que os praticantes de TDD estão sofrendo, quer eles percebam isso ou não.

Claro, se estivermos argumentando que, ao fazer as coisas de maneira semelhante ao TDD, você chegará a designs que podem funcionar facilmente com o TDD, bem, há maneiras muito mais rápidas de se conseguir isso - ou seja, estudar de fato os conceitos de composibilidade. Há muitos recursos por aí, muita teoria matemática rigorosa (principalmente em programação funcional, mas também em outros campos). Por que não gastar todo o seu tempo de TDD aprendendo ?

Culturalmente, o TDD mostra sintomas de ser uma prática ritualística. Ele monta em culpa; estimula o procedimento sobre a compreensão; tem toneladas de doutrinas e slogans ("fingir até você conseguir" é realmente muito alarmante se você olhar objetivamente). A definição da Wikipedia sobre a palavra "ritual" é, na verdade, bastante apropriada:

In psychology, the term ritual is sometimes used in a technical sense for a repetitive behavior systematically used by a person to neutralize or prevent anxiety; it is a symptom of obsessive–compulsive disorder.

    
por 12.04.2017 / 09:31
fonte
17

Para adicionar, outra preocupação com o TDD que notei é:

O TDD causa uma mudança inadvertida no foco da equipe de desenvolvimento do Código de Qualidade para as Capas de Teste e a Cobertura de Código! Eu pessoalmente não gostei do TDD, pois ele me torna menos criativo e torna o desenvolvimento de software um processo mecânico chato ! Os testes de unidade são úteis quando usados criteriosamente, mas se tornam um fardo quando tratados com o objetivo de desenvolvimento de software.

Eu conheço um cara que é um gerente e é tecnicamente insípido uma vez obcecado pelo TDD. Era 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 o 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 carteiras 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 essa foi a razão de sua obsessão, pois ele nunca seria capaz de avaliar a qualidade ou sugerir melhorias no design.

    
por 10.08.2011 / 07:16
fonte
14

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 básicos. Quando vou adicionar um recurso, ou corrigir um problema com o dito código; Eu preferiria escrever um teste primeiro (o modo TDD). Infelizmente, o código está strongmente acoplado e não posso testar nada sem muita refatoração.

A refatoração é um ótimo exercício, mas é necessário para colocar o código em um estado testável. E depois desse passo, não tenho freios e contrapesos para ver se minhas mudanças quebraram alguma coisa; curto de executar o aplicativo e examinar cada caso de uso.

Por outro lado, adicionar recursos / corrigir erros em um projeto TDD se torna muito simples. Por natureza, o código escrito com o TDD é geralmente bastante desacoplado com pequenos pedaços para trabalhar.

Em qualquer caso, o TDD é uma diretriz. Siga-o ao ponto em que você acha que obtém a máxima eficácia. Cobertura de teste decente e código desacoplado, código bem escrito.

    
por 04.08.2011 / 17:38
fonte
12

Eu fiz a experiência que às vezes confio muito nos meus testes quando se trata do design do sistema. Eu sou basicamente muito baixo em detalhes de implementação para dar o passo atrás para olhar o quadro maior. 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 um passo atrás com mais frequência.

Dito isto, se você tem um framework como os rails, onde suas decisões arquiteturais são muito limitadas, esses problemas são basicamente inexistentes.

Outro problema é quando você confia em seus testes cegamente. A verdade é - como qualquer outro código - seus testes podem ter erros também. Portanto, seja tão crítico em relação aos seus testes quanto sua implementação.

    
por 12.11.2018 / 18:58
fonte
11

Como grande fã de TDD, às vezes vejo essas desvantagens

  • Tentação de escrever muitos testes em prol de quase 100% de cobertura de código. Na minha opinião, não é necessário escrever testes
    • para getters / setters de propriedade simples
    • para todos os casos em que uma exceção é lançada
    • verifica a mesma funcionalidade por diferentes camadas. (Exemplo: se você tem um teste unitário para verificar a validação de entrada para cada parâmetro, então não é necessário repetir todos esses testes por meio de um teste de integração também)
  • Custos de manutenção do código de teste para testes semelhantes, que variam apenas levemente (criados por meio de duplicação de código (também conhecido como copy-paste-inheritance)). Se você já tem um, é fácil criar um similar. Mas, se você não refatorar o código de teste, eliminando a duplicação de código nos métodos auxiliares, poderá precisar de algum tempo para corrigir os testes, caso os detalhes de implementação de seu código de negócios sejam alterados.

  • Se você estiver sob pressão de tempo , poderá ficar tentado a eliminar testes quebrados (ou comentá-los) em vez de corrigir eles. Desta forma você perde o investimento nos testes

por 15.02.2014 / 02:34
fonte
9

Ainda não encontrei mais de um cenário como desenvolvedor de jogos em que o TDD valeu a pena. E a instância em que estava, era um código que era puramente matemático por natureza e precisava de uma abordagem sólida para testar um grande número de casos de borda simultaneamente - uma necessidade rara.

Talvez algo, algum dia, mude de ideia, mas entre as práticas do XP, a idéia de refatorar impiedosamente e de desenvolver o código em si é muito mais importante e levar para a maior produtividade para mim, cf. uma citação de um artigo de James Newkirk :

Simplicity - "What is the simplest thing that could possibly work?"
The message is very clear. Given the requirements for today, design and write your software. Do not try to anticipate the future, let the future unfold. It will often do this in very unpredictable ways making anticipation a cost that is often too expensive to afford."

Os conceitos de coragem e de apertar feedback , loops que ele menciona também são, em minha opinião, a chave para a produtividade.

    
por 04.08.2011 / 13:20
fonte
7

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 saberá onde começar a bloquear testes de coisas triviais (posso criar um objeto Foo , posso passar um Quux para o Baz e Testes que não testam nada), ou se eu estou tentando implementá-lo em um projeto existente, então eu acho que eu teria que reescrever várias classes para poder usá-los em 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 sabe o que é o teste unitário (TDD ou de outra forma) e porque é uma coisa boa.

    
por 04.08.2011 / 17:00
fonte
7

Zelotes do TDD.

Para mim, eles são apenas um de uma longa lista de loucos religiosos batendo à minha porta, tentando provar que meu jeito de fazer as coisas está irreparavelmente quebrado e que o único caminho para a salvação é Jesus, Kent Back, ou Teste Unitário.

IMO, a maior mentira deles é que o TDD levará você à salvação a um melhor design de algoritmo. Veja o famoso solucionador Soduku escrito em TDD: aqui , aqui , aqui , aqui e aqui

E compare-o com o solucionador de sudoku de Peter Norvig usando o TDD, mas usando a engenharia antiga: link

    
por 04.04.2016 / 13:16
fonte
4

Se você usar o TDD a partir desses artigos "fanáticos", você terá a sensação errada de que seu software não apresenta erros.

    
por 04.08.2011 / 09:24
fonte
4

TDD tem alguns benefícios:

  • Você se concentra em como para chamar seu código e o que esperar primeiro (ao escrever o teste primeiro) em vez de se concentrar em resolver o problema e depois colá-lo na aplicação. A modularidade facilita a simulação e o envolvimento.
  • Os testes garantem que seu programa funcione da mesma maneira antes e depois de uma refatoração. Isso não significa que seu programa está livre de erros, mas que continua funcionando da mesma maneira.

O TDD é sobre investimento a longo prazo. O esforço é compensado quando você acessa o modo de manutenção de seu aplicativo e, se o aplicativo não for planejado para chegar a esse ponto, talvez você nunca recupere o investimento.

Eu considero o ciclo vermelho-verde de TDD com os passos do bebê semelhantes a uma lista de verificação para um avião. É chato e tedioso verificar cada uma das coisas no avião antes da decolagem, especialmente se for trivialmente simples (os passos de bebê TDD), mas verificou-se que aumenta a segurança. Além de verificar tudo funciona, essencialmente redefine o plano . Em outras palavras, um avião é reinicializado antes de cada decolagem.

    
por 04.08.2011 / 22:17
fonte
3

Minha experiência negativa sobre o TDD é algo que sinto com muitas coisas novas e sensacionalistas. Na verdade, gosto de TDD porque garante a validade do meu código e, o que é ainda mais importante: posso reconhecer testes com falha, depois de adicionar um novo código ou qualquer tipo de refatoração.

O que me incomoda sobre o TDD é o fato de que há muitas regras ou diretrizes sobre isso. Como ainda é muito novo, a maioria de nós experimenta ser iniciante no TDD. Então, o que funciona bem para alguns de nós, pode não funcionar para os outros. O que eu quero dizer é que não existe uma maneira "certa ou errada" de realizar o TDD: existe o jeito que funciona para mim - e a minha equipe se eu tiver uma.

Portanto, contanto que você escreva testes - antes ou depois do código de produção não importa IMHO - eu não tenho certeza se o teste realmente significa que você tem que seguir todas as diretrizes que são apresentadas agora, já que elas ainda não são provou ser a solução ideal para o trabalho diário. Se você encontrar uma maneira melhor de escrever testes, você deve publicá-la em um blog, discuti-la aqui ou escrever um artigo sobre ela. Assim, em dez anos ou mais, poderíamos ter compartilhado experiência suficiente para saber qual regra do TDD pode ser considerada boa ou não em uma determinada situação.

    
por 05.08.2011 / 08:42
fonte
3

Eu tenho, em mais de uma ocasião, código escrito que descartei no dia seguinte, já que era desajeitado. Eu reiniciei com o TDD e a solução foi melhor. Então eu não tive muito na linha de experiência negativa do TDD. No entanto, tendo dito isso, passei algum tempo pensando sobre um problema e encontrando uma solução melhor fora do espaço TDD.

    
por 05.08.2011 / 11:25
fonte
3

Eu descobri que o TDD tem um desempenho ruim quando se trata de sistemas emergentes. Sou desenvolvedor de jogos de vídeo e recentemente usei o TDD para criar um sistema que usa vários comportamentos simples para criar movimentos realistas para uma entidade.

Por exemplo, há comportamentos responsáveis por afastá-lo de áreas perigosas de tipos diferentes e responsáveis por direcioná-lo para áreas interessantes de tipos diferentes. Amalgamação da saída de cada comportamento cria um movimento final.

As entranhas do sistema foram implementadas facilmente, e o TDD foi útil aqui para especificar o que cada subsistema deveria ser responsável.

No entanto, tive problemas ao especificar como os comportamentos interagem e, mais importante, como eles interagem ao longo do tempo. Muitas vezes, não havia resposta certa e, embora meus testes iniciais estivessem passando, o departamento de QA continuava a encontrar casos extremos em que o sistema não funcionava. Para encontrar a solução correta, tive que fazer uma iteração de vários comportamentos diferentes, e se eu atualizasse os testes toda vez para refletir os novos comportamentos antes de verificar que funcionavam no jogo, talvez acabasse jogando os testes uma e outra vez. Então eu deletei esses testes.

Eu deveria ter tido testes mais strongs que capturaram os casos de borda QA descobertos, mas quando você tem um sistema como esse que fica em cima de muitos sistemas de física e jogabilidade, e você está lidando com Com o passar do tempo, torna-se um pesadelo especificar exatamente o que está acontecendo.

Eu quase com certeza cometi erros na minha abordagem, e como eu disse para a coragem do sistema, o TDD funcionou de forma brilhante, e até mesmo apoiou alguns poucos refatoradores otimizadores.

    
por 09.08.2011 / 09:54
fonte

Tags