it-swarm-pt.tech

Desvantagens do Desenvolvimento Orientado a Testes?

O que eu perco ao adotar o design testado?

Listar apenas negativos; não liste os benefícios escritos de forma negativa.

191
IanL

Diversas desvantagens (e não estou afirmando que não há benefícios - especialmente ao escrever a base de um projeto - economizar muito tempo no final):

  • Grande investimento de tempo. Para o caso simples você perde cerca de 20% da implementação real, mas para casos complicados você perde muito mais.
  • Complexidade adicional. Para casos complexos, seus casos de teste são mais difíceis de calcular, eu sugiro, em casos como esse, tentar usar código de referência automático que será executado em paralelo na versão de depuração/execução de teste. do teste unitário de casos mais simples.
  • Impactos do projeto. Às vezes, o design não é claro no início e evolui à medida que você avança - isso forçará você a refazer seu teste, o que gerará uma grande perda de tempo. Eu sugeriria adiar testes unitários neste caso até que você tenha alguma noção do design em mente.
  • Continuous Tweaking. Para estruturas de dados e testes de unidade de algoritmos de caixa preta seria perfeito, mas para algoritmos que tendem a ser alterados, ajustados ou ajustados, isso pode causar um grande investimento de tempo que se pode afirmar que não é justificado. Portanto, use-o quando achar que ele realmente se ajusta ao sistema e não force o design a se ajustar ao TDD.
124
Adi

Se você quer fazer TDD "real" (leia: teste primeiro com as etapas vermelha, verde e refatoradora), então você também deve começar a usar mocks/stubs quando quiser testar pontos de integração.

Quando você começar a usar mocks, depois de um tempo, você vai querer começar a usar Injeção de Dependência (DI) e um contêiner de Inversão de Controle (IoC). Para fazer isso, você precisa usar interfaces para tudo (que tem muitas armadilhas).

No final do dia, você tem que escrever muito mais código, do que se você fizesse isso do jeito simples e simples. Em vez de apenas uma classe de cliente, você também precisa escrever uma interface, uma classe simulada, alguma configuração IoC e alguns testes.

E lembre-se de que o código de teste também deve ser mantido e cuidado. Os testes devem ser tão legíveis quanto todo o resto e leva tempo para escrever um bom código.

Muitos desenvolvedores não entendem muito bem como fazer tudo isso "da maneira certa". Mas como todo mundo diz a eles que o TDD é a única maneira verdadeira de desenvolver software, eles simplesmente tentam o melhor que podem.

É muito mais difícil do que se imagina. Muitas vezes os projetos feitos com o TDD acabam com um monte de código que ninguém entende. Os testes de unidade geralmente testam a coisa errada, o caminho errado. E ninguém concorda como deve ser um bom teste, nem mesmo os chamados gurus.

Todos esses testes tornam muito mais difícil "mudar" (ao contrário da refatoração) o comportamento do seu sistema e as mudanças simples tornam-se muito difíceis e demoradas.

Se você ler a literatura do TDD, há sempre alguns exemplos muito bons, mas geralmente em aplicativos da vida real, você deve ter uma interface de usuário e um banco de dados. É aí que o TDD fica realmente difícil e a maioria das fontes não oferece boas respostas. E, se o fizerem, sempre envolve mais abstrações: objetos simulados, programação em uma interface, padrões MVC/MVP etc., que novamente exigem muito conhecimento e ... você precisa escrever ainda mais código.

Portanto, tenha cuidado ... se você não tiver uma equipe entusiasmada e pelo menos um desenvolvedor experiente que saiba escrever bons testes e também conheça algumas coisas sobre uma boa arquitetura, você realmente terá que pensar duas vezes antes de seguir a estrada TDD .

184
Thomas Jespersen

Quando você chega ao ponto em que tem um grande número de testes, a alteração do sistema pode exigir a reescrita de alguns ou de todos os seus testes, dependendo de quais foram invalidados pelas alterações. Isso poderia transformar uma modificação relativamente rápida em uma muito demorada.

