Uma das coisas que notei usando Selenium é que as vezes você fica perdido quando um teste falha.
Nem sempre a mensagem de erro retornada pelo Junit ou pelo Selenium é suficiente para entender o porquê de um teste falhar.
A imagem do browser na hora em que houver uma falha pode te auxiliar na detecção do verdadeiro erro do seu teste ou sistema.
O Selenium possuí 2 comandos para dar screenshot:
1- captureScreenshot(String fileName)
Esse comando captura toda a tela. É como se você desse um print screen com o teclado.
Ficaria mais ou menos assim:
2- captureEntirePageScreenshot (String filename, String kwargs);
Esse comando captura toda a página que está no browser.
A imagem ficaria assim:
O benefício do captureScreenshot é que funciona em todos os browsers. Em compensacão, se sua página é muito grande, ou seja, você precisa usar a barra de rolagem para ver a página inteira, a imagem gerada apenas conterá a parte visível. Com o captureEntirePageScreenshot esse problema não acontece, mesmo que a página tenha scroll, a imagem final será da página completa. O contra do captureEntirePageScreenshot é que ele só funciona nativamente no Firefox. Para funcionar no IE, você precisa instalar uma ferramenta http://snapsie.sourceforge.net.
Agora que você já sabe qual o comando para tirar screenshot com o Selenium, vamos agora aprender a tirar o screenshot apenas quando seu teste em Junit der erro.
Para isso você vai ter que usar a versão 4.7 ou mais recente do Junit.
Primeiro você precisa criar uma classe que implemente a interface MethodRule. Depois você precisa implementar o método apply com a lógica de chamar o comando de capturar a tela. A classe ficaria mais ou menos assim:
package br.com.seuenium; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; import com.thoughtworks.selenium.Selenium; public class ScreenshotRule implements MethodRule { public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object testCase) { return new Statement() { public void evaluate() throws Throwable { try { statement.evaluate(); } catch (Throwable e) { try { ExemploTest exemploTest = (ExemploTest) testCase; Selenium selenium = exemploTest.getSelenium(); if(selenium != null) { String fileName = "/tmp/image.png"; selenium.captureEntirePageScreenshot(fileName, ""); } } catch (Exception e2) { System.err.println("Não foi possível capturar o screenshot"); } throw e; } } }; } }
Esse código chama o método evaluate do statement que corresponde à execução de um método anotado com @Test. Se retornar uma exceção, o comando de capturar a tela é acionado.
Em seguida, na sua classe de teste, você deve criar um atributo público do tipo ScreenshotRule e deve inicializá-lo na própria declaração e anotá-lo com @Rule.
Deve ficar mais ou menos assim:
package br.com.seuenium; import junit.framework.Assert; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.thoughtworks.selenium.DefaultSelenium; import com.thoughtworks.selenium.Selenium; public class ExemploTest { private Selenium selenium; @Rule public ScreenshotRule screenshotRule = new ScreenshotRule(); @Before public void start(){ selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.seuenium.com.br"); selenium.start(); } @After public void stop(){ selenium.stop(); } @Test public void testErro() { selenium.open("/testes/7-screenshot/teste.php"); Assert.assertEquals("Hello World", selenium.getText("id=inexistente")); } @Test public void testSucesso() { selenium.open("/testes/7-screenshot/teste.php"); Assert.assertEquals("Hello World", selenium.getText("id=existente")); } public Selenium getSelenium() { return selenium; } }
Eu criei um projeto maven pronto para ser executado. Basta fazer o download aqui.
Descompacte o arquivo, entre no diretório e execute “mvn clean install”. O testErro irá falhar e você poderá ver o screenshot em target/testErro.png.
Bom, é isso pessoal. Qualquer dúvida mandem um comentário.
Até a próxima.