Tutorial: Selenium continuous integration test

The project for this tutorial can be found at:

https://github.com/ericynt/blog-repo (development branch)

See the read me in the submodule for info. about how to run the project.

What does this project do?

  • clone the web application project that is going to be tested from a git repo.
  • download and unzip a version of Firefox that is compatible with the Selenium version that is used
  • build the project using a maven command
  • run the war that has been built in embedded Tomcat
  • run the Selenium test using the Firefox webdriver against the local Tomcat instance
  • close the browser and Tomcat

What are some of the advantages of setting up the test in this way?

It is very flexible. You don’t even need a repository manager. You can clone different branches. You can easily add more webdrivers and browser versions.

package com.eric;

import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

import java.io.File;

/**
 *
 */
public class FirefoxWebDriverFactory {
    static FirefoxDriver createFirefoxDriver () {
        String path = "\\target\\FirefoxPortable32\\FirefoxPortable.exe";
        String userDir = System.getProperty("user.dir");
        File file = new File(userDir + path);
        FirefoxBinary firefoxBinary = new FirefoxBinary(file);

        return new FirefoxDriver(firefoxBinary, new FirefoxProfile());
    }
}

package com.eric;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebDriver;

/**
 *
 */
public class MyITCase {
   private WebDriver webDriver = FirefoxWebDriverFactory.createFirefoxDriver();

    @Test
    public void myTest () {
        webDriver.navigate().to("http://localhost:8080/webapp");
        Assert.assertEquals("Hello World!", webDriver.getTitle());
        webDriver.close();
    }
}

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.eric</groupId>
        <artifactId>blog-projects</artifactId>
        <version>1.0.0</version>
    </parent>

    <artifactId>selenium-ci-tut</artifactId>
    <version>1.0.0</version>
    <packaging>war</packaging>

    <name>selenium-ci-tutorial</name>

    <scm>
        <connection>scm:git:https://github.com/efsavage/hello-world-war.git</connection>
        <developerConnection>scm:git:https://github.com/efsavage/hello-world-war.git</developerConnection>
    </scm>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-firefox-driver</artifactId>
            <version>2.53.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>webapp</directory>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-scm-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>git_clone</id>
                        <goals>
                            <goal>checkout</goal>
                        </goals>
                        <phase>initialize</phase>
                        <configuration>
                            <scmVersion>master</scmVersion>
                            <scmVersionType>branch</scmVersionType>
                            <checkoutDirectory>${project.basedir}/webapp</checkoutDirectory>
                            <workingDirectory>${project.basedir}/</workingDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.3.2</version>
                <executions>
                    <execution>
                        <id>build_webapp_war</id>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <phase>generate-resources</phase>
                        <configuration>
                            <executable>mvn</executable>
                            <arguments>
                                <argument>clean</argument>
                                <argument>install</argument>
                                <argument>-f</argument>
								<argument>webapp/pom.xml</argument>
                            </arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>com.googlecode.maven-download-plugin</groupId>
                <artifactId>download-maven-plugin</artifactId>
                <version>1.3.0</version>
                <executions>
                    <execution>
                        <id>install_firefox</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>wget</goal>
                        </goals>
                        <configuration>
                            <url>http://www.firefox-usb.com/download/FirefoxPortable32-45.0.2.zip</url>
                            <unpack>true</unpack>
                            <outputDirectory>${basedir}/target</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <executions>
                    <execution>
                        <id>run-tomcat</id>
                        <goals>
                            <goal>run-war-only</goal>
                        </goals>
                        <phase>pre-integration-test</phase>
                        <configuration>
                            <port>8080</port>
                            <path>/webapp</path>
                            <fork>true</fork>
                            <warDirectory>${basedir}/webapp/target/hello-world-war-1.0.0</warDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <executions>
                    <execution>
                        <id>run-it-tests</id>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Some final notes

  • the maven-failsafe-plugin picks up any Java test file that ends with ITCase or IT or starts with IT by default: http://maven.apache.org/surefire/maven-failsafe-plugin/examples/inclusion-exclusion.html
  • Selenium is very specific about which browser version is supported by which version of Selenium and which webdriver version: http://www.seleniumhq.org/about/platforms.jsp
  • I wouldn’t use PhantomJS for testing. Only maybe to automate something very trivial and it must run headless.
  • If you are using IntelliJ IDEA you can add the cloned project dir. to ‘excluded’ in Project Structure so it doesn’t get indexed every time you run the test
  • the tomcat7-maven-plugin requires that the packaging is war
  • as far as I can tell the download-maven-plugin is platform independent
Advertisements