Basta dizer não aos testes de ponta a ponta

Você provavelmente teve isso quando você e seus amigos realmente queriam assistir a um filme e depois se arrependeu de ter passado algum tempo nele. Ou talvez você se lembre do momento em que sua equipe pensou que havia encontrado um "recurso matador" e encontrado suas "armadilhas" somente após o lançamento do produto.

As boas ideias geralmente falham na prática e, no mundo dos testes, uma estratégia de teste baseada na automação de teste de ponta a ponta é um bom exemplo disso.

Os testadores podem investir seu tempo escrevendo muitos tipos de testes automatizados, incluindo testes de unidade, testes de integração e testes de ponta a ponta, mas essa estratégia visa principalmente testes de ponta a ponta que testam o produto ou serviço como um todo. Normalmente, esses testes imitam cenários reais do usuário.

Fonte

Testes de ponta a ponta em teoria


Embora confiar principalmente nos testes de ponta a ponta é uma péssima idéia, em teoria você pode apresentar vários argumentos a favor dessa afirmação. 

Portanto, o número um na lista do Google de dez coisas que, como sabemos, é verdadeiro: "Os interesses dos usuários acima de tudo". Portanto, usar testes de ponta a ponta que se concentram em cenários reais do usuário parece uma ótima idéia. Além disso, essa estratégia geralmente é atraente para muitos participantes do processo.

  • Os desenvolvedores gostam dessa estratégia, porque você pode transferir a maioria dos testes, se não todos, para outros.
  • , , , , , , .
  • ,   , ; .

End-2-end


Então, se essa estratégia de teste parece tão boa em teoria, o que há de errado com ela na prática? Para demonstrar isso, apresentarei um cenário fictício abaixo, mas baseado em situações reais familiares a mim e a outros testadores. 

Suponha que uma equipe crie um serviço para editar documentos online (por exemplo, Google Docs). Vamos supor que a equipe já tenha uma infraestrutura fantástica para teste. Toda noite:

  • Cria a versão mais recente do serviço,
  • essa versão é implantada no ambiente de teste da equipe,
  • nesse ambiente de teste, todos os testes de ponta a ponta são executados,
  • A equipe recebe um relatório por email resumindo os resultados do teste.

O prazo está se aproximando rapidamente. Para manter um alto nível de qualidade do produto, digamos que decidimos que pelo menos 90% dos testes finais bem-sucedidos são necessários para que possamos considerar que a versão está pronta. Digamos que o prazo final chegue em um dia.


Apesar de vários problemas, os testes acabaram revelando erros reais.

O que correu bem Os

erros que afetam o usuário foram identificados e corrigidos antes de chegarem a ele.

Algo deu errado

  • A equipe concluiu sua fase de programação uma semana depois (e trabalhou muitas horas extras).
  • Encontrar a causa raiz do teste com falha de ponta a ponta consome muito tempo e pode levar muito tempo.
  • Falhas na equipe paralela e mau funcionamento do equipamento moveram os resultados do teste por vários dias.
  • Muitos erros menores estavam ocultos atrás de erros grandes.
  • Os resultados dos testes de ponta a ponta não são confiáveis ​​às vezes.
  • Os desenvolvedores tiveram que esperar até o dia seguinte para descobrir se a correção funcionou ou não.

Portanto, agora que sabemos o que deu errado na estratégia de ponta a ponta, precisamos mudar nossa abordagem de teste para evitar muitos dos problemas acima. Mas qual é a abordagem correta?

O verdadeiro valor dos testes


Como regra, o trabalho do testador termina quando o teste falha. O erro é registrado e, em seguida, a tarefa do desenvolvedor é corrigir o erro. No entanto, para determinar onde a estratégia de ponta a ponta não funciona, precisamos ir além desse pensamento e abordar o problema usando nossos princípios básicos. Se “focarmos no usuário (e tudo o mais segue)”, devemos nos perguntar: o teste reprovado beneficia o usuário? 

Aqui está a resposta: "Um teste com falha não beneficia diretamente o usuário".

Embora essa afirmação, à primeira vista, pareça chocante, é verdade. Se o produto funcionar, ele funciona, independentemente de o teste dizer que funciona ou não. Se um produto está quebrado, ele está quebrado, independentemente de o teste indicar que está quebrado ou não. Portanto, se os testes reprovados não beneficiam o usuário, o que o beneficia?

Correções de bugs beneficiam diretamente o usuário.

O usuário ficará feliz apenas quando esse comportamento imprevisível (erro) desaparecer. Obviamente, para corrigir um erro, você deve saber que ele existe. Para descobrir que existe um erro, idealmente, você deve ter um teste que o detecte (porque, se o teste não detectar o erro, o usuário o encontrará). Porém, em todo o processo, desde a falha do teste até a correção do erro, o valor agregado aparece na última etapa.


