Selenium é uma ferramenta para testar aplicações web pelo browser de forma automatizada. Selenium se refere ao Acceptance Testing (ou functional testing) que involve rodar testes num sistema finalizado. Os testes rodam diretamente num browser, exatamente como o usuário faria.
Por que testar?
Temos que testar o nosso código, mas em uma aplicação web fica dificil de testar a camada de apresentação, o resultado final. Como testar os custom tags (por exemplo erro.tag ou select.tag)? Como testar a compatibilidade entre browser diferentes de forma automatizada? Em geral, como testar que a página renderizada tem o resultado desejado?
Temos que testar o nosso código, mas em uma aplicação web fica dificil de testar a camada de apresentação, o resultado final. Como testar os custom tags (por exemplo erro.tag ou select.tag)? Como testar a compatibilidade entre browser diferentes de forma automatizada? Em geral, como testar que a página renderizada tem o resultado desejado?
Para isso serve Selenium, que se preocupa basicamente com duas tarefas
- testes de funcionalidades da aplicação web
- testes de compatibilidade entre browser e plataformas diferentes
Componentes do Selenium:
Dois componentes são importante para gerar e rodar testes com Selenium:
1. Selenium RC
É
um servidor escrito em java. Ele recebe chamadas http e executa os
testes. As chamadas vem dos testes unitários (com junit, por exemplo).
Este blog tem foco nesse componente.
2. Selenium IDE
É
uma extensão do firefox. Com ela podemos criar testes. Ela funciona com
um recorder e grava as ações do usuário. As ações podem ser
transformadas em código em várias linguagens entre elas java.
Integração com JUnit
Vamos criar um teste de funcionalidade com Selenium e JUnit. Precisamos:
- uma aplicação web
- o selenium server
- o selenium test client com junit
- o selenium server
- o selenium test client com junit
Objetivo é testar um combo box numa página jsp. Vamos deixar o selenium abrir um browser, chamar a página e testar a combo box.
A página do aplicação web
Aqui tem uma página ( index.jsp) simples para testar a opção selecionada num combo box:
<html>
<head>
<title>Selenium e JUnit HowTo</title>
</head>
<title>Selenium e JUnit HowTo</title>
</head>
<body>
Size:
<select name=¿size¿>
<option id="x-large">X-Large</option>
<option id="large">Large</option>
<option id="medium selected>Medium</option>
<option id="small">Small</option>
<option id="tiny">Tiny</option>
</select>
</body>
Size:
<select name=¿size¿>
<option id="x-large">X-Large</option>
<option id="large">Large</option>
<option id="medium selected>Medium</option>
<option id="small">Small</option>
<option id="tiny">Tiny</option>
</select>
</body>
</html>
Vamos supor que esta página é acessível pela url: http://localhost:8080/test/index.jsp
O Selenium Server
O
servidor Selenium tem obviamente estar rodando antes de executar os
testes de funcionalidade. Para iniciar o server precisamos o
selenium-server.jar que está dentro do Selenium-RC download .
Executamos na linha de comando:
$java -jar selenium-server.jar
Existe um modo interativo do server para passar testes diretamente na linha de comando. Basta adicionar a opção -interactiv.
$java -jar selenium-server.jar -interactiv
O selenium client
Com
a aplicação web e o servidor selenium rodando podemos escrever o teste
com junit. Os métodos setUp e tearDown da classe de teste vão abrir e
fechar a conexão com o servidor selenium. A classe DefaultSelenium é
utilizado para a conexão. Aqui o selenium-java-client-driver.jar que vem
com o Selenium RC é necessário:
new DefaultSelenium("localhost", 4444, "*firefox /usr/lib/firefox/firefox-bin", "http://localhost:8080") |
A
porta 4444 é a padrão do Selenium, o terceiro parâmetro é o perfil do
browser junto com o caminho executável (tem que ser binario mesmo), por
último a url do servidor web. Existem perfis disponíveis para os browser
mais usados do mercado.
Aqui temos o começo código do nosso teste unitário:
| private static DefaultSelenium selenium; @BeforeClass public static void setup() { String url = "http://localhost:8080"; selenium = new DefaultSelenium("localhost", 4444, "*firefox /usr/lib/firefox/firefox-bin", url); selenium.start(); }
@AfterClass
public static void tearDown() { selenium.stop(); } |
Falta agora o método de teste que abre a página index.jsp e verifica a opção selecionada no combobox:
| @Test public void testSelectedIdOfSizeComboBox() { selenium.open("/test/index.jsp"); assertEquals(¿medium¿, selenium.getSelectedId("size")); } |
Ao
rodar o teste o Selenium abrirá o firefox e chamará a página. Existem
muitos métodos para que o Selenium preencha campos, submeta formulários,
navegue entre as páginas e muito mais. Você pode utilizar o Selenium IDE e
realizar as operações que deseja testar, e o Selenium IDE vai gerar um
código com tudo o que você fez durante aquela sessão no browser, depois
basta você adicionar as assertions desejadas, gastando pouco esforço para codificar a simulação de cliques e preenchimento de formulários.
Problemas com Firefox 2.0
Usando Firefox 2.0.1 eu tive problemas na versão atual do Selenium. Lendo o forum li que isso já foi resolvido no snapshot do selenium (que não está disponível atualmente) e será resolvido na próxima versão.
Versões usadas
- selenium-remote-control-0.9.1-SNAPSHOT
- selenium client 0.9.0
- junit 4.1
Dica (Selenium IDE)
Podem-se
encontrar em sites que usam AJAX, Portlets e DHTML alguns controles que
possuem variação dinâmica em seu identificador. Veja, por exemplo, o ID
desse controle gerado pela especificação de portlets Pluto:
id="Pluto_8A828179268FE1FD01268FE6FB8302AE__SELECTED_client_code"
Ao utilizar o Selenium IDE para gerar o script de teste automatizado, obtemos o seguinte comando em Selenese HTML:
type Pluto_8A828179268FE1FD01268FE6FB8302AE__SELECTED_client_code
O
grande problema é que esse número muda de forma constante e aleatória.
Como podemos tornar nosso teste no Selenium mais estável? Usando o
comando contains dentro do XPath !
O comando modificado fica assim:
type //select[contains(@id,"Pluto_") and contains(@id, '_SELECTED_client_code')]
Fazendo
essa pequena alteração obtemos scripts que conseguem trabalhar com
identificadores dinâmicos que mudam aleatoriamente, algo comum em
aplicações AJAX ou de portais . Uma dica fundamental para melhor uso do
Selenium IDE.