Além disso, você pode começar a tomar decisões de design com base mais em TDD do que em princípios de design realmente bons. Considerando que você pode ter tido uma solução muito simples e fácil que é impossível testar o modo como TDD demanda, agora você tem um sistema muito mais complexo que é realmente mais propenso a erros.

66
Eric Z Beard

Eu acho que o maior problema para mim é a enorme perda de tempo que leva "entrar nele". Eu ainda estou muito no início da minha jornada com TDD (Veja meu blog para atualizações minhas aventuras de teste se você estiver interessado) e eu gastei literalmente horas introdução.

Leva muito tempo para colocar seu cérebro em "modo de teste" e escrever "código testável" é uma habilidade em si.

TBH, respeitosamente discordo de comentários de Jason Cohen em tornar públicos os métodos privados, não é disso que se trata. Eu não fiz mais métodos públicos na minha nova maneira de trabalhar do que antes . No entanto, envolve mudanças arquitetônicas e permite que você "conecte" módulos de código para tornar tudo mais fácil de testar. Você deve não estar tornando os componentes internos do seu código mais acessíveis para fazer isso. Caso contrário, estamos de volta à estaca zero com tudo sendo público, onde está o encapsulamento disso?

Então, (IMO) em poucas palavras:

  • O tempo gasto para pensar (ou seja, na verdade, grok'ing testing ).
  • O novo conhecimento necessário para saber como escrever código testável.
  • Compreender as alterações arquitetônicas necessárias para tornar o código testável.
  • Aumentando sua habilidade de "TDD-Coder" ao tentar melhorar todas as outras habilidades necessárias para o nosso glorioso ofício de programação :)
  • Organize sua base de código para incluir código de teste sem estragar seu código de produção.

PS: Se você quiser links para positivos, eu já perguntei e respondi várias perguntas, confira my profile .

54
Rob Cooper

Nos poucos anos em que estive praticando Test Driven Development, eu tenho que dizer que as maiores desvantagens são:

Vendendo para a gerência

O TDD é melhor feito em pares. Por um lado, é difícil resistir ao desejo de apenas escrever a implementação quando você SABE como escrever um if/else declaração. Mas um par irá mantê-lo na tarefa porque você o mantém na tarefa. Infelizmente, muitas empresas/gerentes não acham que esse é um bom uso de recursos. Por que pagar duas pessoas para escrever um recurso, quando eu tenho dois recursos que precisam ser feitos ao mesmo tempo?

Vendendo para outros desenvolvedores

Algumas pessoas simplesmente não têm paciência para escrever testes de unidade. Alguns estão muito orgulhosos de seu trabalho. Ou, alguns apenas como ver métodos/funções complicados desaparecerem no final da tela. O TDD não é para todos, mas eu realmente gostaria que fosse. Isso tornaria a manutenção das coisas muito mais fácil para aquelas pobres almas que herdam o código.

Mantendo o código de teste junto com seu código de produção

Idealmente, seus testes só irão quebrar quando você tomar uma decisão de código ruim. Ou seja, você pensou que o sistema funcionava de uma maneira, e acontece que não funcionou. Ao quebrar um teste, ou um (pequeno) conjunto de testes, isso é realmente uma boa notícia. Você sabe exatamente como seu novo código afetará o sistema. No entanto, se os seus testes forem mal escritos, fortemente acoplados ou, pior ainda, gerados ( tosse VS Test), a manutenção dos seus testes pode tornar-se um coro rapidamente . E, depois que testes suficientes começarem a causar mais trabalho do que o valor percebido que eles estão criando, os testes serão a primeira coisa a ser deletada quando os cronogramas forem comprimidos (por exemplo, o tempo de processamento).

Escrevendo testes para que você cubra tudo (cobertura de código de 100%)

Idealmente, novamente, se você aderir à metodologia, seu código será 100% testado por padrão. Normalmente, pensei, acabo com cobertura de código acima de 90%. Isso geralmente acontece quando eu tenho alguma arquitetura de estilo de modelo, e a base é testada, e eu tento cortar cantos e não testar as personalizações de modelo. Além disso, descobri que quando encontro uma nova barreira que não encontrei anteriormente, tenho uma curva de aprendizado para testá-la. Admito escrever algumas linhas de código, mas eu realmente gosto de ter 100%. (Eu acho que eu era um grande empreendedor na escola, er skool).

