Há 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 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 fazer a programação 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 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 de programação de 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 ignorar as desvantagens. Saber o que você está lidando desde o início ajuda a negociar algumas, se não todas, as desvantagens.
O teste primeiro pressupõe que você esteja escrevendo um código que seja:
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 falsa segurança 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, são armazenados, assinados e lacrados e, como estão sendo executados contra objetos divinos do IIS, é muito difícil zombar muito corretamente. Adicione algumas restrições ao uso do desempenho e 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 poucos recursos pode não ser possível para criar um design verdadeiramente de estilo 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.
fonte
A maior desvantagem que já vi não é com o próprio TDD, mas com os profissionais. 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).
fonte
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 muitos testes. Além disso, leva algum tempo e experiência para perceber qual é a granularidade certa de testes (exagerar é quase tão ruim quanto subexpor). Esses testes também são de 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 dirão que você deve zombar de todas as coisas, como o banco de dados, ou que 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.
fonte
Para mim, há um profundo problema psicológico 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.
fonte
Uma situação em que o teste primeiro 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:
Às vezes, não chego ao passo 2.
Nesse caso, o uso do TDD resultou em mais desvantagens do que vantagens para mim:
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.
fonte
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, acessórios ou testes funcionais, as dependências de estados ou sistemas externos costumam ser a fonte de maior complexidade nos testes, confusão em como testar e o maior risco de errar. Alguns problemas que eu já vi:
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 depois implementá-lo 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 tempo para entender o que você se importa com o teste e o que você não se importa com o teste.
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 unitário específico: grandes refatores
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.
fonte
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.
fonte
Os benefícios do TDD são que obriga a proteger 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 guardar? Há muito código que nem deveria estar lá em primeiro lugar! Portanto, o problema com o TDD é quando se trata de desenvolvedores que escrevem códigos incorretos. O TDD provavelmente não os ajudará a escrever um bom código, é muito mais provável que eles escrevam testes horríveis também. Assim, no caso deles, o TDD adicionará apenas à bagunça; testes mal escritos e / ou redundantes não são mais divertidos do que outras formas de código incorreto.
fonte