Com a multiplicação de aparelhos mobile, navegadores e outros dispositivos IoT, criar testes automatizados de UI que sejam escaláveis e de fácil manutenção se tornou imprescindível. A criação desses testes nunca foi tão desafiadora. Testes frágeis e duvidosos podem gerar obstáculos para equipes com processos ágeis e DevOps, atrapalhando a entrega.

A UI é seguramente a parte mais frágil de qualquer aplicação. Qualquer mudança de planos e ideias de um produto gerará alteração na interface. Isto faz com que ela seja suscetível a ajustes frequentes, atrapalhando assim a manutenção dos testes automatizados de UI. O objetivo de cada testador é montar testes automáticos que são estáveis, escaláveis e reutilizáveis. Mais e mais testes automatizados estão sendo feitos na camada de interface. Mas quando ocorrem mudanças, o teste irá quebrar. Um bom exemplo disto é o uso de HTML em um website. Se o testador ou desenvolvedor está interagindo com cada elemento HTML ao invés de uma camada encapsuladora, então quando qualquer mudança for feita no elemento, o teste irá falhar.

Hoje os testadores já estão familiarizados com as dores de cabeça por conta de testes mal automatizados. Qualquer mudança feita na interface de usuário (UI) ou no código subjacente da aplicação pode induzir os testes automatizados ao erro. Isto leva ao gasto de várias horas para a manutenção, loops de feedbacks demorados dos desenvolvedores e a um obstáculo no ciclo de testes. A fragilidade dos testes é um problema que toda equipe se depara e geralmente acaba sendo ignorada ou considerada como um fenômeno natural, quando em baixa ocorrência. Reduzir o número de testes frágeis em até mesmo 10% pode gerar resultados de testes espantosos e positivos, melhorando a qualidade do ciclo de testes.

O problema principal ao lidar com testes frágeis é a impossibilidade de se livrar totalmente deles. O objetivo deste artigo é oferecer dicas práticas para ajudar você a reduzir a quantidade desses testes.

Compreendendo o impacto dos testes automatizados fragilizados

As equipes não podem contar apenas com o resultado de testes individuais para medir a eficácia do ciclos de testes automáticos. Uma taxa de êxito de 99,5% é promissora e muitos podem estar inclinados a aceitar isso, mas este não é o caso. A matemática nunca mente, então vamos olhar os números para compreender melhor.

Imagine que você tem 300 testes em uma suíte de teste, cada um com uma taxa de falha de 0,5%. Isto faz com o que a taxa de aprovação para cada teste seja de 99,5%. Entretanto, nenhuma equipe executa apenas um único teste, seja manual ou automático. Então é importante fazer a conta levando em consideração toda a suíte de teste. Na fórmula abaixo, calculamos a taxa de aprovação pelo número total de testes para alcançar a taxa de aprovação da suíte.

Taxa de aprovação da suíte de testes = (99.5%)^ 300 = 22.23%

Em uma escala macro, esses números não são ideais. A suíte de teste está sendo aprovada menos de 25% das vezes. E se a suíte tiver 400 testes? A aprovação cai drasticamente para 13,5%. E 500? Meros 8%.

Vamos pensar positivo! E se a taxa de aprovação individual for para 99,7%?

Taxa de aprovação da suíte de testes = (99.7%)^ 300 = 40%

A aprovação da suíte de testes quase dobrou com um aumento de 0,2%. Isto demonstra o porquê que mesmo uma taxa de erro de 0,5% não pode ser tolerada. Para equipes ágeis e DevOps, uma taxa de erro como essa pode se transformar em uma bola de neve, prejudicando toda a pipeline, atrasando progressos ou até mesmo entregas.

Todo teste passará 100% das vezes? Não, mas as equipes hoje precisam melhorar a taxa de falhas. Frações de uma porcentagem, mesmo uma melhoria marginal, podem fazer um mundo de diferença e as equipes vão colher frutos a curto e longo prazo, os processos escalonáveis vão ter ciclos mais rápidos e custos de manutenção reduzidos. Então, o que você pode fazer para evitar que os testes automatizados sejam frágeis? O importante é entender como eles se tornam frágeis e duvidoso antes de mais nada.

