Skip to content

Instantly share code, notes, and snippets.

@dmds1993
Last active September 17, 2015 01:55
Show Gist options
  • Save dmds1993/6e7a2f31e6386c84619f to your computer and use it in GitHub Desktop.
Save dmds1993/6e7a2f31e6386c84619f to your computer and use it in GitHub Desktop.
Artigo Selenium WebDriver blog stefan teixeira e Sleides de Rodrigo Branas
http://pt.slideshare.net/rodrigobranas/selenium-webdriver-34165867
Home
Subscribe
Entendendo os tipos de esperas no Selenium WebDriver
29 April 2014 on selenium, java
Ter um mecanismo de espera confiável é um dos maiores desafios quando estamos trabalhando com automação de testes pela UI. Neste post, vou explicar sobre os tipos de esperas no Selenium WebDriver (em Java) e como usá-las. No final do post, serão descritos dois casos um pouco mais complexos e como foram solucionados.
No Selenium WebDriver, de acordo com a própria documentação, existem dois tipos de esperas: implícita e explícita.
Implícita
A espera implícita serve, basicamente, para dizer ao WebDriver um tempo máximo pelo qual ele deve aguardar quando estiver tentando encontrar um elemento. Exemplo:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Lembretes:
Tempo default é 0 (zero) segundos.
Basta setar o valor uma vez!
10 segundos costuma ser um tempo razoável.
É um recurso útil, mas não use somente ele. A espera explícita é mais flexível e confiável para seus testes, principalmente se a aplicação a ser testada usa muito JavaScript ou AJAX.
Explícita
A espera explícita diz ao WebDriver uma condição (ou tempo) para que ele aguarde antes de prosseguir com o teste. Um exemplo de espera explícita é o polêmico Thread.sleep(), que deve ser evitado ao máximo por ser uma má prática e por ser muito dependente do browser, da máquina onde os testes estão sendo rodados, ou até de alguma integração que sua aplicação possa ter com outros sistemas.
Com isso, use o WebDriverWait! Exemplo:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("botaoOk")));
Lembrete:
Tempo de polling default é de 0,5 segundos (ou 500 milissegundos).
A classe ExpectedConditions
Na classe ExpectedConditions, existem várias condições predefinidas para usar nos seus testes. Abaixo, vou listar as condições que mais uso e dar algumas dicas.
Visibilidade de elementos
visibilityOfElement / visibilityOfElementLocated
Dica: opte por essa ExpectedCondition em vez da "presenceOfElement". A "presence" verifica apenas que o elemento está no DOM, enquanto a "visibility" verifica que o elemento está presente E enabled (ou seja, disponível para interação).
Texto presente em elemento
textToBePresentInElement / textToBePresentInElementLocated
Útil para aguardar até que uma mensagem de sucesso apareça em uma div, por exemplo. Lembrando que, para aguardar até que um texto esteja presente em um input de texto qualquer, use a ExpectedCondition "textToBePresentInElementValue".
Frames
frameToBeAvailableAndSwitchToIt
Como o nome diz, aguarda até que o frame esteja disponível e muda para ele, dessa forma não precisamos escrever o tão odiado "driver.switchTo().frame()".
Aguardar até que um checkbox (ou radio button) esteja selecionado
elementToBeSelected / elementSelectionStateToBe(WebElement element, true) / elementSelectionStateToBe(By locator, true)
Lembrando que é muito importante, principalmente com checkboxes, colocar uma espera como essa após o clique no elemento. Seu teste pode rodar "rápido demais" e acabar não dando tempo de selecionar o checkbox.
Aguardar até que um checkbox (ou radio button) esteja deselecionado
elementSelectionStateToBe(WebElement, false) / elementSelectionStateToBe(By locator, false)
Mesma dica que comentei acima.
Outros casos
Aplicações que usam muito AJAX
Em aplicações que usam muito AJAX, com campos muito dinâmicos, o WebDriver pode acabar "se perdendo" e lançando exceções como NoSuchElementException ou StaleElementReferenceException. O grande problema é que esses erros podem ser intermitentes, gerando falsos negativos. Testes com essa característica são chamados de flaky tests.
Passei por diversos problemas como esse ao testar aplicações que usam AJAX demais nos campos. A solução foi adicionar ignores à instância de wait, para aguardar pela condição especificada, ignorando as exceções que citamos. Além disso, acabei conhecendo e utilizando a classe FluentWait, que, segundo a API:
"é uma implementação da interface Wait que permite configurar o tempo de timeout, o intervalo de polling e adicionar ignores para exceções específicas."
Você pode declarar uma instância de FluentWait da seguinte forma:
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(10, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
Fica fácil de ler o que código acima faz: cria uma instância de FluentWait com timeout de 10 segundos, intervalo de polling de 1 segundo, e ignorando as exceções NoSuchElementException e StaleElementReferenceException. O FluentWait é extremamente flexível e pode ser usado nas mais complexas situações.
Alan Richardson (Evil Tester), autor dos livros "Selenium Simplified" e "Java For Testers", escreveu um post muito interessante sobre o uso do FluentWait com WebElements.
Aguardar até o valor de um atributo mudar
Em algum momento, pode surgir a necessidade de aguardar até que algum atributo de um elemento mude, por exemplo. Porém, essa prática não é muito recomendada (seção "Waiting for attributes"), então use-a com cuidado (ainda assim, é melhor do que usar Thread.sleep).
Vamos considerar o seguinte exemplo, que vivenciei recentemente:
Figura inputs
Na imagem acima vemos dois inputs de texto (A e B) e um botão "Calcular". Suponha que quando informo um valor no Input A e clico no botão, é feita uma requisição a um sistema externo e um valor é calculado e exibido no Input B. De acordo com as ExpectedConditions que vimos anteriormente, poderíamos, a princípio, usar a "textToBePresentInElementValue" para automatizar a espera dessa requisição, certo?
Poderíamos, mas apenas se soubéssemos exatamente qual valor seria retornado pela requisição. No caso, isso não era trivial e não era o foco do teste. Nesse teste, precisávamos apenas do Input B preenchido para prosseguir com o preenchimento de um form. Logo, bastava aguardar até que a tag "value" do Input B tivesse algum valor qualquer diferente de vazio.
A classe ExpectedCondition permite que você crie suas próprias condições customizadas. O exemplo em questão foi resolvido usando uma espera como a seguinte:
public static void aguardaAteQueValueMude(final WebElement element)
{
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
String value = element.getAttribute("value");
if(!value.equals("")) {
return true;
}
return false;
}
});
}
No trecho de código acima, observe que estou criando uma ExpectedCondition booleana que, a cada intervalo de polling, vai recuperar o conteúdo da tag "value" do elemento (no caso, o Input B) e, caso esse valor seja diferente de vazio (""), a condição retorna true. Caso contrário, após os 10 segundos de timeout, retorna false.
Para complementar, recomendo dar uma olhada nos links abaixo (alguns deles foram citados no texto). Recomendo também a palestra da Trish Khoo (Google) sobre falhas intermitentes, apresentada na Selenium Conference 2013.
Compartilhem suas dúvidas nos comentários, até o próximo post! :)
Referências
WebDriverAdvanced
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html
http://seleniumsimplified.com/2012/08/fluentwait-with-webelement/
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/FluentWait.html
http://blog.mozilla.org/webqa/tag/webdriverwait/
http://vnrtech.blogspot.com.br/2013/04/selenium-explicit-wait.html
Sobre o autor: Stefan Teixeira trabalha como QA Engineer e, desde o final de 2014, tem se aventurado no mundo DevOps. É Bacharel em Ciência da Computação pela UFRJ e MBA em Garantia de Qualidade de Software pela Escola Politécnica da UFRJ. Entusiasta de Testes Automatizados (e de tudo que possa ser automatizado!), Agile Testing e da cultura DevOps.
Contatos: stefanfk@gmail.com | Twitter | LinkedIn
Stefan Teixeira
Read more posts by this author.
Share this post
Stefan Teixeira © 2015
Proudly published with Ghost
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment