O teste unitário ou o desenvolvimento orientado para testes são válidos?

47

Minha equipe no trabalho está se mudando para o Scrum e outras equipes estão começando a fazer desenvolvimento orientado a testes usando testes de unidade e testes de aceitação do usuário. Eu gosto dos UATs, mas não sou vendido em testes unitários para desenvolvimento orientado a testes ou desenvolvimento orientado a testes em geral.

Parece que escrever testes é um trabalho extra, dá às pessoas uma muleta quando escrevem o código real e pode não ser eficaz com muita frequência.

Eu entendo como os testes de unidade funcionam e como escrevê-los, mas alguém pode argumentar que é realmente uma boa ideia e vale a pena o esforço e o tempo?

Além disso, existe algo que torna o TDD especialmente bom para o Scrum?

    
por Owen Johnson 17.03.2012 / 06:13
fonte

9 respostas

67

Resposta curta: Absolutamente positiva.

Resposta Longa: Testes de unidade são uma das práticas mais importantes que eu tento influenciar no meu local de trabalho (banco grande, negociação fx). Sim, eles são um trabalho extra, mas é um trabalho que paga de novo e de novo. Testes automatizados de unidade não apenas ajudam você a realmente executar o código que está escrevendo e, claro, a verificar suas expectativas, mas eles também agem como um tipo de cão de guarda para futuras mudanças que você ou outra pessoa possa fazer. A quebra do teste ocorrerá quando alguém alterar o código de forma indesejável. Eu acho que o valor relativo dos testes unitários diminui em correlação com o nível de mudança esperada e crescimento em uma base de código, mas a verificação inicial do que o código faz valer a pena, mesmo quando a mudança esperada é baixa. O valor do teste unitário também depende do custo dos defeitos. Se o custo (onde o custo é perda de tempo / dinheiro / reputação / esforço futuro) de um defeito for zero, então o valor relativo de um teste também é zero; no entanto, este quase nunca é o caso em um ambiente comercial.

Geralmente, não contratamos mais pessoas que não criam testes de unidade rotineiramente como parte de seu trabalho - é apenas algo que esperamos, como aparecer todos os dias. Eu não vi uma análise de custo-benefício pura de ter testes unitários (alguém sinta-se livre para me indicar um), mas posso dizer por experiência que em um ambiente comercial, ser capaz de provar que funciona código em um sistema grande e importante vale a pena . Também me permite dormir melhor à noite, sabendo que o código que escrevi funciona (até certo ponto) e, se mudar, alguém será alertado sobre quaisquer efeitos colaterais inesperados causados por uma compilação quebrada.

Desenvolvimento orientado a testes, em minha mente não é uma abordagem de teste. Na verdade, é uma abordagem / prática de design com a saída sendo o sistema de trabalho e um conjunto de testes de unidade. Eu sou menos religioso sobre esta prática, pois é uma habilidade que é muito difícil de desenvolver e aperfeiçoar. Pessoalmente, se estou construindo um sistema e não tenho uma ideia clara de como ele funcionará, eu utilizarei o TDD para me ajudar a encontrar o meu caminho no escuro. No entanto, se eu estiver aplicando um padrão / solução existente, normalmente não o farei.

Na ausência de provas matemáticas para você de que faz sentido escrever testes de unidade, recomendo que você experimente durante um período prolongado e experimente os benefícios por si mesmo.

    
por 17.03.2012 / 07:08
fonte
15

Os erros encontrados anteriormente são menos dispendiosos de corrigir do que os erros encontrados mais tarde. O TDD ajuda você a verificar a exatidão do seu sistema. Você investe um pouco mais adiantado, mas recupera-o mais tarde. O gráfico é um pouco exagerado, mas mostra bem a ideia.

Fonte da imagem

    
por 17.03.2012 / 21:26
fonte
8

It seems like writing tests is extra work, gives people a crutch when they write the real code, and might not be effective very often.