Codificação rígida e massa de dados ruins

Se um teste funciona independentemente de outro, então os dados também devem ser assim, armazenados separadamente.

Caso um teste seja dependente dos dados de outro teste, então é preciso tomar medidas para evitar que os dados sejam corrompidos durante cada execução e garantir que o próximo teste funcione adequadamente. Os dados precisam ser validados em cada etapa.

Não é incomum ter dados que foram criados de forma precária, que não cobrem todos os testes ou cenários. Testadores geralmente conseguem cobrir ambos os cenários positivos e negativos, mas é fácil esquecer dos pontos fora da curva. É importante prestar atenção nestes casos excepcionais.

Subutilização do número requerido de ambientes de teste

Os ambientes de teste muitas vezes são pensados como computadores físicos onde os testes são executados. Com a vasta quantidade de dispositivos nas mãos dos consumidores, cada um com seu sistema operacional, tamanho de tela e resolução, além do número de navegadores, os testes não são mais feitos em uma única interface, mas dezenas ou centenas..

No back-end, os vários ambientes de teste podem incluir serviços, outros pedaços da sua aplicação que seus testes podem interagir, redes ou APIs de terceiros. Com tantas variáveis, é essencial abranger o escopo de qualquer ambiente de teste para incluir tudo que sua aplicação pode interagir.

Subestimando complexidade tecnológica

Os softwares atuais raramente são individuais, eles dependem de uma rede de subsistemas para funcionarem corretamente. Vários desses subsistemas e os processos que eles implementam podem ser independentes do resto da aplicação.

Isto significa que os processos podem completar as funções designadas sem ter que esperar por feedback, transformando uma aplicação em um todo, assíncrono em natureza. Os testadores tem que levar em consideração o aumento de complexidade como esta, já que os testes executadas também serão assíncronos.

Aplicações geralmente são quebradas em múltiplos componentes para testes e os processos de teste geralmente consistem em múltiplas tarefas. No desenvolvimento de software, os testes que são sincrônicos podem ser executados em uma sequência particular ou um de cada vez.

Considere o seguinte exemplo:

  • Chamar ou atualizar dados de teste
  • Rodar os dados em um teste de UI
  • Esperar uma resposta

Neste exemplo, cada tarefa não pode ser executada até a anterior ter sido completada. Tarefas assíncronas podem ser iniciadas antes da primeira finalizar. Para combater essa questão, os testadores colocam intervalos de tempo aleatórios nos testes, o que geralmente causa dois problemas:

  • O intervalo de tempo pode não ser longo o bastante. Se não, o teste de UI quebrará quando a resposta não for longa o bastante, gerando assim um teste frágil.
  • Alternativamente, você pode ter o problema oposto. Se o intervalo de tempo for muito longo, você pode ficar esperando a resposta certa e seus testes vão ser lerdos.

Conclusão

Testes frágeis sempre existirão, especialmente na camada de interface. Durante as sessões de estratégias de desenvolvimento e de testes, isto precisa ser levado em consideração. Contudo, testes frágeis não devem ser tolerados e devem ser reduzidos o máximo possível em qualquer suíte de teste. Compreender a raiz do problema da fragilidade permite aos desenvolvedores e equipes implementarem métodos preventivos para evitar um pesadelo de escalabilidade e de manutenção. Ao gerenciar a fragilidade dos testes e mensurando não apenas a taxa de aprovação de testes individuais, mas também avaliando a taxa de sucesso e estabilidade de uma suíte de teste como um todo, possibilita às equipes a criação de testes de UI automatizados mais robustos e escaláveis. Isto aumenta a velocidade do ciclo de testes e a qualidade de software.

Newsletter

Assine nossa newsletter e seja avisado sobre novos artigos, cases, eventos e muito mais.

E-books e Relatórios

Conheça nossa base de ebooks, artigos, relatórios e cases. Aprenda sobre as boas práticas de testes, qualidade de software e muito mais.

Tudo disponível para download gratuitamente.