Include integration tests in maven build with TestNG

To execute integration tests you can use testNG an other test framwork bases on junit framework.

Test Suite
Just create a simple testNG suite defined in a XML format:

<suite name="LoginTestSuite">
  <test name="loginTest1-1">
     <parameter name="username" value="jcooper"/>
     <parameter name="password" value="welcome1"/>
     <parameter name="validTest" value="true"/>
     <classes>
     <class name="com.iteye.exchange.account.AllLoginTestsIT "/>
    </classes>
  </test>

  <test name="loginTest1-2">
     <parameter name="username" value="scot"/>
     <parameter name="password" value="dontknow"/>
     <parameter name="validTest" value="false"/>
     <classes>
     <class name="com.iteye.exchange.account.AllLoginTestsIT "/>
    </classes>
  </test>

  <test name="loginTest1-3">
     <parameter name="username" value="unknown"/>
     <parameter name="password" value="hack"/>
     <parameter name="validTest" value="false"/>
     <classes>
     <class name="com.iteye.exchange.account.AllLoginTestsIT "/>
    </classes>
  </test>
</suite>

Annotations
It calls the following Selenium test case where i have created a simple login script that logins with the supplied username and password (annotated with testng annotations ). It validates the tests if a valid or invalid repose is available in the HTML page.

Used annotations:

  1. @BeforeClass you specify the setup method. In this case a connection to a running selenium server.
  2. @Test to specify a tests method. In this case the execution of the login script
  3. @Parameters to specify a tests method parameters. In this case the username, password and if it’s a valid test
  4. @AfterClass to specify the post test method. In this case the closure of the selenium server

Selenium Test case
The Selenium test case:

package com.iteye.exchange.account;

import com.thoughtworks.selenium.*;
import org.testng.annotations.*;

public class AllLoginTestsIT extends SeleneseTestCase {
	private DefaultSelenium selenium;

	@BeforeClass
	public void setup() {
		selenium = new DefaultSelenium("localhost", 4444, "*iexplore",
				"http://localhost:8080/");
		selenium.start();
	}

	@Test
	@Parameters( { "username", "password", "validTest" })
	public void testLogin(String username, String password, Boolean validTest)
			throws Exception {
		selenium.open("/");
		selenium.type("username", username);
		selenium.type("password", password);
		selenium.click("//input[@value='Login']");
		selenium.waitForPageToLoad("30000");

		if (validTest) {
			verifyEquals(selenium.getText("//div[@id='nav']/div/span"),
					username);
			selenium.click("link=Logout");
			selenium.waitForPageToLoad("30000");

		} else {
			verifyEquals(selenium
					.getText("//form[@id='id1']/div[2]/ul/li/span"),
					"Unknown username / password");
		}
	}

	@AfterClass
	public void tearDown() {
		selenium.stop();
	}
}

Maven build file

In the maven buildfile you need to include testng as dependency for the project (only needed in the test phase). I start and stop Jetty and Selenium in the pre-integration-test and post-integration-test phase so they are up and rud running when i execute the integration tests using the maven-failsafe plugin.

Don’t forget to include maven-failsafe to the verify phase to let the build fail if there is an error in a integration test.
To let Jetty run as a demon process just give the daemon element a true value

..
<dependencies>
  <dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>5.12.1</version>
    <scope>test</scope>
  </dependency>
  <dependencies>
  ...
    <plugin>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>jetty-maven-plugin</artifactId>
      <version>7.0.1.v20091125</version>
      <executions>
        <execution>
          <id>start-jetty</id>
          <phase>pre-integration-test</phase>
          <goals>
            <goal>run</goal>
          </goals>
          <configuration>
            <daemon>true</daemon>
            <scanIntervalSeconds>2</scanIntervalSeconds>
            <stopPort>9966</stopPort>
            <stopKey>foo</stopKey>
            <webdefaultxml>src/main/resources/webdefault.xml</webdefaultxml>
          </configuration>
        </execution>
        <execution>
          <id>stop-jetty</id>
          <phase>post-integration-test</phase>
          <goals>
            <goal>stop</goal>
          </goals>
          <configuration>
            <scanIntervalSeconds>2</scanIntervalSeconds>
            <daemon>true</daemon>
            <stopKey>HALT</stopKey>
            <stopPort>9100</stopPort>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-failsafe-plugin</artifactId>
      <version>2.5</version>
      <configuration>
        <suiteXmlFiles>
          <suiteXmlFile>testng.xml</suiteXmlFile>
        </suiteXmlFiles>
        <includes>
          <include>**/*IT.java</include>
        </includes>
      </configuration>
      <executions>
        <execution>
          <id>integration-test</id>
          <phase>integration-test</phase>
          <goals>
            <goal>integration-test</goal>
          </goals>
        </execution>
        <execution>
          <id>verify</id>
          <phase>verify</phase>
          <goals>
            <goal>verify</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>selenium-maven-plugin</artifactId>
      <version>1.0</version>
      <executions>
        <execution>
          <id>start-sel</id>
          <phase>pre-integration-test</phase>
          <goals>
            <goal>start-server</goal>
          </goals>
          <configuration>
            <background>true</background>
            <logOutput>true</logOutput>
            <multiWindow>true</multiWindow>
          </configuration>
        </execution>
        <execution>
          <id>stop-sel</id>
          <phase>post-integration-test</phase>
          <goals>
            <goal>stop-server</goal>
          </goals>
        </execution>
      </executions>
    </plugin>

in this example the tests a straight forward and i didn’t use yet the added function that testNG has to offer. That is that you can specify test groups. To get a good explanation and example i refer to Maven Handbook Chapter 7.4
Resources

Popularity: 10% [?]

Share this Post:
Digg Google Bookmarks reddit Mixx StumbleUpon Technorati Yahoo! Buzz DesignFloat Delicious BlinkList Furl

No Responses to “Include integration tests in maven build with TestNG”

Leave a Reply:

Name (required):
Mail (will not be published) (required):
Website:
Comment (required):
XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>