No entanto, com isso eu diria que os benefícios do TDD superam em muito os negativos pela simples ideia de que, se você puder obter um bom conjunto de testes que cubra seu aplicativo, mas não sejam tão frágeis que uma alteração os interrompa, você ser capaz de continuar adicionando novos recursos no dia 300 do seu projeto como você fez no primeiro dia. Isso não acontece com todos que tentam TDD pensando que é uma mágica para todo o seu código bug-ridden, e então eles acham que pode trabalhe, ponto final.

Pessoalmente, descobri que com o TDD, escrevo códigos mais simples, passo menos tempo debatendo se uma determinada solução de código funcionará ou não, e que não tenho medo de alterar qualquer linha de código que não atenda aos critérios estabelecidos por O time.

O TDD é uma disciplina difícil de dominar, e eu estou nisso há alguns anos e ainda aprendo novas técnicas de teste o tempo todo. É um enorme investimento inicial, mas, a longo prazo, sua sustentabilidade será muito maior do que se você não tivesse testes unitários automatizados. Agora, se apenas meus chefes pudessem descobrir isso.

49
casademora

Em seu primeiro projeto TDD, há duas grandes perdas, tempo e liberdade pessoal

Você perde tempo porque:

  • A criação de um conjunto de testes de aceitação e de unidade abrangente, refatorado e sustentável aumenta o tempo da primeira iteração do projeto. Este pode ser o tempo economizado a longo prazo, mas igualmente pode ser o tempo que você não tem de sobra.
  • Você precisa escolher e se tornar especialista em um conjunto principal de ferramentas. Uma ferramenta de teste de unidade precisa ser complementada por algum tipo de estrutura de simulação e ambos precisam se tornar parte de seu sistema de criação automatizado. Você também quer escolher e gerar métricas apropriadas.

Você perde a liberdade pessoal porque:

  • O TDD é uma maneira muito disciplinada de escrever código que tende a ser usado contra os que estão no topo e na base da escala de habilidades. Sempre escrever o código de produção de uma determinada maneira e sujeitar seu trabalho a uma revisão por pares contínua pode enlouquecer seus piores e melhores desenvolvedores e até mesmo levar à perda de pessoal.
  • A maioria dos métodos ágeis que incorporam o TDD exigem que você converse continuamente com o cliente sobre o que se propõe a realizar (nesta matéria/dia/qualquer outra coisa) e quais são os tradeoffs. Mais uma vez, esta não é a xícara de chá de todos, tanto do lado dos desenvolvedores quanto dos clientes.

Espero que isto ajude

24
Garth Gilmour

O TDD requer que você planeje como suas classes irão operar antes de escrever o código para passar nesses testes. Isso é positivo e negativo.

Acho difícil escrever testes em um "vácuo" - antes que qualquer código tenha sido escrito. Na minha experiência, tenho a tendência de tropeçar nos meus testes sempre que inevitavelmente penso em alguma coisa enquanto escrevo minhas aulas que esqueci enquanto escrevo meus testes iniciais. Então é hora de não apenas refatorar minhas aulas, mas também meus testes. Repita isso três ou quatro vezes e pode ser frustrante.

Eu prefiro escrever um rascunho de minhas aulas primeiro, depois escrever (e manter) uma bateria de testes de unidade. Depois que eu tenho um rascunho, o TDD funciona bem para mim. Por exemplo, se um bug for relatado, gravarei um teste para explorar esse bug e, em seguida, corrija o código para que o teste seja aprovado.

14
Chrass

A prototipagem pode ser muito difícil com o TDD - quando você não tem certeza de qual caminho você vai tomar para uma solução, escrever os testes antecipadamente pode ser difícil (além dos muito amplos). Isso pode ser uma dor.

Honestamente, eu não acho que, para o "desenvolvimento básico" para a grande maioria dos projetos, haja qualquer lado negativo; é muito mais falado do que deveria, geralmente por pessoas que acreditam que seu código é bom o suficiente para não precisar de testes (nunca é) e pessoas que simplesmente não podem ser incomodadas em escrevê-las.

