Quais são as desvantagens da programação em primeiro teste?

46

É toda a raiva hoje em dia. "Todo mundo" recomenda isso. Isso por si só me deixa desconfiada.

Quais são algumas das desvantagens que você encontrou ao desenvolver um teste (test-driven)? Estou à procura de experiências pessoais de praticantes experientes - eu posso ler as reflexões hipotéticas de centenas de candidatos em outros lugares na internet.

Eu não pergunto porque estou querendo odiar TDD, mas porque é meu trabalho melhorar o processo de desenvolvimento de software, e quanto mais pudermos aprender sobre os problemas que as pessoas enfrentam, maiores as chances de melhorar o processo.

    
por Alex Feinman 20.09.2010 / 15:24
fonte

9 respostas

41

Existem muito poucos, mas as vantagens longe superam as desvantagens.

Há uma curva de aprendizado acentuada.

Muitos desenvolvedores parecem esperar que possam ser eficientes com a programação do teste desde o primeiro dia. Infelizmente, leva muito tempo para ganhar experiência e programar na mesma velocidade de antes. Você não pode contornar isso.

Para ser mais específico, é muito fácil errar. Você pode facilmente (com boas intenções) acabar escrevendo um monte de testes que são difíceis de manter ou testar coisas erradas. É difícil dar exemplos aqui - esse tipo de problema simplesmente exige experiência para ser resolvido. Você precisa ter uma boa noção de separar preocupações e projetar para testabilidade. Meu melhor conselho aqui seria fazer programação em pares com alguém que conhece muito bem o TDD.

Você faz mais codificações na frente.

Teste primeiro significa que você não pode pular testes (o que é bom) e significa que você vai acabar escrevendo mais código na frente. Isso significa mais tempo. Mais uma vez, você não pode contornar isso. Você é recompensado com código que é mais fácil de manter, estender e geralmente menos bugs, mas isso leva tempo.

Pode ser uma tarefa difícil para os gerentes.

Os gerentes de software geralmente estão preocupados apenas com cronogramas. Se você mudar para a programação inicial e, de repente, levar duas semanas para concluir um recurso em vez de um, eles não vão gostar. Esta é definitivamente uma batalha que vale a pena lutar e muitos gerentes são esclarecidos o suficiente para obtê-la, mas pode ser difícil de vender.

Pode ser difícil de vender para outros desenvolvedores.

Como há uma curva de aprendizado íngreme, nem todos os desenvolvedores gostam de programar o primeiro teste. Na verdade, acho que os desenvolvedores mais não gostam disso no começo. Você pode fazer coisas como programação em pares para ajudá-los a acelerar, mas pode ser difícil de vender.

No final, as vantagens superam as desvantagens, mas não ajuda se você simplesmente ignorar as desvantagens. Saber com o que você está lidando desde o início ajuda você a negociar algumas, senão todas as desvantagens.

    
por 20.09.2010 / 15:27
fonte
35

Teste primeiro pressupõe que você está escrevendo um código que é:

  • testável em uma forma de teste de unidade
  • que o que você está desenvolvendo tem uma abordagem óbvia e não requer prototipagem ou experimentação extensiva
  • que você não precisará refatorar demais ou que terá tempo para reescrever repetidamente centenas ou milhares de casos de teste
  • nada é selado
  • tudo é modular
  • tudo é injetável ou reproduzível
  • que sua organização coloca um valor alto o suficiente em defeitos baixos para justificar o coletor de recursos
  • que há algo de benéfico para testar em um nível de teste de unidade

Se o seu projeto não atender a esses requisitos, você terá dificuldades. Os promotores do TDD não têm boas respostas para este outro para sugerir que você redesenhe o seu produto para melhor se enquadrar nessas linhas. Existem situações em que isso é impossível ou indesejável.

Na prática, também pode haver um grande problema com as pessoas que pensam que os primeiros testes realmente provam algo sobre a função correta do programa. Em muitos casos isso não é verdade, mas mesmo nos casos em que é verdade, está longe de ser um quadro completo de correção. As pessoas veem centenas de testes de aprovação e assumem que é seguro testar menos, já que antes do TDD eles faziam apenas algumas centenas de casos de teste. Na minha experiência, o TDD significa que você precisa ter ainda mais testes de integração, pois os desenvolvedores também terão a falsa segurança e a dor de alterar todos os testes para fazer um grande redator pode levar os desenvolvedores a fazer um trabalho interessante.

Exemplos:

