Capturando a tela com o Selenium e Junit

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:

Tela Inteira

2- captureEntirePageScreenshot (String filename, String kwargs);

Esse comando captura toda a página que está no browser.
A imagem ficaria assim:

Página Inteira

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.

Tags: , ,

  • Israel

    Seu Enium,

    Por favor, qual a sua opinião em relação a comparação Junit x TestNG ?
    Seu estivesse começando um projeto hoje,qual seria a sua recomendação?

    Obrigado,
    Israel

  • Israel

    Seu Enium,

    Por favor, qual a sua opinião em relação a comparação Junit x TestNG ?
    Seu estivesse começando um projeto hoje,qual seria a sua recomendação?

    Obrigado,
    Israel

  • http://www.seuenium.com.br Enium

    O Junit é mais simples e mais conhecido. A maioria das IDEs já possuem uma integração nativa e você não precisa instalar nenhum plugin adicional.
    O TestNG tem mais funcionalidades mas nem todo mundo conhece.
    No google achei um post sobre as diferenças dos dois… Dê uma olhada:
    http://lijinjoseji.wordpress.com/2008/02/29/testng-56-and-junit-44-which-framework-you-will-choose-for-unit-testing/

  • http://www.seuenium.com.br Enium

    O Junit é mais simples e mais conhecido. A maioria das IDEs já possuem uma integração nativa e você não precisa instalar nenhum plugin adicional.
    O TestNG tem mais funcionalidades mas nem todo mundo conhece.
    No google achei um post sobre as diferenças dos dois… Dê uma olhada:
    http://lijinjoseji.wordpress.com/2008/02/29/testng-56-and-junit-44-which-framework-you-will-choose-for-unit-testing/

  • http://blog.klaus.pro.br/ Klaus Paiva

    Bem legal essa dica hein seu Enium!

  • http://blog.klaus.pro.br/ Klaus Paiva

    Bem legal essa dica hein seu Enium!

  • http://sembugs.blogspot.com Elias Nogueira

    Parabés pelo blog e pelo post “Seu Enium”
    E aproveitando pra responder a pergunta do Israel, o melhor é utilizar o TestNG, uma vez que ele possui uma gama de funcionalidades para agrupar, re-executar testes que falharam, criar “tags” para os testes, etc.. Além de poder rodar os testes de forma distribuidas com o TestNG + Selenium.

    Abraços!

  • http://sembugs.blogspot.com Elias Nogueira

    Parabés pelo blog e pelo post “Seu Enium”
    E aproveitando pra responder a pergunta do Israel, o melhor é utilizar o TestNG, uma vez que ele possui uma gama de funcionalidades para agrupar, re-executar testes que falharam, criar “tags” para os testes, etc.. Além de poder rodar os testes de forma distribuidas com o TestNG + Selenium.

    Abraços!

  • Thiago

    Seu Enium

    Tentei rodar as classes no eclipse+selenium-rc+junit, sempre cai” Não foi possível capturar o screenshot”, tenho configurar firefox ou algo a mais.
    Eu estou usando sistema operacional windows mudei o caminho mas não sei se add correto.

    Obrigado

    Abraços.

  • Thiago

    Seu Enium

    Tentei rodar as classes no eclipse+selenium-rc+junit, sempre cai” Não foi possível capturar o screenshot”, tenho configurar firefox ou algo a mais.
    Eu estou usando sistema operacional windows mudei o caminho mas não sei se add correto.

    Obrigado

    Abraços.

  • http://www.seuenium.com.br Enium

    Rodei no Windows XP o exemplo que dá pra baixar aqui http://www.seuenium.com.br/testes/7-screenshot/screenshot-selenium.zip e não teve problemas. Você tem o stacktrace do erro?

  • http://www.seuenium.com.br Enium

    Rodei no Windows XP o exemplo que dá pra baixar aqui http://www.seuenium.com.br/testes/7-screenshot/screenshot-selenium.zip e não teve problemas. Você tem o stacktrace do erro?

  • Thiago

    Seu Enium

    O problema que o sistema fechava o browser na hora do erro,antes de tirar o print ai caia na condição” Não foi possível capturar o screenshot”.
    Coloquei para parar o selenium depois do print ficou perfeito.

    Obrigado.

  • Thiago

    Seu Enium

    O problema que o sistema fechava o browser na hora do erro,antes de tirar o print ai caia na condição” Não foi possível capturar o screenshot”.
    Coloquei para parar o selenium depois do print ficou perfeito.

    Obrigado.

  • Leonardo Neuwald

    Seu Enium

    Estou iniciando no mundo dos testes, e testes automatizados.
    Onde trabalho, utilizo a ferramenta TestLink para criar os Casos de Testes.
    Existe alguma forma de integração entre o Selenium e o TestLink, se sim, pode me indicar alguma leitura?

    Muito Obrigado!

  • Leonardo Neuwald

    Seu Enium

    Estou iniciando no mundo dos testes, e testes automatizados.
    Onde trabalho, utilizo a ferramenta TestLink para criar os Casos de Testes.
    Existe alguma forma de integração entre o Selenium e o TestLink, se sim, pode me indicar alguma leitura?

    Muito Obrigado!

  • http://www.seuenium.com.br Enium

    Eu realmente não sei. Algum leitor do blog sabe se existe?

  • http://www.seuenium.com.br Enium

    Eu realmente não sei. Algum leitor do blog sabe se existe?

  • Thiago

    Pessoal voltei,

    Seu Enium sobre a duvida do Leonardo aqui neste link explica a possivel integração, isto depende qual é a forma de teste a ser executado ou linguagem url:http://testlink.sourceforge.net/docs/testLink.php.
    Eu resolvi não integrar por isto não pesquisei mais, mas ai no link traz uma visão da integração.
    Na empresa que eu trabalho (realizo testes de validação web, caixa preta) eu uso testlink para criar casos de testes integrado com mantis para documentar os bugs.
    Agora eu começei a criar suite de teste no eclipse com selenium rc e junit.Criei os pacotes(que é a suite) e os casos de teste que são as classes em java, com auxilio do selenium ide crio os casos de testes e transformo para java e jogo no eclipse o codigo altero necessario.
    Coloquei o screenshot do erro para funcionar tirando o print do erro, e quando tem validação tiro print do casos ok documentando os prints de casos com erro e os certos no caso o ok.
    Agora ficou facil tenho todos os prints, so documentar no testlink e passar os bugs no mantis.
    Um produto nosso vou tentar automatizar 70% isso demorava em media para validar 5 horas no teste automatico vou gastar no maximo 1 hora.
    Mas tudo depende do projeto do tempo do processo da empresa tem ser avaliado.

    Obrigado.

  • Thiago

    Pessoal voltei,

    Seu Enium sobre a duvida do Leonardo aqui neste link explica a possivel integração, isto depende qual é a forma de teste a ser executado ou linguagem url:http://testlink.sourceforge.net/docs/testLink.php.
    Eu resolvi não integrar por isto não pesquisei mais, mas ai no link traz uma visão da integração.
    Na empresa que eu trabalho (realizo testes de validação web, caixa preta) eu uso testlink para criar casos de testes integrado com mantis para documentar os bugs.
    Agora eu começei a criar suite de teste no eclipse com selenium rc e junit.Criei os pacotes(que é a suite) e os casos de teste que são as classes em java, com auxilio do selenium ide crio os casos de testes e transformo para java e jogo no eclipse o codigo altero necessario.
    Coloquei o screenshot do erro para funcionar tirando o print do erro, e quando tem validação tiro print do casos ok documentando os prints de casos com erro e os certos no caso o ok.
    Agora ficou facil tenho todos os prints, so documentar no testlink e passar os bugs no mantis.
    Um produto nosso vou tentar automatizar 70% isso demorava em media para validar 5 horas no teste automatico vou gastar no maximo 1 hora.
    Mas tudo depende do projeto do tempo do processo da empresa tem ser avaliado.

    Obrigado.

  • Nelson

    Boa tarde,

    Estou com uma dúvida no Selenium, Estou tentando verificar uma mensagem de alert utilizando assertAlert, porém ocorre o erro abaixo:

    [error] Actual value ‘O campo Nome é obrigatório. ‘ did not match ‘O campo Nome é obrigatório. ‘

    As mensagens são exatamente iguais, mas o Selenium informa que não.

    Obrigado,
    Nelson

  • Nelson

    Boa tarde,

    Estou com uma dúvida no Selenium, Estou tentando verificar uma mensagem de alert utilizando assertAlert, porém ocorre o erro abaixo:

    [error] Actual value ‘O campo Nome é obrigatório. ‘ did not match ‘O campo Nome é obrigatório. ‘

    As mensagens são exatamente iguais, mas o Selenium informa que não.

    Obrigado,
    Nelson

  • http://www.seuenium.com.br Enium

    Muito estranho esse comportamento. Alguém já passou por um problema parecido?

  • http://www.seuenium.com.br Enium

    Muito estranho esse comportamento. Alguém já passou por um problema parecido?

  • Thiago

    Nelson qual é o selenium que vc está usando?
    Pode ser algum espaço, no eclipse com junit selenium rc, da para verificar exatamente na onde está o erro.
    Acontece muito comigo de ter um espaço e selenium acusa o erro apesar da frases serem iguais.
    Ex: ‘O campo Nome é obrigatório. ‘ e ‘O campo Nome é obrigatório.’ não são iguais por causa do espaço.

  • Thiago

    Nelson qual é o selenium que vc está usando?
    Pode ser algum espaço, no eclipse com junit selenium rc, da para verificar exatamente na onde está o erro.
    Acontece muito comigo de ter um espaço e selenium acusa o erro apesar da frases serem iguais.
    Ex: ‘O campo Nome é obrigatório. ‘ e ‘O campo Nome é obrigatório.’ não são iguais por causa do espaço.

  • Nelson

    Tiago,

    Estou utilizando o Selenium IDE. Eu já tinha verificado essa questão do espaço e mesmo assim não funcionou. Valau aí pela força.

  • Nelson

    Tiago,

    Estou utilizando o Selenium IDE. Eu já tinha verificado essa questão do espaço e mesmo assim não funcionou. Valau aí pela força.

  • Thiago

    Nelson

    Se puder passar url posso tentar te ajudar.

  • Thiago

    Nelson

    Se puder passar url posso tentar te ajudar.

  • http://sembugs.blogspot.com Elias Nogueira

    O Selenium IDE vai falhar nas verificações/asserções de alertas de JavaScript.
    No Selenium RC capture o alert pelo métogo getAlert() e depois compare com um assertEquals(expected, actual) a mensagem do alert.
    Ex (Java):

    String atual = selenium.getAlert();
    String esperado = “A senha informada está incorreta!”;
    assertEquals (esperado, atual);

    O Selenium IDE pega o valor do alert com quebra de linha (n). Tente remover as quebras de linha no IDE. Deve funcionar.

  • http://sembugs.blogspot.com Elias Nogueira

    O Selenium IDE vai falhar nas verificações/asserções de alertas de JavaScript.
    No Selenium RC capture o alert pelo métogo getAlert() e depois compare com um assertEquals(expected, actual) a mensagem do alert.
    Ex (Java):

    String atual = selenium.getAlert();
    String esperado = “A senha informada está incorreta!”;
    assertEquals (esperado, atual);

    O Selenium IDE pega o valor do alert com quebra de linha (\n). Tente remover as quebras de linha no IDE. Deve funcionar.

  • Nelson

    Tiago,

    Infelizmente não posso passar. Gostaria até de levantar outro problema que está ocorrendo. Quando o Selenium está aberto, o sistema apresente o alerta com o layout diferente do default do sistema.
    Agradeço aí pela força.

  • Nelson

    Tiago,

    Infelizmente não posso passar. Gostaria até de levantar outro problema que está ocorrendo. Quando o Selenium está aberto, o sistema apresente o alerta com o layout diferente do default do sistema.
    Agradeço aí pela força.

  • Renato

    Seu Enium,

    Segui aquele post que vc ensinou a executar testes em Paralelo Testes em paralelo com Selenium Grid, Maven e TestNG.
    Gostaria de saber se existe uma forma de tirar print screen das telas de erro utilizando o TestNG ao invés do Junit, visto que já está tudo configurado para o TestNG.

    Grato.

  • Renato

    Seu Enium,

    Segui aquele post que vc ensinou a executar testes em Paralelo Testes em paralelo com Selenium Grid, Maven e TestNG.
    Gostaria de saber se existe uma forma de tirar print screen das telas de erro utilizando o TestNG ao invés do Junit, visto que já está tudo configurado para o TestNG.

    Grato.

  • http://www.seuenium.com.br Enium

    Ótima pergunta. Tão boa que decidi criar um post novo sobre isso. Você pode dar uma olhada aqui: Screenshot com Selenium – Parte 2, TestNG

  • http://www.seuenium.com.br Enium

    Ótima pergunta. Tão boa que decidi criar um post novo sobre isso. Você pode dar uma olhada aqui: Screenshot com Selenium – Parte 2, TestNG

  • http://www.seuenium.com.br/2010/04/23/screenshot-com-selenium-parte-2-testng/ Screenshot com Selenium – Parte 2, TestNG | Blog do Seu Enium

    [...] um tempo atrás escrevi um post demonstrando como dar print screen com Junit, Maven e Selenium se houvesse algum erro no teste. [...]

  • cerveja

    Pessoal estou com um problema gostaria de Ajuda.
    o sistema no qual estou trampando e de gestao de Horarios, INclui, Exclui alterar, as horas trabalhadas por dia do funcionario

    1 . Acesso o Sistema e incluo no Campo Horas = 8.0 Descrição = Teste
    2.apos incluir sistema apresenta a mensagem de Sucesso numa “Caixa” “PopUp” “Horas incluiidas com Sucesso” OK”.

    não consigo no selenium pressionar o OK dessa caixinha popUp.

    gostaria de saber como eu faço pra conseguir isso??

    muito obrigado desde de já pessoal

    estou utilizando o selenium 2.0

  • Anônimo

    Caro Seu Enium,

    Baixei e instalei o snapsie e executei seus exemplos, mas não tenho idéia de como integrá-lo com o Selenium. Você pode me dar uma dica?
    Também gostaria de saber se o snapsie é uma alternativa ao captureEntirePageScreenshot para outros navegadores como Opera e Safari para o Windows.

    Obrigado,

  • Anônimo

    Só funciona para IE. Pra te falar a verdade eu nunca usei. Nessa URL tem um exemplo de como usar, mas é sem o Selenium. http://snapsie.svn.sourceforge.net/viewvc/snapsie/trunk/test/testQuirks.html?view=markup
    Olhando esse exemplo, para integrar com o Selenium, vc teria que rodar o comando runScript com o código Javascript que chama o Snapsie, algo como:
    runscript | new Snapsie().saveSnapshot(‘c:/imagem.png’);

  • Anônimo

    Alguém sabe como fazer pra tirar printscreen no momento do erro, porém só q chamando por dentro da IDE, testando pelo JUnit?

  • Anônimo

    Pela IDE não tem como.

  • Anônimo

    Eu até consigo rodar o Selenium pelo eclipse chamando o JUnit, o problema é fazer tirar o print… =/

  • Anônimo

    Seu Enium,

    Em primeiro lugar, muito obrigado pela sua ajuda!! Eu consegui fazer o snapsIE funcionar da seguinte maneira:
    1 – Substitui o arquivo “corelibsnapsie.js” do selenium-server-1.0.3.jar (eu nem imaginava que este js já estava lá!)
    2 – Atualizei o arquivo “corescriptsselenium-api.js” do selenium-server-1.0.3.jar, conforme a referência abaixo. Basicamente troquei a linha: “new Snapsie().saveSnapshot(filename, ‘selenium_myiframe’);” por “Snapsie.saveSnapshot(filename, ‘selenium_myiframe’);” (Alerta aos navegantes: se tentarem substituir todo o código, acorre um erro associado à variável snapsieUrl)
    3 – Utilizei o próprio método captureEntirePageScreenshot, porém utilizando como browser o tipo “*iexploreproxy”. (não entendi o motivo, apenas segui a orientação)

    Referência: http://blog.codecentric.de/en/2010/02/taking-remote-screenshots-with-selenium-and-the-robot-framework/

  • Anônimo

    Desculpa, acredito q esqueci de dar uma informação importante, eu to usando o Selenium 2

blog comments powered by Disqus