Quantcast
Channel: Blog do Seu Enium » selenium
Viewing all articles
Browse latest Browse all 10

Evoluindo seus testes em Selenium com PageObjects

$
0
0

Já faz um tempo que queria falar sobre esse assunto mas estava esperando para o blog ter mais conteúdo e mais acesso.

Quem desenvolve testes com o Selenium já notou que a IDE é só para vender o peixe. É lindo acreditar que criar teste automatizado é só ligar o botão de gravação, sair navegando pelas páginas e salvar os arquivos para uma próxima execução. Tudo parece perfeito até o momento em que você precisa dar manutenção nos seus testes.
O padrão de PageObjects ajuda em:

  • Manutençao do código
  • Clareza no código
  • Reuso de funcionalidades
  • Organização dos testes

A ideia do padrão é criar classes para cada tela do seu sistema para que ela contenha as funcionalidades da própria e encapsule a lógica dos comandos do Selenium.

Vamos para um exemplo prático.

Criei uma página com a funcionalidade de uma busca.

Tela de busca

Vamos criar uma classe representando a tela de busca e suas funcionalidades:

package br.com.seuenium;
 
import com.thoughtworks.selenium.DefaultSelenium;
 
public class TelaBusca {
 
	private DefaultSelenium selenium;
 
	public TelaBusca(DefaultSelenium selenium) {
		this.selenium = selenium;
	}
 
	public void abrir() {
		selenium.open("/testes/8-pageobjects/buscar.php");
	}
 
	public void buscar(String termo) {
		selenium.type("name=q", termo);
		selenium.click("//input[@type='submit']");
		selenium.waitForPageToLoad("10000");
	}
 
}

O construtor da classe recebe o objeto DefaultSelenium para poder acessar os comandos da api. Os dois métodos criados representam as funcionalidades da tela: o primeiro que é abrir a própria página e o segundo que é buscar por um determinado termo. Note que a lógica do Selenium de digitar o termo no campo e em seguida clicar no botão de submit foi encapsulada pelo método buscar.

Agora vamos criar o nosso caso de teste. A ideia do teste é buscar pelo termo “Selenium” e depois validar que o termo continua presente na caixa de busca. A tela vai ficar assim:

Tela de resultado de busca

E o TestCase:

package br.com.seuenium;
 
import org.junit.*;
 
import com.thoughtworks.selenium.DefaultSelenium;
 
public class BuscaTestCase {
 
	private DefaultSelenium selenium;
 
	@Before
	public void start() {
		selenium = new DefaultSelenium("localhost", 4444, "*firefox",
				"http://www.seuenium.com.br");
		selenium.start();
	}
 
	@Test
	public void testSucesso() {
 
		TelaBusca tela = new TelaBusca(selenium);
 
		tela.abrir();
		tela.buscar("Selenium");
 
		//validacoes
		Assert.assertEquals("Selenium", tela.carregarTermoBuscado());
	}
 
	@After
	public void stop() {
		selenium.stop();
	}
}

Note que o método “testSucesso” instancia a classe TelaBusca, chama o método “abrir” e depois o “buscar”. Em seguida vêm as validações, que por enquanto é só uma. O testCase dá um asserEquals do termo “Selenium” com o método “carregarTermoBuscado” que ainda não foi implementado. Vamos implementá-lo:

package br.com.seuenium;
 
import com.thoughtworks.selenium.DefaultSelenium;
 
public class TelaBusca {
 
	private DefaultSelenium selenium;
 
	public TelaBusca(DefaultSelenium selenium) {
		this.selenium = selenium;
	}
 
	public void abrir() {
		selenium.open("/testes/8-pageobjects/buscar.php");
	}
 
	public void buscar(String termo) {
		selenium.type(localizadorDoCampoDoTermo(), termo);
		selenium.click("//input[@type='submit']");
		selenium.waitForPageToLoad("10000");
	}
 
	public String carregarTermoBuscado() {
		return selenium.getValue(localizadorDoCampoDoTermo());
	}
 
	private String localizadorDoCampoDoTermo() {
		return "name=q";
	}
 
}

Note que o método foi implementado e também houve um pequeno refactoring. Tanto o método “carregarTermoBuscado” como o “buscar” compartilhavam um mesmo locator que correspondia ao input text do termo. Foi criado o método “localizadorDoCampoDoTermo” para evitar duplicidade e facilitar a manutenção do teste. Caso o campo mude de nome no futuro, você apenas terá que alterar esse método e não ficará caçando em seus testes quem usa esse campo. A mesma ideia poderia ser aplicada ao locator do botão buscar.

Continuando com as validações, vamos conferir se a tela retornou os 2 resultados esperados.

Vamos adicionar a seguinte validação no TestCase:

List<String> resultadosEsperados = Arrays.asList(
	"Selenium IDE is a Firefox add-on that records clicks, typing, and other actions to make a test, which you can play back in the browser.",
	"Selenium is a chemical element with the atomic number 34, represented by the chemical symbol Se, an atomic mass of 78.96.");
Assert.assertEquals(resultadosEsperados, tela.carregarResultados());

E na classe da tela vamos implementar o método que retorna a lista de resultados:

public List<String> carregarResultados() {
	List<String> resultados = new ArrayList<String>();
	Integer xpathCount = selenium.getXpathCount(localizadorDosResultados()).intValue();
	for (int i = 1; i <= xpathCount; i++) {
		resultados.add(selenium.getText(localizadorDosResultados()+"["+i+"]"));
	}
	return resultados;
}

Bom gente, esse exemplo é bem simples, mas já da pra ver os ganhos em usar PageObjects.

Você pode fazer o download aqui de um projeto maven com os testes desse post.

Há outros tópicos sobre PageObjects que pretendo falar em outros posts. Para quem não sabe, vai sair uma versão nova do Selenium, a 2.0, e ela tem suporte nativo para PageObjects. Esperem o próximo post para ler mais sobre o Selenium 2.0. Aguardem!!!


Viewing all articles
Browse latest Browse all 10

Latest Images

Trending Articles