O teste unitário tem valor como muleta. Ele suporta seus esforços de desenvolvimento, permitindo que você altere sua implementação sem temer que seu aplicativo deixe de funcionar conforme necessário. Os testes de unidade também são muito mais do que uma muleta, pois fornecem uma ferramenta com a qual você pode validar se sua implementação atende aos requisitos.

Todos os testes, sejam testes de unidade, testes de aceitação, testes de integração e assim por diante, são tão eficazes quanto as pessoas que os utilizam. Se você abordar o seu trabalho de maneira desleixada, seus testes serão desleixados e sua implementação terá problemas. Então, por que se incomodar? Você se incomoda em testar porque precisa provar para si mesmo e para seus clientes que o seu software funciona e não tem nenhum problema que possa impedir que o software seja usado. Sim, os testes são definitivamente trabalhos extras, mas a maneira como você testa os testes determinará quanto esforço será necessário para corrigir os bugs após o lançamento e quanto esforço seu código exigirá para alterar e manter.

I understand how unit tests work and how to write them, but can anyone make the case that it's really a good idea and worth the effort and time?

TDD e, na verdade, qualquer método que exija que você escreva testes antes de codificar adota a abordagem que você coloca em um esforço inicial como adiantamento da dívida técnica futura. À medida que você trabalha no projeto, qualquer coisa que seja perdida ou que não seja bem implementada incorrerá em mais dívida técnica na forma de maior dificuldade de manutenção, o que afeta diretamente os custos futuros e os requisitos de recursos. O teste antecipado garante que você não apenas tenha se esforçado para solucionar a dívida técnica futura, mas também garantir que você codifique seus requisitos de modo que eles possam ser verificados simplesmente executando o código. O teste primeiro também oferece a oportunidade de validar sua compreensão do domínio do problema antes de se comprometer com a solução do problema no código e valida seus esforços de implementação.

Tudo se resume a tentar maximizar o valor comercial do seu código. Código que é em grande parte não testado e difícil de manter é geralmente barato e rápido de criar, e muito caro para manter durante a vida útil do produto após o lançamento. O código que foi testado exaustivamente no nível da unidade geralmente é mais caro para ser criado, mas custa relativamente pouco para ser mantido durante a vida útil do produto após o lançamento.

Also, is there anything that makes TDD especially good for SCRUM?

O TDD não é especificamente adequado para nenhuma metodologia específica. É simplesmente uma ferramenta. Uma prática que você pode integrar em seus processos de desenvolvimento para ajudá-lo a alcançar seus resultados específicos. Então, para responder à sua pergunta, o TDD é complementar ao seu método, seja SCRUM ou qualquer outra abordagem.

    
por 17.03.2012 / 07:16
fonte
8

Is unit testing or test-driven development worth while?

Sim, faz . Tio Bob (Robert C Martin) contou em uma apresentação;

For a developer to prove that his code is working better to write a test and pass it than shouting , singing or dancing about it.

E como você não excluirá o teste, contanto que o teste seja um passe, você tem certeza de que a funcionalidade está funcionando - os problemas de regressão foram resolvidos.

Há muitas coisas escritas,

  1. Você é responsável por fazer esse recurso funcionar. Escreva um teste. Apenas faça.
  2. Quando substituir os testes de unidade pelo teste de integração

Are SCRUM, Unit testing and TDD related?

Em breve, quando você for um mestre em Unit testing , estará próximo de TDD . SCRUM não tem nada a ver com isso, mas, como dizem, grandes coisas se misturam bem, essas técnicas de desenvolvimento de um software se somam a uma excelente pilha , se você não tiver tentei ainda tentar.

Is there anything that makes TDD especially good for SCRUM?

Como eu disse acima eles fazem uma boa combinação ; Se você adicionar alguns testes de automação a ele, será mais especial .

    
por 17.03.2012 / 07:10
fonte
5

As pessoas acham que é um esforço extra porque é uma atividade inicial. O que você perde no tempo agora você ganha de volta mais tarde.

