Maven Selenium
From Foochal
Our goal:
- compile the app
- run non-selenium unit tests
- package your app into a .war file
- start a test container (jetty or tomcat)
- deploy your app to the test container
- start a browser
- point the browser to the app running in the test container
- test your application through the browser. these tests are junit tests and were authored using selenium IDE (and then possibly tweaked a little).
- indicate failure or success, log any errors and quit
- optionally proceed with deployment of app to a real container
Step by Step configuration
This is a step by step guide of how to setup your pom.xml to automatically run your selenium tests when you build your application with maven, with full understanding of what is going on.
For a quick start, skip to step 3, then come back to steps 1 and 2 later if needed.
|
In step 1/3, you will be able to run your selenium unit tests through maven, but you will need to keep 3 terminals open (command prompt on windows), referred to here as Terminals A, B and C.
|
[edit] Launch your app in jetty in Terminal-ASee how to configure jetty, here mvn jetty:run [edit] Start the selenium server in Terminal-BEdit your pom.xml to add selenium plugin, sample configuration here mvn selenium:start-server [edit] Run your selenium test in Terminal-CTo learn how write a selinium unit test looks like, see this sample selenium junit test mvn test |
|
In step 2/3, you will be able to run your selenium unit tests through maven, but you will only 2 terminals - Terminals A and C.
|
[edit] Configure your pom.xml to automatically start selenium-server in Terminal-C before running testsSo far, you manually started the selenium server. You we will configure the pom.xml to automatically start selenium server before running the tests. <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<executions>
<execution>
<id>start</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</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-server</goal>
</goals>
</execution>
</executions>
</plugin>
[edit] Launch your app in jetty in Terminal Amvn jetty:run [edit] Run your selenium test in Terminal CEdit your surefire-plugin to make tests unit tests run in test phase and selenium tests run in the integration-test phase. See sample pom.xml configuration here mvn integration-test The above command should start the selenium server automatically. Please note that you need to run integration-test and NOT test. |
|
In step 3/3, you will be able to run your selenium unit tests through maven and you will only 1 terminal - Terminals C.
|
[edit] Automatically start jetty server in Terminal-C before running tests<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>0.3-SNAPSHOT</version>
<configuration>
<wait>false</wait>
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
<goal>deploy</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
[edit] Run your selenium test in Terminal Cmvn integration-test The above command should start the jetty server automatically. |
How it works
FAQ
Selenium source
<dependency> <groupId>org.openqa.selenium.client-drivers</groupId> <artifactId>selenium-java-client-driver</artifactId> <version>0.9.2</version> <scope>test</scope> </dependency>
Maven-Selenium Plugin
Add this to your pluginRepositories section
<pluginRepository> <id>codehaus snapshot repository</id> <url>http://snapshots.repository.codehaus.org/</url> <releases> <enabled>true</enabled> </releases> </pluginRepository>
Add this to your build/plugins section
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>selenium-maven-plugin</artifactId> </plugin>
Maven Selenium java client driver
Add this to your respositories section
<repository> <id>openqa</id> <name>OpenQA Repository</name> <url>http://maven.openqa.org</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository>
Add this to your dependencies section
<dependency> <groupId>org.openqa.selenium.client-drivers</groupId> <artifactId>selenium-java-client-driver</artifactId> <version>0.8.1</version> <scope>test</scope> </dependency>
Simple selenium java unit test
Create a simple index.jsp with the following text
<html> <body> <h1>Hello, World</h2> </body> </html>
Here's an example junit3 test, SeleniumHelloWorldExample.java
import junit.framework.TestCase;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.SeleniumException;
public class SeleniumHelloWorldExample extends TestCase {
private DefaultSelenium selenium;
@Override
public void setUp() throws Exception {
super.setUp();
selenium = createSeleniumClient("http://localhost:8080/");
selenium.start();
}
@Override
public void tearDown() throws Exception {
selenium.stop();
super.tearDown();
}
protected DefaultSelenium createSeleniumClient(String url) throws Exception {
return new DefaultSelenium("localhost", 4444, "*firefox", url);
}
public void testHelloWorld() throws Exception {
try {
selenium.open("http://localhost:8080/mywebapp/index.jsp");
assertEquals("Hello, World", selenium.getText("//h1"));
} catch (SeleniumException ex) {
fail(ex.getMessage());
throw ex;
}
}
}
How to run selenium tests in integration test phase
Here's a surefire configuration, which
- In maven:test phase: runs unit tests
- In maven:integration-test phase: runs (selenium) integration tests
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/selenium/*Test.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/selenium/*Test.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Run integration tests
mvn integration-test
Test single class
To test your class in
src/test/java/org/foochal/MyTest
Simply type (don't give package name)
mvn -Dtest=MyTest test
Compile your test sources
mvn test-compile
Skipping unit tests in maven
mvn -Dmaven.test.skip=true package
Running Maven Selenium on linux
See this page: http://mojo.codehaus.org/selenium-maven-plugin/examples/headless-with-xvfb.html
You may have to download Xvfb from here: http://ftp.xfree86.org/pub/XFree86/4.4.0/binaries/
Error launching selenese, cannot open display
If you followed the instructions on the above page, as I did, you may end get this error.
[INFO] Starting Xvfb...
[INFO] Using display: :20
Launching Xvfb
Waiting for Xvfb...
[INFO] Redirecting output to: target/selenium/xvfb.log
Xvfb started
[INFO] [selenium:selenese {execution: start}]
[INFO] Results will go to: target/results-firefox-suite.html
(firefox-bin:18143): Gtk-WARNING **: cannot open display:
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Timed out waiting for profile to be created!
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.RuntimeException: Timed out waiting for profile to be created!
at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:271)
at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.launch(FirefoxCustomProfileLauncher.java:147)
at org.openqa.selenium.server.browserlaunchers.AbstractBrowserLauncher.launchHTMLSuite(AbstractBrowserLauncher.java:20)
at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:88)
While there are several ways to solve this, the simplest way I found was to set the DISPLAY on command line (or the build environment)
export DISPLAY=:20
This should fix the problem. Note that :20 is the default port that selenium uses. You can also specify a different port in the selenium plugin configuration and then specify the same port in the DISPLAY env variable.
Browser does not exist
If the specified browser does not exist a detailed error will be logged in this file
less /target/selenium/server.log
The error looks like this
14:42:46,991 WARN [org.mortbay.http.HttpConnection] GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*firefox&2 =http%3A%2F%2Flocalhost%3A8080%2F HTTP/1.1 java.lang.RuntimeException: Firefox couldn't be found in the path! Please add the directory containing 'firefox-bin' to your PATH environment variable, or explicitly specify a path to Firefox like this: *firefox /blah/blah/firefox-bin
Maven will throw this error
com.thoughtworks.selenium.SeleniumException: ERROR: No launcher found for sessionId null at com.thoughtworks.selenium.HttpCommandProcessor.doCommand(HttpCommandProcessor.java:73) at com.thoughtworks.selenium.HttpCommandProcessor.stop(HttpCommandProcessor.java:145)
I have an executable called 'firefox', but selenium is looking for 'firefox-bin'?
On Linux, create a symbolic link using the following command:
cd <to the directory where firefox executable is present> ln -s firefox firefox-bin
How can I run html tests (recorded using Selenium IDE) using maven
The following configuration starts the html tests located in the suite src/test/selenium/suite.html in the test phase.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<configuration>
<browser>*firefox</browser>
<suite>src/test/selenium/suite.html</suite>
<startURL>http://wiki.foochal.org</startURL>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>selenese</goal>
</goals>
</execution>
</executions>
</plugin>
The following command will run the tests:
mvn test
If you wish to the tests in a different phase, simply change the phase, for example to integration-test
Here's a sample test suite file:
<html> <head><title>Example Test Suite</title></head> <body> <table> <tr><td><b>Example Test Suite</b></td></tr> <tr><td><a href="./test1.html">Test1</a></td></tr> <tr><td><a href="./test2.html">Test2</a></td></tr> <tr><td><a href="./test3.html">Test3</a></td></tr> </table> </body> </html>

