Platinum Partner
java,jboss,maven,tomcat,selenium,webdriver,cargo-maven-plugin

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.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}