Minhas razões para o teste de unidade também incluem:

Dá-lhe um alvo: não pode escrever um teste se não souber o que o software deve fazer. Isso ajuda a eliminar problemas nas especificações antes, em vez de mais tarde.

Dá-lhe uma sensação de progresso.

Avisa se uma alteração de código altera a saída de outras áreas de código. Isso torna a refatoração mais fácil.

Fornece uma camada adicional de documentação (especialmente se você comentar seus testes corretamente).

Incentiva todo tipo de boas práticas. Como os testes devem ser executados rapidamente, ele incentiva você a escrever código dissociado e que oferece suporte a zombaria. Isso tudo ajuda na refatoração.

Há outros também abrangidos em outros posts neste tópico. Vale a pena.

    
por 17.03.2012 / 09:29
fonte
2

Is unit testing or test-driven development worthwhile?

Definitivamente sim (veja as outras respostas)

[Is it] really a good idea and worth the effort and time?

  • Sim se você começar algo novo (adicionar um novo módulo ou um aplicativo completamente novo)
  • Não se já existe muito código existente que não foi desenvolvido orientado por testes e que deve ser estendido (legado).

Na minha opinião, o desenvolvimento orientado a testes é mais eficaz se você escrever os testes de unidade antes do código real. Desta forma, o código que preenche os testes torna-se claramente separado com um mínimo de referências externas que é facilmente testável.

Se o código já existe sem os testes unitários, normalmente há muito trabalho extra para escrever os testes unitários, porque o código não foi escrito para testes fáceis.

Se você faz o TDD, o código é automaticamente testável.

    
por 20.03.2012 / 18:00
fonte
2

Deixe-me abordar isso do outro lado. O que acontece quando você desenvolve um aplicativo não trivial sem testes de unidade? Se você tem um bom departamento de QA, uma das primeiras coisas que acontecerá é que você terá um grande número de problemas relatados. Porque você não testou o que fez e assumiu que funcionaria e porque você não prestou muita atenção aos requisitos e sua aplicação não os atende. Opa de volta à prancheta para reescrever e consertar. Agora você fez as correções e encontrou um conjunto totalmente novo de problemas porque não tinha como confirmar se suas correções não afetaram mais nada antes de você passar para o controle de qualidade. O prazo final já chegou e a gestão está aborrecida.

A situação é pior se você não tiver um bom departamento de QA, pois os usuários encontrarão os bugs e isso não apenas deixará seu chefe infeliz, mas também poderá deixar o ambiente de produção de joelhos e centenas ou até milhares de pessoas ficará paralisado enquanto você corrige os erros que o teste de unidade teria evitado. Esta não é uma boa escolha de carreira.

Agora, suponha que essa abordagem cowboy se prolongue por anos? Agora, todas as mudanças, mesmo as triviais, parecem criar novos problemas insuspeitados. Não apenas isso, mas muitas das coisas que você gostaria de fazer para que o aplicativo funcionasse melhor, você não pode fazê-lo porque são muito arriscadas ou muito caras, ou ambos. Então você coloca os patches nos patches tornando o sistema cada vez mais complexo e mais difícil de usar.

Os usuários começam a questionar suas estimativas de tempo porque ficam cada vez maiores e é difícil explicar a eles que o sistema se tornou uma bagunça tão complicada, que é difícil encontrar onde fazer as mudanças e ainda mais difícil de garantir eles não quebram outra coisa.

Eu trabalhei em um lugar como este, onde após dez anos de desenvolvimento, praticamente nada que quiséssemos fazer para consertar os problemas reais poderia ser feito porque não poderíamos dizer qual das centenas de aplicações cliente personalizadas iriam quebrar. Os desenvolvedores iniciais foram muito mais do tipo "testes de unidade, não precisamos de testes de unidades fedorentos". Todos os que os seguiram sofreram graças à sua falta de visão.

