ti-enxame.com

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

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

Quais são algumas desvantagens que você encontrou ao fazer o desenvolvimento de teste primeiro (orientado a teste)? Estou procurando experiências pessoais de profissionais experientes - posso ler as reflexões hipotéticas de uma centena de aspirantes a outros lugares da Internet.

Não pergunto porque estou querendo odiar o TDD, mas porque é meu trabalho melhorar o processo de desenvolvimento de software e quanto mais aprendermos sobre os problemas que as pessoas encontram, maior a chance de melhorar o processo.

48
Alex Feinman

Existem algumas, mas as vantagens são muito maiores superam as desvantagens.

Existe uma curva de aprendizado acentuada.

Muitos desenvolvedores parecem esperar que possam ser eficientes com a programação de teste primeiro 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 muito facilmente (com muito boas intenções) escrever vários testes 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 idéia de separar as preocupações e projetar a testabilidade. Meu melhor conselho aqui seria programar em pares com alguém que conhece muito bem o TDD.

Você faz mais codificação antecipadamente.

O teste primeiro significa que você não pode pular testes (o que é bom) e significa que você acabará escrevendo mais código com antecedência. Isso significa mais tempo. Novamente, você não pode contornar isso. Você é recompensado com um código que é mais fácil de manter, estender e geralmente menos bugs, mas isso leva tempo.

Pode ser uma venda difícil para os gerentes.

Os gerentes de software geralmente se preocupam apenas com os cronogramas. Se você mudar para a programação do primeiro teste 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 travar e muitos gerentes são esclarecidos o suficiente para consegui-la, mas pode ser uma venda difícil.

Pode ser uma venda difícil para outros desenvolvedores.

Como existe uma curva de aprendizado acentuada, nem todos os desenvolvedores gostam da programação do teste primeiro. Na verdade, eu acho que a maioria dos desenvolvedores não gosta disso no começo. Você pode fazer coisas como programação em pares para ajudá-los a se atualizar, mas pode ser uma venda difícil.

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

41
Jaco Pretorius

O teste primeiro pressupõe que você esteja escrevendo um código que seja:

  • testável de maneira unitária
  • que o que você está desenvolvendo tem uma abordagem óbvia e não exigirá prototipagem ou experimentação extensiva
  • que você não precisará refatorar demais ou que tenha tempo para reescrever centenas ou milhares de casos de teste repetidamente
  • nada é selado
  • tudo é modular
  • tudo é injetável ou ridicularizado
  • que sua organização valorize suficientemente baixos defeitos para justificar o coletor de recursos
  • que há algo de útil para testar em um nível de teste unitário

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

Na prática, também pode haver um grande problema para as pessoas que pensam que os testes do primeiro teste 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 uma imagem completa da correção. As pessoas veem centenas de testes aprovados e assumem que é seguro testar menos, pois antes do TDD eles apenas faziam algumas centenas de casos de teste. Na minha experiência, TDD significa que você precisa ter ainda mais testes de integração, pois os desenvolvedores também terão a segurança falsa e a dor de alterar todos os testes para fazer um grande redator pode levar os desenvolvedores a fazer soluções interessantes.

Exemplos:

Meu melhor exemplo pessoal é ao escrever um código de segurança para o asp.net. Se eles devem ser executados em um ambiente hostil a partir da configuração da máquina, eles são recebidos, assinados e lacrados e, por estarem rodando contra objetos IIS god god, é muito difícil zombar deles) Adicione algumas restrições ao desempenho e ao uso da memória e você perderá rapidamente a flexibilidade de usar objetos de espaço reservado nas áreas restantes.

Qualquer tipo de microcontrolador ou outro código de ambiente com pouco recurso pode não ser possível executar um design de estilo verdadeiramente OO, pois as abstrações não são otimizadas e você tem limites de recursos baixos. O mesmo pode ser dito para rotinas de alto desempenho em muitos casos também.

36
Bill

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

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

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

26
luis.espinal

Comecei a fazer 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 é totalmente convertida e o comprometimento de código não testado no repositório é considerado uma coisa ruim e usada. Tem funcionado muito bem para nós e não consigo imaginar voltar à codificação de cowboys.

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

