Coding Dojo Floripa

Desenvolvimento Ágil

Archive for Abril, 2008

Como usar TDD e Page Objects para construir interfaces web

Posted by Ivan Sanchez em Domingo, Abril 20, 2008

Quando o assunto é interface web, a maioria dos desenvolvedores sabe o quão complicado é escrever testes automatizados, e muita gente simplesmente acaba deixando de lado esse assunto na prática, talvez por não saber o tamanho da irresponsabilidade que isto significa. Como o Vínicius da ImproveIt já bem disse:

Desenvolver software sem testes não é apenas coisa de fanfarrão. É coisa de irresponsável. É impossível uma atividade tão complexa quanto desenvolver software ser conduzida sem testes automatizados, em uma quantidade absurda. Quer dizer, possível é, mas não é aceitável.

No caso específico de interfaces web, muitos usuários do Selenium já passaram pelo extremo da empolgação, quando em 5 minutos se instala a Selenium IDE no seu Firefox e sai gravando tudo que a sua aplicação pode fazer, e acabaram no desespero total quando a coleção de testes começa a aumentar e, mesmo depois de começar a usar o Selenium RC, manter os testes fica cada vez mais difícil a cada nova mudança. E o desenvolvimento guiado por testes por onde andou durante toda esta jornada? Provavelmente restrito a testes de unidade e integração, ou seja, sem tocar na interface com o usuário.

O engraçado é que a solução para tudo isso está bem mais perto do que a gente imagina: é a velha programação orientada a objetos, representada neste caso pelo padrão Page Objects (PO). A idéia é simples:

Representar os elementos da interface com o usuário como uma série de objetos que se comunicam entre si.

Se você prestou atenção, viu que este padrão está na documentação do WebDriver, uma outra ferramenta para automatizar interação com browsers, mas que para este post não tem muita importância, desde que você consiga conectar seus Page Objects com a aplicação real. Para provar isso, aqui vai um exemplo usando selenium-rc:

public class GoogleTest {

	private Selenium selenium;

	@Before
	public void setUp() throws Exception {
		selenium = new DefaultSelenium("localhost", 4444, "*firefox",
				"http://www.google.com/webhp?hl=en");
		selenium.start();
	}

	@Test
	public void codingDojoShouldBeInFirstPageOfResults() {
		GoogleHomePage home = new GoogleHomePage(selenium);
		GoogleSearchResults searchResults = home.searchFor("coding dojo");
		String firstEntry = searchResults.getResult(0);
		assertEquals("Coding Dojo Wiki: FrontPage", firstEntry);
	}

	@After
	public void tearDown() throws Exception {
		selenium.stop();
	}

}

Este exemplo usa dois POs bastante simples (GoogleHomePage e GoogleSearchResults):

public class GoogleHomePage {

	private final Selenium selenium;

	public GoogleHomePage(Selenium selenium) {
		this.selenium = selenium;
		this.selenium.open("http://www.google.com/webhp?hl=en");
		if (!"Google".equals(selenium.getTitle())) {
			throw new IllegalStateException("This is not the Google Home Page");
		}
	}

	public GoogleSearchResults searchFor(String string) {
		selenium.type("q", string);
		selenium.click("btnG");
		selenium.waitForPageToLoad("5000");
		return new GoogleSearchResults(string, selenium);
	}
}
public class GoogleSearchResults {

	private final Selenium selenium;

	public GoogleSearchResults(String string, Selenium selenium) {
		this.selenium = selenium;
		if (!(string + " - Google Search").equals(selenium.getTitle())) {
			throw new IllegalStateException(
					"This is not the Google Results Page");
		}
	}

	public String getResult(int i) {
		String nameXPath = "xpath=id('res')/div[1]/div[" + (i + 1) + "]/h2/a";
		return selenium.getText(nameXPath);
	}
}

Quais as vantagens desta abordagem?

É possível guiar seu desenvolvimento usando testes em cima de POs.

Imagine a interação do usuário com a aplicação e crie um modelo de objetos para representar essa interação. Verifique este modelo na forma de um novo teste. Enquanto os elementos da interface não existirem o teste vai falhar, então os crie baseando-se no modelo para fazer o seu teste passar. Escreva novos testes e faça-os passarem aos poucos, e nunca inclua algo na tela que não foi descrito na forma de testes.

É muito mais fácil manter classes do que scripts.

Não demorará muito para você começar a reutilizar seus POs e poder aplicar todos os recursos de refatoração que você já conhece. Novos testes poderão ser incluídos mais facilmente e mudanças no layout afetarão apenas POs específicos.

Então, ainda existe alguma razão para não escrever testes para a interface com o usuário? Espero que não, mas se tiver, me avise!

Posted in Agile, Programming, TDD | 10 Comments »

codingdojobrasil.org

Posted by Ivan Sanchez em Sexta-feira, Abril 11, 2008

Há muito tempo eu queria colocar um Wiki para compartilhar as experiências dos coding dojos pelo país, e ultimamente a participação que tenho acompanhado nas listas de discussões me fez pensar que chegou a hora…

Está no ar o site do Coding Dojo Brasil:

http://codingdojobrasil.org

Posted in Geral | Leave a Comment »

Novo blog do Dojo SP

Posted by Ivan Sanchez em Sexta-feira, Abril 11, 2008

Atualizando o blogroll, aqui vai o link pro blog do Dojo SP: http://www.dojosp.epistemol.net/

Se você estiver interessado em participar das reuniões da terra da garoa, se inscreva no grupo de discussão.

Hoje em dia esse é o coding dojo mais ativo do Brasil, o que significa que além das reuniões também rolam umas discussões bastante interessantes na sua lista.

Fica a dica 😉

Posted in Blogging, Blogroll, Dojo | Leave a Comment »