Fone: 8h - 17PM

Dextra

Boas práticas ao criar testes com Selenium

Por: Dherik Barison 12/11/2013

Olá, pessoal!

Testes automatizados são um assunto de suma importância para um sistema. Uma das ferramentas de grande destaque nesta área, quando estamos falando de sistemas web, é o Selenium.

É importante ter o entendimento de como usar da melhor maneira o Selenium, evitando trilhar caminhos perigosos no seu uso e extraindo o que há de melhor dele. Sendo assim, este texto segue com algumas dicas de utilização do Selenium que podem poupar o desenvolvedor de alguns problemas.

Mas, de quais problemas estamos falando?

Os principais problemas que observo no uso de Selenium estão relacionados a sua instabilidade: testes que passam às vezes, testes que só passam na máquina do outro, testes que só passam se outros testes anteriormente forem executados, testes que só passam se executados individualmente…

O blog de testes do Google já falou deste assunto. O blog com dicas de selenium também detalha tecnicamente alguns pontos que abordaremos aqui, mas vou acrescentar mais algumas observações.

Vamos aos problemas!

Isolamento deficiente dos testes

Esta deve ser a principal preocupação do desenvolvedor antes de começar a criar qualquer suíte de teste. É muito importante que o teste não dependa de um resultado de outro teste.

O erro mais comum neste aspecto é com relação a base de dados. Ao utilizar o Selenium, o sistema está sendo testado desde a tela até a persistência de informações. O teste, ao final da execução, deixará as informações que ele persistiu/alterou/removeu neste banco. Assim, o desenvolvedor deve implementar um meio da base de dados ser limpa antes de cada teste ser executado.

O recomendado, devido a flexibilidade, é utilizar bancos de dados como o HyperSQL aliado a um container leve (como o MyContainer) para que os testes possam ser executados rapidamente e com o mínimo de recursos.

Problemas com tempos de espera

Quando estamos escrevendo testes funcionais, é preciso ter um controle de espera para que uma ação seja disparada depois de uma outra. Esta ação pode ser o clique de um botão para salvar um formulário, preenchimento de um campo, clique em um link para abrir um popup, etc.

Estas ações precisam ser, de alguma maneira, coordenadas. Quando uma terminar, a outra precisa ser executada. Mas, quanto tempo demora cada ação?

Para responder esta pergunta, devemos esclarecer que o Selenium permite 2 tipos de controle de espera: o explicito e o implícito.

Um tempo de espera explicito pode ser feito de 2 maneiras. Uma delas é usando Thread.sleep(). Basicamente, você determina um tempo fixo no qual alguma ação no teste precisa esperar antes de ser executada. A desvantagem desta técnica é que se a ação estiver pronta para ser executada antes do tempo fixado do Thread.sleep, o teste vai precisar aguardar sempre este tempo. Se este tempo ser ultrapassado, o teste falhará.

[gist]https://gist.github.com/dherik/7327231[/gist]

Por este tempo não ser sempre o mesmo em todas as situações, devemos evitar usar tempos de espera fixos. Há tantas ações, com diferentes tempos, em diferentes situações, que é humanamente impossível escrever um teste controlando o tempo preciso entre cada ação possível. Segundo, mesmo que isto fosse possível, eventualmente eles falhariam pois este tempo pode ser maior, já que é esperado que o teste seja executado em diferentes computadores com concorrência de recursos com outros processos no mesmo computador.

A outra forma de tempo explicito no Selenium é usar o WebDriverWait. É uma implementação disponível no Selenium que permite esperar por um determinado elemento na tela, com um tempo de espera máximo. Se o elemento for encontrado antes do tempo de espera máximo, o teste continua.

[gist]https://gist.github.com/dherik/7327322[/gist]

Mesmo com o uso do WebDriverWait, escrever um teste funcional pode ficar custoso de se implementar ao tentarmos controlar cada elemento que cada ação deve esperar antes de ser executada.

Se existir esta possibilidade, uma maneira de contornar isto é de usar como referência aquela animação de tempo de espera entre uma ação e outra, comum em muitos sistemas web, representada por uma imagem animada (um arquivo Gif), que mostra quando uma ação Ajax é disparada no sistema. Quando o request Ajax retorna, a imagem é escondida e assim o usuário pode continuar a utilizar o sistema. Desta maneira é possível determinar que a próxima ação pode ser executada assim que a animação desaparecer.

O tempo implícito é um tempo padrão de espera para qualquer elemento no DOM. Se desejamos escrever um texto em um campo, por exemplo, o Selenium obedecerá este tempo implícito antes de acusar um erro de que aquele elemento não existe. Este tempo deve ser muito baixo, para evitar que o Selenium fique esperando muito tempo por um elemento na tela antes de acusar um erro de tempo de espera excedido. O valor padrão deste tempo é 0. A necessidade do seu aumento pode ser um sintoma de problemas em controle de tempo entre ações no teste, portanto, tenha muita consciência ao aumentá-lo, pois ele influenciará todos os testes.

[gist]https://gist.github.com/dherik/7327336[/gist]

Um exemplo de efeito colateral do aumento do tempo implícito é se o desenvolvedor deseja saber se um elemento não está presente na tela. Ao aumentar o tempo implícito, o sistema demorará exatamente este tempo para dizer que este elemento não está presente, o que impactará diretamente no tempo de execução dos testes.

Existem várias outras boas práticas no uso do Selenium, como uso do PageObject e outras pequenas práticas, mas as listadas acima, provavelmente, serão as que mais terá problemas se não segui-las.

Agradecimentos ao Tiago Bento pela revisão do texto.

 

Tags

Comentários