12
Calum

Bem, e esse alongamento, você precisa depurar seus testes. Além disso, há um certo custo em tempo para escrever os testes, embora a maioria das pessoas concorde que é um investimento inicial que compensa ao longo da vida útil do aplicativo tanto na depuração de tempo economizada quanto na estabilidade.

O maior problema que eu pessoalmente tive com isso, porém, é levantar a disciplina para realmente escrever os testes. Em uma equipe, especialmente uma equipe estabelecida, pode ser difícil convencê-los de que o tempo gasto vale a pena.

9
Tim Sullivan

A desvantagem do TDD é que ele é geralmente associado à metodologia 'Ágil', o que coloca não importância na documentação de um sistema, em vez do entendimento por que um teste 'deveria' retornar um valor específico em vez de qualquer outro reside apenas na cabeça do desenvolvedor.

Assim que o desenvolvedor sai ou esquece o motivo pelo qual o teste retorna um valor específico e não outro, você está ferrado. O TDD é bom se estiver adequadamente documentado e rodeado por documentação legível por humanos (isto é, gerente de cabelo pontudo) que pode ser consultado em 5 anos quando o mundo mudar e seu aplicativo também precisar.

Quando eu falo de documentação, isso não é uma sinopse no código, isso é a escrita oficial que existe externa ao aplicativo, como casos de uso e informações básicas que podem ser referidas por gerentes, advogados e pessoas pobres que precisam atualizar seu código em 2011.

7
Ron McMahon

Se os seus testes não forem muito completos, você pode ter um falso sentido de que "tudo funciona" só porque os testes são aprovados. Teoricamente, se seus testes forem aprovados, o código está funcionando; mas se pudéssemos escrever código perfeitamente na primeira vez, não precisaríamos de testes. A moral aqui é certificar-se de fazer uma verificação de sanidade por conta própria antes de chamar algo completo, não confie apenas nos testes.

Na mesma nota, se a sua verificação de sanidade encontra algo que não foi testado, certifique-se de voltar e escrever um teste para isso.

7
Aaron Lee

Eu encontrei várias situações em que TDD me deixa louco. Para citar alguns:

  • Manutenção de caso de teste:

    Se você está em uma grande empresa, muitas chances são de que você não precise escrever os casos de teste sozinho ou pelo menos a maioria deles é escrita por outra pessoa quando você entra na empresa. Os recursos de um aplicativo mudam de tempos em tempos e, se você não tiver um sistema em funcionamento, como o HP Quality Center, para rastreá-los, você ficará louco em pouco tempo.

    Isso também significa que os novos membros da equipe demoram um bom tempo para entender o que está acontecendo com os casos de teste. Por sua vez, isso pode ser traduzido em mais dinheiro necessário.

  • Complexidade de automação de teste:

    Se você automatizar alguns ou todos os casos de teste em scripts de teste executáveis ​​por máquina, será necessário verificar se esses scripts de teste estão em sincronia com os casos de teste manuais correspondentes e de acordo com as alterações do aplicativo.

    Além disso, você gastará tempo para depurar os códigos que o ajudarão a detectar bugs. Na minha opinião, a maioria desses erros vem da falha da equipe de testes em refletir as alterações do aplicativo no script de teste de automação. Alterações na lógica de negócios, GUI e outras coisas internas podem fazer com que seus scripts parem de ser executados ou executem de maneira não confiável. Às vezes as mudanças são muito sutis e difíceis de detectar. Uma vez que todos os meus scripts relatam falhas, eles basearam seus cálculos nas informações da tabela 1, enquanto a tabela 1 era agora a tabela 2 (porque alguém trocou o nome dos objetos da tabela no código da aplicação).

6
Martin08