Sem testes de unidade, o software é mais problemático e leva mais tempo para desenvolver e manter inicialmente. Por que diabos você não gostaria de fazer testes de unidade? O tempo que você gasta escrevendo o teste será muito menor do que o tempo gasto corrigindo problemas que você deveria ter encontrado anteriormente (quanto mais cedo o erro for encontrado, menos tempo para corrigir) e problemas que você teria evitado ao escrever os testes primeiro que dá uma melhor compreensão dos requisitos antes de começar a codificação.

    
por 20.03.2012 / 19:20
fonte
1

Todo o código que você escreve precisa ser testado em algum momento. Você não quer escrever tudo de uma vez e depois apertar o botão de compilação e cruzar os dedos. Você escreve e compila pequenos blocos e envia uma entrada cuidadosamente elaborada em seu código para verificar se faz o que acha que faz. Então, você geralmente apaga seu aparelho de teste ad-hoc e passa para o próximo componente.

Com o teste de unidade, ele simplifica esse processo e dá uma desculpa para manter seus testes por perto. Dessa forma, se você fizer alterações que quebram as coisas que você testou no passado, você pode capturar essa regressão explicitamente em vez de permitir que ela afete outras partes do seu código. Existe um valor real nisso.

Quanto à abordagem red-green-refactor para TDD, acho isso um pouco tedioso. Mas para cada um deles.

    
por 17.03.2012 / 10:31
fonte
0

Na maioria das vezes, acho que os desenvolvedores são resilientes à ideia de escrever testes. Não é tanto que eles argumentem que os testes não têm valor, mas sim que são apenas um meio de descobrir como resolver um problema em particular. Geralmente esse problema muda com base no contexto. Feito isso, os testes não servem e podem ser excluídos. Aqui está uma amostra de contextos que meus colegas deram no passado sobre como decidir quando escrever um teste e você encontrará que a única resposta possível de acordo com eles nunca é:

  • o problema em questão deve ser um exemplo de livro de texto para o TDD, como uma pilha ou uma calculadora
  • código trivial não deve ser testado (invalida o argumento anterior)
  • código crítico ou difícil deve ser testado exaustivamente (implícito por um argumento anterior)
  • Os testes de
  • não devem ser acoplados à implementação para permitir a refatoração abrangente (invalida o argumento anterior)
  • testes de efeitos colaterais, como chamar um serviço de terceiros com uma carga útil específica, não são necessários (portanto, nenhum teste de caixa preta)

Na verdade, há um tipo de teste que eu encontrei é geralmente aceito e que, em última análise, é inútil. Ou seja, testes baseados em GUI, como o uso de selênio, webdriver, watir ou arquillian. É assim que obtemos os ciclos de construção de 7 horas em vez dos ciclos de criação de 5 minutos nos meus projetos de TDD.

Esses mesmos desenvolvedores normalmente reclamam com todos os outros como o código é ruim e quão incompetentes os desenvolvedores anteriores devem ter sido. Eles também acham extremamente importante que você faça um design adequado usando um quadro branco, um MS office ou um wiki e tome muito cuidado para garantir que este design permaneça atualizado.

Esse último é o que realmente me fez perceber que esses desenvolvedores são fraudes. Todos nós sabemos que qualquer documento de projeto que não seja um teste de unidade se tornará desatualizado e não será mantido atualizado por causa do custo de manutenção para fazê-lo. Na verdade, tentei e tentei criar um bom meio para expressar idéias de design no formato MS Office, que fosse útil e legível antes e depois do fato de escrever código. Eu falhei em todos os casos e apesar de existirem pessoas que conseguem produzir um documento do MS Office que parece bonito, eu nunca realmente encontrei aqueles úteis.

Então, você tem uma escolha. Você pode projetar e documentar praticando TDD, que é o único método conhecido e comprovado para produzir tal documentação com base em meus 10 anos de experiência em desenvolvimento. Ou você pode entrar na política.

    
por 17.03.2012 / 15:44
fonte