Meu melhor exemplo pessoal é ao escrever código de segurança para o asp.net. Se eles forem executados em um ambiente hostil a partir da configuração da máquina, eles serão gaceados, assinados e lacrados e, como estão sendo executados em relação aos objetos de deus do IIS, é muito difícil reproduzir corretamente. Adicione algumas restrições para desempenho e uso de memória e você rapidamente perderá a flexibilidade de usar objetos de espaço reservado nas áreas restantes.

Qualquer tipo de microcontrolador ou outro código de ambiente de baixo recurso pode não ser possível para fazer um design de estilo OO real, já que as abstrações não otimizam e você tem limites baixos de recursos. O mesmo pode ser dito para rotinas de alto desempenho em muitos casos também.

    
por 20.09.2010 / 15:54
fonte
25

A maior desvantagem que eu vi não é com o TDD em si, mas com os praticantes. Eles adotam uma abordagem dogmática e fanática, onde tudo deve ser testado. Às vezes (muitas vezes isso é), isso não é necessário. Além disso, pode não ser prático (ou seja, introduzir uma organização no TDD).

Um bom engenheiro encontra trade-offs e aplica o equilíbrio correto de quando / onde / como aplicar primeiro o teste. Além disso, se você está constantemente gastando muito mais tempo desenvolvendo testes em vez de um código real (por um fator de 2-3 ou mais), você está com problemas.

Em outras palavras, seja pragmático e razoável com o TDD (ou qualquer outra coisa relacionada ao desenvolvimento de software).

    
por 14.10.2010 / 18:32
fonte
6

Comecei a fazer o TDD no início de agosto de 2009 e convenci toda a minha empresa a mudar para ele em setembro / outubro de 2009. Atualmente, toda a equipe de desenvolvedores está totalmente convertida e enviar código não testado para o repositório é considerado uma Coisa Má e lançada. em cima. Tem funcionado muito bem para nós e não consigo imaginar voltar à codificação cowboy.

No entanto, existem dois problemas que são bastante visíveis.

O conjunto de testes deve ser mantido

Quando você estiver falando sério sobre o TDD, você acabará escrevendo lotes de testes. Além disso, é preciso algum tempo e experiência para perceber qual é a granularidade dos testes (o excesso de desempenho é quase tão ruim quanto o subdesenvolvimento). Esses testes também são código , e eles são suscetíveis ao bitrot. Isso significa que você precisa mantê-las como todo o resto: atualize-as quando atualizar as bibliotecas das quais elas dependem, refatorie de tempos em tempos ... Quando você faz grandes mudanças em seu código, muitos testes de repente ficam desatualizados ou mesmo errado. Se tiver sorte, você pode simplesmente excluí-los, mas muitas vezes você acabará extraindo os bits úteis e adaptando-os à nova arquitetura.

Abstrações de teste vazam de tempos em tempos

Estamos usando o Django, que tem uma ótima estrutura de testes. No entanto, às vezes, faz suposições que estão ligeiramente em desacordo com a realidade. Por exemplo, alguns middlewares podem quebrar os testes. Ou, alguns testes fazem suposições sobre um back-end de armazenamento em cache. Além disso, se você estiver usando um banco de dados "real" (não SQLite3), preparar o banco de dados para os testes levará muito tempo. Claro, você pode (e deve) usar o SQLite3 e um db na memória para testes que você faz localmente, mas algum código irá se comportar de maneira diferente dependendo do banco de dados que você usa. Configurar um servidor de integração contínua que é executado em uma configuração realista é uma obrigação.

(Algumas pessoas vão dizer que você deve zombar de todas as coisas como o banco de dados, ou seus testes não são "puros", mas isso é apenas ideologia falando. Se você cometer erros no seu código de zombaria (e acredite, você vai), seu testuite será inútil.)

Tudo isso dito, os problemas que descrevi começam a ser perceptíveis somente quando você está bastante avançado com o TDD ... Quando você está apenas começando com o TDD (ou trabalhando em projetos menores), a refatoração de teste não será um problema.

    
por 09.10.2010 / 19:05
fonte
4

Para mim, há alguns problemas psicológicos profundos com testes sempre que eu tento aplicá-los extensivamente, como em TDD: se eles estão lá, eu codifico de forma desleixada porque confio que os testes detectarão algum problema. Mas, se não houver testes para fornecer uma rede de segurança, codifico com cuidado e o resultado é invariavelmente melhor do que com testes.

Talvez seja só eu. Mas eu também li em algum lugar que carros com todos os tipos de sinos de segurança & assobios tendem a bater mais (porque os motoristas sabem que os recursos de segurança estão lá), então talvez isso seja algo a ser reconhecido; TDD pode ser incompatível com alguns indivíduos.

    
por 14.10.2010 / 19:04
fonte
2

