You are testing a web application and you need to start a servlet container prior to running integration tests.
Use the Maven Jetty Plugin to start an instance of a server prior to running your integration tests. Assume that you are writing integration tests to test the sample web application project that was introduced in Section 6.1, “Running a Web Application in a Servlet Container”. If you have some Selenium tests for the web application, you can start an instance of Jetty running the web application as a daemon in the pre-integration-test phase and stop the instance in the post-integration-test phase.
Your web application is in the org.sonatype.mcookbook:sample-web project and your integration tests are in the org.sonatype-mcookbook:sample-web-it project. You can configure the Maven Dependency plugin to copy the WAR to the sample-web-it project during the package phase, then during the pre-integation-test phase you will configure the Maven Jetty plugin to start an instance of Jetty to run the sample-web.war as well as to start the Selenium server. The Maven Surefire plugin will then execute the unit tests, and after the tests are complete the Jetty server will be stopped in the post-integration-test phase.
Our TestNG integration tests is as follows. It is going to connect
to the default Jetty host and port of localhost:8080, and submit a form
that calculates the tenth number in the Fibonacci sequence
(F10). This integration test is stored in
${basedir}/src/test/java.
package org.sonatype.mcookbook;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import com.thoughtworks.selenium.SeleniumException;
public class FibTest {
private Selenium selenium;
@BeforeClass
public void startSelenium() {
this.selenium = new DefaultSelenium("localhost", 4444, "*safari",
"http://localhost:8080");
this.selenium.start();
}
@Test public void testSequence() throws Exception {
selenium.open("/sample-web/");
selenium.type("index", "10");
selenium.click("//input[@value='Calculate']");
selenium.waitForPageToLoad("30000");
assert selenium.isTextPresent("55");
}
@AfterClass(alwaysRun = true)
public void stopSelenium() {
this.selenium.stop();
}
}
The POM to configure the sample-web-it is shown below.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mcookbook</groupId>
<artifactId>sample-web-it</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sample-web-it</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.sonatype.mcookbook</groupId>
<artifactId>sample-web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
<overWrite>true</overWrite>
<destFileName>sample-web.war</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>
${project.build.directory}/war
</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
<configuration>
<background>true</background>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.22</version>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-war</goal>
</goals>
<configuration>
<contextPath>sample-web</contextPath>
<daemon>true</daemon>
<webApp>
${project.build.directory}/war/sample-web.war
</webApp>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<stopPort>9991</stopPort>
<stopKey>test</stopKey>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.10</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium.client-drivers</groupId>
<artifactId>selenium-java-client-driver</artifactId>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.sonatype.mcookbook</groupId>
<artifactId>sample-web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
</project>
This POM contains the following configuration:
When you run the integration-test phase of this build, you will see that Maven runs through the lifecycle and starts Selenium and Jetty before running the integration tests.
$ mvn clean install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building sample-web-it
[INFO] task-segment: [clean, integration-test]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
...
[INFO] [resources:resources {execution: default-resources}]
...
[INFO] [resources:testResources {execution: default-testResources}]
...
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Compiling 1 source file to
~/Code/sonatype/maven-cookbook/mcookbook-examples/integrate/sample-web-it/
target/test-classes
[INFO] [surefire:test {execution: default-test}]
[INFO] Tests are skipped.
[INFO] [jar:jar {execution: default-jar}]
...
[INFO] [dependency:copy {execution: copy}]
...
[INFO] [selenium:start-server {execution: default}]
Created dir: ~/maven-cookbook/mcookbook-examples/integrate/sample-web-it/
target/selenium
Launching Selenium Server
Waiting for Selenium Server...
...
[INFO] [dependency:copy {execution: copy}]
[INFO] Configured Artifact: org.sonatype.mcookbook:sample-web:1.0-SNAPSHOT:war
[INFO] Copying sample-web-1.0-SNAPSHOT.war to
~/maven-cookbook/mcookbook-examples/integrate/sample-web-it/
target/war/sample-web.war
[INFO] [jetty:run-war {execution: start-jetty}]
[INFO] Configuring Jetty for project: sample-web-it
2009-11-29 04:21:37.994:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
[INFO] Context path = /sample-web
[INFO] Starting jetty 6.1.22 ...
2009-11-29 04:21:38.683:INFO::Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
[INFO] [surefire:test {execution: default}]
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
04:21:39,436 INFO [org.mortbay.util.Credential] Checking Resource aliases
...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.597 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] [jetty:stop {execution: stop-jetty}]
[INFO] Stopping server 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13 seconds
[INFO] Finished at: Sun Nov 29 04:21:42 CST 2009
[INFO] Final Memory: 48M/99M
[INFO] ------------------------------------------------------------------------
2009-11-29 04:21:43.201:INFO::Shutdown hook executing
2009-11-29 04:21:43.822:INFO::Shutdown hook complete