Functional Tests with Selenium 2.0 and cargo-maven-plugin
The Selenium and Webdriver projects are merged to create a powerful, open source framework for functional tests based in Javascript for testing web applications and sites. The tests can be executed in a browser like Firefox or Chrome, or can be executed by a lightweight, super-fast browser emulation based on HtmlUnit.
If you want to do some tests just download the .jars and add in your projects classpath.
In this how-to I'll use Selenium and Webdriver to execute integration tests in the maven life cycle with cargo-maven-plugin.
The cargo-maven-plugin
is used to deploy applications using maven. It installs the container
and the dependencies that are required to deploy your application and can
be configured by most containers available such as Tomcat, JBoss, Jetty(embedded) or GlashFish. The cargo-maven-plugin will start the container and deploy the application, after that it will execute the tests and stop the container.
For this example, I'll use the "Modelos de Celulares" project developed in the last post and I'll add the Selenium tests and configuration of cargo-maven-plugin.
First of all lets add the cargo-maven-plugin dependency to start the container to execute the tests in the pre-integration-test maven lifecycle. After that we stop the container in the post-integration-test maven lifecycle. The container used in this example was Tomcat 6x installed locally and defined in the <home> attribute.
It was necessary to add another plugin to execute all tests when the container started. The plugin is maven-surefire-plugin.
See the example of maven-surefire-plugin and cargo-maven-plugin configured in the pom.xml file:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0.6</version>
<configuration>
<wait>false</wait>
<!-- Container configuration -->
<container>
<type>installed</type>
<containerId>tomcat6x</containerId>
<home>${TOMCAT_HOME}</home>
</container>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Skip the normal tests,
we'll run them in the integration-test phase -->
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
The next step is add the Selenium dependency to implement the functional tests. Just add in the pom.xml file:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium</artifactId>
<version>2.0b2</version>
<scope>test</scope>
</dependency>
After that, lets create a test class. A way to acess the object browser is through four official drivers: FirefoxDriver, the most mature driver and used in this example project; Internet Explorer Driver, tested in versions IE6, IE7 on windows Vista and XP and compared with other drivers, its relatively slow. The ChromeDriver, is a newer driver and the HtmlUnit as a lightweight, super-fast browser emulation.
Lets interac with the browser with FirefoxDriver's method class call "findElement" with WebElement parameter and can be recover by by class like in this method "tentaCadastrarSemNenhumDado()" below:
public void tentaCadastrarSemNenhumDado() {
driver.get("http://localhost:8080/CadastroCelular");
driver.findElement(By.id("botaoSubmit")).click();
String mensagemErroNome = driver.findElement(By.id("mensagemErroNome")).getText();
// name required field message
Assert.assertEquals("Campo Nome Obrigatório", mensagemErroNome);
String mensagemErroDescricao = driver.findElement(By.id("mensagemErroDescricao")).getText();
// description required field message
Assert.assertEquals("Campo Descrição Obrigatório", mensagemErroDescricao);
driver.close();
}
This test tries to insert a model mobile without filling the required fields and checks the messages of required fields.
Through By class is possible recover web elements by links, name, tag html, css or link label. In this version of Selenium there is an annotation call @FindBy
which designed to clean up the code specifying the location strategy.
The method "tentaCadastrarSemNenhumDado()" example was developed
without annotation and see the same method using annotation @FindBy:
@FindBy(id = "botaoSubmit")
private WebElement botaoSubmit;
@FindBy(id = "mensagemErroNome")
private WebElement msgErroNome;
@FindBy(id = "mensagemErroDescricao")
private WebElement msgErroDescricao;
@Test
public void tentaCadastrarSemNenhumDado() {
driver.get("http://localhost:8080/CadastroCelular");
botaoSubmit.click();
// name required field message
Assert.assertEquals("Campo Nome Obrigatório", msgErroNome.getText());
// description required field message
Assert.assertEquals("Campo Descrição Obrigatório", msgErroDescricao.getText());
driver.close();
}
As
you can see the code is cleaner and simple to understand. Configuration
and implementation of functional tests are so simple that you don't
have reason not to do it.
Nice coding.
Sorry about my english. If you have any question, contact me.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Conny Kreyßel replied on Thu, 2011/03/10 - 5:23am
Valdemar Júnior replied on Sun, 2011/03/13 - 8:43am
Hi,
The example updated. Thanks Conny.
Martin Vaněk replied on Sun, 2011/03/13 - 10:02am
Valdemar Júnior replied on Sun, 2011/03/13 - 2:54pm
in response to:
Martin Vaněk
Hi,
I didn't know about maven-failsafe-plugin. I read about it and it's really better than maven-surefire-plugin.
Thanks Martin.
Kyle Liu replied on Mon, 2011/03/14 - 3:53am
The headline of the post is about functional tests , but the example show tests in the maven lifecycle phase "integration-test"
The functional tests and integeration tests are the same ?
Nigini Abilio replied on Fri, 2011/03/18 - 8:14am
Valdemar Júnior replied on Sun, 2011/03/20 - 1:23pm
in response to:
Nigini Abilio
Valdemar Júnior replied on Sun, 2011/03/20 - 9:28pm
in response to:
Kyle Liu
Instant Tax Sol... replied on Thu, 2011/08/04 - 10:46am
Kyle Thomas replied on Sun, 2011/10/09 - 11:16am