Testes de ponta a ponta versus testes de unidade, os testes devem ser dissociados?

23

Em nossa empresa, normalmente garantimos que escrevemos um teste de ponta a ponta para nossos sites / aplicativos da web. Isso significa que acessamos um URL, preenchemos um formulário, enviamos o formulário para outro URL e verificamos os resultados da página. Fazemos isso para testar a validação do formulário, testar se os modelos HTML têm as variáveis ​​de contexto corretas etc.

Também o usamos para testar indiretamente a lógica subjacente.

Foi-me dito por um colega de trabalho que a razão para isso é que podemos extrair e alterar a implementação subjacente a qualquer momento, desde que os testes de ponta a ponta passem.

Gostaria de saber se esse tipo de dissociação faz sentido ou se é apenas uma maneira de evitar a gravação de testes para unidades menores de código?

Rudolf Olah
fonte
6
was told by a co-worker that the reason for this is that we can rip out and change the underlying implementation at any point as long as the end-to-end tests pass.- Isso também vale para testes de unidade. Parece-me que os testes de ponta a ponta estão sendo usados ​​como desculpa para não escrever testes de unidade.
Robert Harvey
12
Isso não é verdade para testes de unidade. Alterar / remover / criar métodos ou classes exige a atualização de todos os testes de unidade para esses métodos ou classes. Não é assim nos testes de ponta a ponta, a menos que a funcionalidade do usuário final esteja mudando. Contanto que seja um refator no nível do sistema (sem modificação da funcionalidade do usuário final), nenhuma alteração será necessária nos testes de ponta a ponta.
Dietbuddha #
2
@dietbuddha, acho que o conceito geral é verdadeiro para testes de unidade, mas em um escopo menor (unidade).
Sam

Respostas:

38

Testes de ponta a ponta também são necessários. De que outra forma você pode saber que conectou todas as unidades corretamente? No código muito simples, é possível testar todos os caminhos através do código apenas com testes de ponta a ponta, mas à medida que você obtém mais camadas, fica proibitivamente mais caro fazê-lo.

Por exemplo, digamos que você tenha três camadas, cada uma com cinco caminhos possíveis. Para testar todos os caminhos em todo o aplicativo, seriam necessários 5 3 testes de ponta a ponta, mas você pode testar todos os caminhos em cada unidade com apenas 5,3 testes de unidade. Se você fizer apenas testes de ponta a ponta, muitos caminhos acabam sendo negligenciados, principalmente em tratamento de erros e condições de contorno.

Karl Bielefeldt
fonte
Essa é uma boa resposta. Eu vejo o valor de ambos, mas vendo o número de possibilidades para testar completamente todos os caminhos com fim a testes finais é útil para explicar por que a unidade de teste precisa ser feito mais do que é
Rudolf Olah
14
Vejo os testes de unidade como valiosos principalmente porque localizam os problemas rapidamente. De ponta a ponta são valiosas porque dão a você a confiança de que tudo funciona em conjunto.
21713 Jason Swett
20

Sim, testes de ponta a ponta (ou testes de integração) fazem muito sentido, mas também os testes de unidade. Idealmente, você tem os dois, pois os dois normalmente capturam diferentes tipos de bugs. Portanto, ter testes de ponta a ponta nunca deve ser uma desculpa para não ter testes de unidade.

Doc Brown
fonte
2
Uma nota rápida sobre a redação; mesmo que não seja uma ciência exata, muitas pessoas dirão que testes de ponta a ponta e testes de integração são coisas diferentes. Veja stackoverflow.com/questions/4904096/…
sbrattla 15/15
6

Depois de mais alguns anos de codificação e trabalho em projetos, fornecerei uma resposta para minha própria pergunta.

Sim, você deve escrever testes de unidade. Os testes de ponta a ponta são mais difíceis de escrever e quebradiços, especialmente se eles dependem dos componentes da interface do usuário.

Se você estiver usando uma estrutura como Django ou Rails (ou suas próprias classes personalizadas), deverá ter uma classe de formulário que manipulará a validação do formulário. Você também terá classes de exibição que exibem modelos renderizados e o formulário e lidam com solicitações GET e POST.

Em um teste completo, você:

  1. pegue o url
  2. preencha o formulário com dados válidos
  3. postar o formulário no URL
  4. verifique se o banco de dados foi atualizado ou se alguma ação foi executada como resultado do formulário válido

Você está testando muito código e sua cobertura será muito boa, mas você só está testando o caminho feliz quando tudo der certo. Como você garante que o formulário tenha a validação correta? E se esse formulário for usado em várias páginas? Você escreve mais um teste de ponta a ponta?

Vamos tentar novamente com testes de unidade:

  1. teste o método view GET
  2. teste o método view POST com um formulário falso / simulado
  3. teste o formulário com dados válidos
  4. teste o formulário com dados inválidos
  5. testar os efeitos colaterais do formulário

Usando testes de unidade, você está testando pedaços menores de código e os testes são específicos e fáceis de escrever. Quando você combina isso com o TDD (Test Driven Development), obtém um código de qualidade superior.

A facilidade de escrever testes de unidade não deve ser descartada, porque quando você está em um projeto que não possui testes automatizados, precisa começar de algum lugar. Começar com testes de unidade é mais fácil e rápido e permite iniciar imediatamente o teste de bugs, e não apenas do caminho feliz.

Rudolf Olah
fonte
outro ponto de dados, o Blog de testes do Google diz não para mais testes no fim do fim: googletesting.blogspot.ca/2015/04/…
Rudolf Olah
5

Na verdade, testes de ponta a ponta ou testes de integração são mais importantes que os testes de unidade, pois garantem que você tenha um sistema totalmente funcional. Os testes de unidade não cobrem a parte de integração de um sistema, o que é uma tarefa complicada, especialmente em grandes projetos.

No entanto, como já foi dito, você também deve realizar testes de unidade, pois é mais complicado detectar os casos extremos nos testes de integração.

m3th0dman
fonte
1

Ele verifica o comportamento do sistema, enquanto os testes de unidade verificam o comportamento da unidade. Os benefícios e custos para cada um são diferentes. Você poderia fazer um ou outro ou ambos.

No meu trabalho, realizamos Desenvolvimento Orientado a Testes de Aceitação sem testes de unidade que se parecem com o que você descreveu. Começamos fazendo ambos, e com o tempo, acabamos eliminando os testes unitários com o custo que excede os benefícios para nós.

Dito isto, acho que o custo / benefício para o domínio e o ambiente do problema deve conduzir as decisões para se envolver em qualquer prática de desenvolvimento, incluindo diferentes práticas de teste automatizado. Em vez de fé, prefiro que todas as práticas tenham evidências empíricas dentro do contexto de que são usadas para apoiá-las.

dietbuddha
fonte
O que me preocupa é que iremos codificar para testes de aceitação que levam a classes ou métodos grandes em vez de unidades menores.
Rudolf Olah
@ouse: Só porque você não está escrevendo testes de unidade, não há razão para não escrever um bom código. No entanto, se você tiver programadores inexperientes ou apenas maus hábitos, os benefícios podem superar os custos. Em qualquer um dos casos, você deve fazer a análise e reduzi-la a uma equação simples. For Any Practice: Practice iff Benefit > Cost
dietbuddha