Portanto, para avaliar qualquer estratégia de teste, você não pode apenas avaliar como ela encontra erros. Você também deve avaliar como isso permite que os desenvolvedores os corrijam (e até evitem).

Construindo o feedback certo


Os testes criam um ciclo de feedback que informa o desenvolvedor sobre se o produto está funcionando ou não. Um loop de feedback ideal tem várias propriedades.

  • . , , . ( ), . . , .
  • . , , , . , , .
  • Deve permitir que você encontre erros rapidamente. Para corrigir o erro, os desenvolvedores precisam encontrar as linhas de código específicas que causam o erro. Quando um produto contém milhões de linhas de código e o erro pode estar em qualquer lugar, é como tentar encontrar uma agulha no palheiro.

Pense pequeno, não grande


Então, como criamos esse loop de feedback perfeito? Pensando no pequeno, não no maior.

Teste de

unidade Os testes de unidade pegam um pequeno pedaço do produto e o testam isoladamente de todo o resto. Eles quase criam o mesmo loop de feedback perfeito:

  • Os testes de unidade são rápidos. Precisamos escrever um pequeno bloco de código e já podemos testá-lo. Testes de unidade são geralmente bem pequenos. De fato, um décimo de segundo é muito longo para testes de unidade.
  • . , , . , — , , — .
  • . , , , , .

Escrever testes de unidade eficazes requer habilidades em áreas como gerenciamento de dependências, stubs / zombarias de escrita e testes rigorosos. Não descreverei essas habilidades aqui, mas, para começar, o exemplo típico oferecido ao novo Googler (ou como são chamados no Google, o Noogler) é como o Google cria e testa o cronômetro.

Testes de unidade contra testes de ponta a ponta

Para testes de ponta a ponta, você precisa esperar: primeiro para criar o produto inteiro, depois para implantá-lo e, finalmente, para concluir todos os testes de ponta a ponta. Quando os testes ainda funcionarem, é mais provável que falhem periodicamente. E mesmo que o teste detecte um erro, ele pode estar em qualquer lugar do produto.

Embora os testes de ponta a ponta sejam melhores na modelagem de cenários reais de usuários, essa vantagem é rapidamente superada por todas as deficiências do ciclo de feedback de ponta a ponta:


Testes de integração Os testes de

unidade têm uma grande desvantagem: mesmo que os módulos funcionem bem separadamente, você não sabe se eles funcionam bem juntos. Mas, mesmo assim, você não precisa executar testes de ponta a ponta. Você pode usar o teste de integração para isso. O teste de integração pega um pequeno grupo de módulos, geralmente dois, e testa seu comportamento como um todo.

Se os dois blocos não se integram corretamente, por que escrever um teste de ponta a ponta quando você pode escrever um teste de integração muito menor e mais focado que detecta o mesmo erro? Obviamente, você deve entender todo o contexto ao testar, mas para testar o trabalho de dois módulos juntos, basta expandir um pouco a perspectiva.

Pirâmide de teste


Mesmo nos testes de unidade e de integração, você provavelmente precisará de um pequeno número de testes de ponta a ponta para testar o sistema como um todo. Para encontrar o equilíbrio certo entre os três tipos de testes, é melhor usar uma pirâmide de testes visuais. Aqui está uma versão simplificada da pirâmide de teste do discurso de abertura da conferência de 2014 da Google Test Automation .


A maior parte dos seus testes são testes de unidade na parte inferior da pirâmide. À medida que você sobe na pirâmide, seus testes se tornam mais abrangentes, mas, ao mesmo tempo, o número de testes (a largura da sua pirâmide) diminui.

De uma maneira boa, o Google oferece uma separação 70/20/10: 70% de testes unitários, 20% de testes de integração e 10% de testes de ponta a ponta. A proporção exata será diferente para cada equipe, mas em geral ela deve manter a forma da pirâmide. Tente evitar os seguintes "formulários":

  • Pirâmide invertida / casquinha de sorvete. A equipe depende principalmente de testes de ponta a ponta, usando vários testes de integração e muito poucos testes de unidade.
  • Ampulheta. A equipe começa com um grande número de testes de unidade e, em seguida, usa testes de ponta a ponta onde os testes de integração devem ser usados. A ampulheta tem muitos testes de unidade na parte inferior e muitos testes de ponta a ponta na parte superior, mas poucos testes de integração no meio.

Assim como uma pirâmide comum tende a ser a estrutura mais estável na vida real, uma pirâmide de teste também tende a ser a estratégia de teste mais estável.

Empregos


Se você gosta e sabe escrever testes de unidade, é bem-vindo! A empresa LANIT abriu uma vaga para o desenvolvedor Java na equipe DevOps, onde você encontrará pessoas que pensam da mesma forma.

All Articles