O conjunto de testes deve ser mantido

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

Abstrações de teste vazam de tempos em tempos

Estamos usando o Django, que possui uma ótima estrutura de teste. No entanto, às vezes, faz suposições ligeiramente divergentes da realidade. Por exemplo, algum middleware pode interromper os testes. Ou, alguns testes fazem suposições sobre um back-end de cache. Além disso, se você estiver usando um banco de dados "real" (não o SQLite3), a preparação do banco de dados para os testes levará muito tempo. Claro, você pode (e deve) usar o SQLite3 e um banco de dados na memória para testes que você faz localmente, mas algum código se comportará de maneira diferente, dependendo do banco de dados usado. É necessário configurar um servidor de integração contínua executado em uma configuração realista.

(Algumas pessoas lhe dirão 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. Se você cometer erros no seu código de zombaria (e acredite, você o fará), seu testinguite não terá valor.)

Isso dito, os problemas que descrevi começam a ser notados apenas 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.

6
Ryszard Szopa

Para mim, há um problema psicológico profundo nos testes sempre que tento aplicá-los extensivamente, como no TDD: se eles estiverem lá, eu codifico com desleixo porque confio que os testes detectarão qualquer 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 os testes.

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

4
Joonas Pulakka

Uma situação em que o primeiro teste realmente me atrapalha é quando eu quero experimentar rapidamente alguma idéia e ver se ela pode funcionar 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, melhorando o design, refatorando.

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

Nesse caso, o uso do TDD resultou em mais desvantagens do que vantagens para mim:

  • Escrever testes durante a implementação da prova de conceito apenas me deixa mais lento 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 alguma coisa ou não.
  • Se a idéia for inútil, tenho que jogar fora meu código e meus testes de unidade bem escritos.

Portanto, quando tenho que explorar algumas idéias novas, não uso o TDD e apenas apresento testes de unidade quando sinto que o novo código está chegando a algum lugar.

2
Giorgio

Desvantagens ou custos do TDD

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

efeitos colaterais

Seja zombaria, instalações ou testes funcionais, as dependências de estados ou sistemas externos costumam ser a fonte de maior complexidade nos testes, confusão na forma de testar e o maior risco de errar. Alguns problemas que eu já vi:

  • Zombando: esqueça de afirmar a ordem das chamadas
  • Zombando: o mock não corresponde à chamada ou resposta real
  • Dispositivo elétrico: o teste depende de dados irreais, ocultando outros problemas
  • Dispositivo elétrico: teste um estado impossível na produção
  • Funcional: falhas de construção falsas devido ao sistema temporário indisponível temporariamente
  • Funcional: a velocidade do teste é muito lenta

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

Pessoas diferentes codificam de maneiras totalmente diferentes. No TDD, você precisa começar com um teste que afirme um comportamento específico e, em seguida, implementar para que o teste seja aprovado. Eu já vi e era um programador cuja programação não era propícia ao TDD. Levei cerca de 2 meses quando comecei a me acostumar a mudar minha abordagem de desenvolvimento.

Leva algum tempo para entender o que você gosta em testar e o que você não gosta em testar.

Toda equipe deve tomar uma decisão explícita sobre onde deseja definir a linha nos testes. O que eles valorizam e querem testar, e o que não valorizam. Geralmente, é 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 específico da unidade: refatores grandes

Um refator grande ou fundamental de uma base de código significativa com dezenas de milhares de testes de unidade gerará um custo enorme para atualizar todos os testes. Isso geralmente se manifesta em resposta ao fazer um refator, mesmo que seja a coisa correta a ser feita simplesmente pelo custo associado a isso.

1
dietbuddha

Minha analogia são barreiras em uma pista Scalextric. Se você os colocar, ficará muito menos cauteloso.

As pessoas também recebem um pouco de cadetismo espacial sobre seus testes - porque eles correm bem, acreditam que o código foi totalmente testado, enquanto é apenas o começo do processo de teste.

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

0
Robbie Dee