Uma situação em que o teste em primeiro lugar realmente fica no meu caminho é quando eu quero testar rapidamente uma ideia e ver se ela funciona antes de escrever uma implementação adequada.

Minha abordagem é normalmente:

  1. Implemente algo que seja executado (prova de conceito).
  2. Se funcionar, consolide adicionando testes, aprimorando o design e refatorando.

Às vezes, não chego ao passo 2.

Neste caso, usar o TDD acabou por ter mais desvantagens do que vantagens para mim:

  • Escrever testes durante a implementação da prova de conceito apenas me atrapalha e interrompe meu fluxo de pensamentos: quero entender uma ideia e não quero perder tempo testando detalhes da minha primeira implementação aproximada.
  • Pode levar mais tempo para descobrir se minha ideia vale ou não alguma coisa.
  • Se a ideia for inútil, tenho que jogar fora meu código e meus testes de unidade bem escritos.

Então, quando tenho que explorar algumas ideias novas, não uso o TDD e apenas introduzo testes de unidade quando tenho a sensação de que o novo código está chegando a algum lugar.

    
por 06.10.2014 / 08:53
fonte
1

Desvantagens ou custos de TDD

Nota: Existe uma variedade de diferentes tipos de TDD. Independentemente da unidade, BDD, ATDD ou outras variantes, muitas das dificuldades permanecem

Efeitos colaterais

Quer se trate de mocking, fixtures ou testes funcionais, dependências em estados ou sistemas externos são muitas vezes a fonte de maior complexidade em testes, confusão em como testar e maior risco de errar. Alguns problemas que vi:

  • Mocking: esqueça de confirmar a ordem das chamadas
  • Mocking: a simulação não corresponde à chamada ou resposta real
  • Fixture: o teste depende de dados irrealistas, mascarando outros problemas
  • Fixture: teste um estado impossível na produção
  • Funcional: a criação falsa é interrompida porque o sistema dependente está temporariamente indisponível
  • Funcional: a velocidade do teste é muito lenta

Você terá que mudar sua abordagem de codificação, para alguns, será uma mudança drástica.

Diferentes pessoas codificam de formas muito diferentes. No TDD, você precisa começar com um teste que defina um comportamento específico e implementar para que o teste seja aprovado. Eu vi e era um programador cuja programação não era propícia ao TDD. Demorei cerca de dois meses quando comecei a me acostumar a mudar minha abordagem de desenvolvimento.

Leva tempo para entender o que você gosta de testar e o que você não se importa em testar.

Cada equipe deve tomar uma decisão explícita sobre onde deseja traçar a linha nos testes. Que coisas eles valorizam que querem testadas e o que não. Muitas vezes, é um processo doloroso aprender a escrever bons testes e o que você realmente se importa com os testes. Enquanto isso, o código continuará em um estado de fluxo até que haja consistência no estilo e na abordagem.

Teste de unidade específico: grandes refatoras

Um refator grande ou fundamental de uma base de código significativa com dezenas de milhares de testes unitários gerará um custo enorme para atualizar todos os testes. Isso muitas vezes se manifestará no retrocesso em se fazer um refatorador, mesmo que seja a coisa correta a se fazer, simplesmente porque o custo está associado a fazê-lo.

    
por 06.10.2014 / 10:38
fonte
0

Minha analogia é barreiras em uma trilha Scalextric. Se você colocá-los, você fica muito menos cauteloso.

As pessoas também obtêm um pouco de cadetes espaciais sobre seus testes - porque elas funcionam bem, elas acreditam que o código é totalmente testado, enquanto é apenas o começo do processo de teste.

Na minha opinião, o TDD é um trampolim para o BDD. Uma série de testes que são executados não ajuda realmente os desenvolvedores sem saber o que os testes fazem. Com o BDD, o resultado do teste é em inglês, o que documenta o teste e, assim, constrói a compreensão do sistema.

    
por 06.10.2014 / 13:52
fonte
-1

Os benefícios do TDD são que obriga você a guardar seu código contra pessoas que não o entendem. Sim, isso geralmente inclui você mesmo. Mas o que acontece quando o código não vale a pena ser guardado? Há um monte de código que nem deveria estar lá em primeiro lugar! Portanto, o problema com o TDD é quando se trata de desenvolvedores que escrevem código incorreto. TDD provavelmente não vai ajudá-los a escrever bons códigos, é muito mais provável que eles também escrevam testes horríveis. Assim, no caso deles, o TDD só aumentará a bagunça; testes mal escritos e / ou redundantes não são mais divertidos do que outras formas de códigos ruins.

    
por 06.10.2014 / 09:46
fonte