O maior problema são as pessoas que não sabem escrever testes unitários apropriados. Eles escrevem testes que dependem uns dos outros (e eles funcionam muito bem com o Ant, mas, de repente, falham quando eu os executo no Eclipse, simplesmente porque eles são executados em ordem diferente). Eles escrevem testes que não testam nada em particular - eles apenas depuram o código, verificam o resultado e o transformam em teste, chamando-o de "test1". Eles ampliam o escopo de classes e métodos, apenas porque será mais fácil escrever testes de unidade para eles. O código dos testes unitários é péssimo, com todos os problemas clássicos de programação (acoplamento pesado, métodos com 500 linhas de comprimento, valores codificados, duplicação de código) e é um inferno de se manter. Por alguma estranha razão, as pessoas tratam os testes de unidade como algo inferior ao código "real" e não se importam com a qualidade deles. :-(

5
rmaruszewski

Você perde muito tempo gasto escrevendo testes. Claro, isso pode ser salvo até o final do projeto, capturando bugs mais rapidamente.

4
Joel Coehoorn

Você perde a capacidade de dizer que está "pronto" antes de testar todo o seu código.

Você perde a capacidade de escrever centenas ou milhares de linhas de código antes de executá-lo.

Você perde a oportunidade de aprender com a depuração.

Você perde a flexibilidade de enviar códigos dos quais não tem certeza.

Você perde a liberdade de acoplar seus módulos.

Você perde a opção de pular a documentação de design de baixo nível.

Você perde a estabilidade que vem com o código que todo mundo tem medo de mudar.

Você perde o título de "hacker".

4
Uncle Bob

A maior desvantagem é que, se você realmente quiser fazer TDD corretamente, você terá que falhar muito antes de ter sucesso. Dado o número de empresas de software que trabalham (dólar por KLOC), você será demitido. Mesmo que seu código seja mais rápido, mais limpo, mais fácil de manter e tenha menos bugs.

Se você estiver trabalhando em uma empresa que lhe paga pelos KLOCs (ou requisitos implementados - mesmo que não testados), fique longe de TDD (ou revisões de código, ou programação em pares, ou Integração Contínua, etc. etc. etc.).

3
Vasco Duarte

Concentrar-se em requisitos difíceis e imprevisíveis é a constante ruína do programador. O desenvolvimento orientado a testes força você a se concentrar nos requisitos mundanos já conhecidos e limita seu desenvolvimento ao que já foi imaginado.

Pense nisso, é provável que você acabe projetando para casos de teste específicos, para que você não seja criativo e comece a pensar "seria legal se o usuário pudesse fazer X, Y e Z". Portanto, quando esse usuário começar a ficar todo empolgado com possíveis requisitos legais X, Y e Z, seu design pode estar muito rígido em casos de teste já especificados e será difícil de ajustar.

Isto, claro, é uma espada de dois gumes. Se você gastar todo o seu tempo projetando para todos os imagináveis, imagináveis, X, Y e Z que um usuário possa desejar, você inevitavelmente nunca completará nada. Se você concluir alguma coisa, será impossível para qualquer pessoa (incluindo você mesmo) ter alguma ideia do que você está fazendo em seu código/design.

2
Doug T.

Eu segundo a resposta sobre o tempo de desenvolvimento inicial. Você também perde a capacidade de trabalhar confortavelmente sem a segurança dos testes. Eu também fui descrito como um nutbar TDD, então você pode perder alguns amigos;)

2
Chris Canal

É percebido como mais lento. A longo prazo, isso não é verdade em termos de tristeza, mas você acabará escrevendo mais código, então você está gastando tempo em "testar e não codificar". É um argumento falho, mas você perguntou!

1
MarcE

Pode ser difícil e demorado escrever testes para dados "aleatórios", como XML-feeds e bancos de dados (não tão difícil). Eu passei algum tempo trabalhando ultimamente com feeds de dados climáticos. É muito confuso escrever testes para isso, pelo menos porque não tenho muita experiência com o TDD.

1
Vargen

Demora algum tempo para entrar nisso e algum tempo para começar a fazê-lo em um projeto, mas ... Eu sempre lamento não fazer uma abordagem orientada a testes quando encontro bugs bugs que um teste automatizado poderia ter encontrado muito rápido. Além disso, o TDD melhora a qualidade do código.

1
aerlijman

Boas respostas a todos. Eu adicionaria algumas maneiras de evitar o lado sombrio do TDD:

  • Eu escrevi aplicativos para fazer seu próprio autoteste aleatório. O problema com a escrita de testes específicos é que, mesmo que você escreva muitos deles, eles só cobrem os casos em que você pensa. Geradores de testes aleatórios encontram problemas que você não pensou.

  • Todo o conceito de muitos testes de unidade implica que você tem componentes que podem entrar em estados inválidos, como estruturas de dados complexas. Se você ficar longe de estruturas de dados complexas, há muito menos para testar.

  • Na medida em que a sua aplicação permitir, não tenha um design que se baseie na correta ordenação de notificações, eventos e efeitos colaterais. Aqueles podem facilmente cair ou embaralhar, então eles precisam de muitos testes.

1
Mike Dunlavey
  • teste de unidade são mais código para escrever, assim, um maior custo inicial de desenvolvimento
  • é mais código para manter
  • aprendizado adicional exigido
1
Bob Dizzle

Você perderá grandes turmas com múltiplas responsabilidades. Você provavelmente também perderá grandes métodos com múltiplas responsabilidades. Você pode perder alguma habilidade para refatorar, mas também perderá parte da necessidade de refatorar.

Jason Cohen disse algo como: o TDD requer uma determinada organização para o seu código. Isso pode ser arquiteturalmente errado; Por exemplo, como os métodos privados não podem ser chamados fora de uma classe, você precisa tornar os métodos não particulares para torná-los testáveis.

Eu digo que isso indica uma abstração perdida - se o código privado realmente precisa ser testado, ele provavelmente deveria estar em uma classe separada.

Dave Mann

1
Dave Mann

Você precisa escrever aplicativos de uma maneira diferente: um que os torne testáveis. Você ficaria surpreso com o quão difícil isso é no começo.

Algumas pessoas acham o conceito de pensar sobre o que vão escrever antes de escrever muito. Conceitos como zombaria podem ser difíceis para alguns também. TDD em aplicativos legados pode ser muito difícil se eles não foram projetados para testes. TDD em torno de estruturas que não são amigáveis ​​com TDD também pode ser uma luta.

TDD é uma habilidade que os desenvolvedores juniores podem ter dificuldades no começo (principalmente porque não foram ensinados a trabalhar dessa maneira).

No geral, embora os contras sejam resolvidos à medida que as pessoas se tornam habilidosas e você acaba abstraindo o código 'fedorento' e tem um sistema mais estável.

1
Peter Gillard-Moss

A pessoa que ensinou o desenvolvimento ágil da minha equipe não acreditou no planejamento, você só escreveu tanto para o menor requisito.

Seu lema era refatorar, refatorar, refatorar. Cheguei a entender que o refinador significava "não planejar com antecedência".

0
Jack B Nimble

Deixe-me acrescentar que, se você aplicar os princípios do BDD a um projeto TDD, poderá aliviar algumas das principais desvantagens listadas aqui (confusão, mal-entendidos, etc.). Se você não estiver familiarizado com o BDD, leia a introdução de Dan North. Ele surgiu o conceito em resposta a algumas das questões que surgiram da aplicação de TDD no local de trabalho. A introdução de Dan para o BDD pode ser encontrada aqui .

Eu só faço essa sugestão porque o BDD aborda alguns desses aspectos negativos e age como uma lacuna. Você vai querer considerar isso ao coletar seu feedback.

0
Kilhoffer

O TDD requer uma determinada organização para o seu código. Isso pode ser ineficiente ou difícil de ler. Ou até arquitetonicamente errado; Por exemplo, como os métodos private não podem ser chamados fora de uma classe, você precisa tornar os métodos não privados para torná-los testáveis, o que é errado.

Quando o código é alterado, você também precisa alterar os testes. Com a refatoração, isso pode ser muito trabalho extra.

0
Jason Cohen

Você tem que ter certeza de que seus testes estão sempre atualizados, no momento em que você começa a ignorar as luzes vermelhas é o momento em que os testes se tornam sem sentido.

Você também tem que ter certeza de que os testes são abrangentes, ou no momento em que um grande erro aparecer, o tipo de gerenciamento abafado que você finalmente convenceu a deixar você gastar mais tempo escrevendo mais código irá reclamar.

0
qui