Skip to end of metadata
Go to start of metadata

Sauce Labs is a cloud platform for executing automated and manual mobile and web tests. Sauce Labs supports running automated tests with Selenium WebDriver (for web applications) and Appium (for native and mobile web applications). This topic will provide you with an example of how to set up your Java tests to run on Sauce.

Example Only

The code in this topic is presented as an example only, since your tests and testing environments may require specialized scripting. This information should be taken only as an illustration of how you could set up your tests with Sauce Labs, and is not directly supported by Sauce.

Prerequisites

Before getting started, you should review the Best Practices for Running Tests.

You need to have these components installed to set up testing on Sauce with Java. 

  • You must have JDK 1.6  or higher installed
  • You need to have the selenium-java client for your operating system installed. You can download it from http://www.seleniumhq.org/download/, under the section Selenium Client & WebDriver Language Bindings.
  • You should install the Java Helper Library, which will automatically update your Sauce Labs dashboard with information like whether tests have passed or failed, output the Sauce Session ID to stdout for parsing by the Sauce Jenkins and Bamboo plugins, and which provides a com.saucelabs.common.SauceOnDemandAuthentication class, which handles obtaining the Sauce OnDemand user name and access key from environment variables or the filesystem.

  • If you want to run Java tests in parallel with a test framework like TestNG or JUnit, you'll need to install a project management and comprehension tool like Maven or Ant. This tutorial includes set up instructions for both frameworks in Maven and Ant to provide you with a comprehensive example of how to configure your tool chain to run Java tests on Sauce. 

Install the Selenium Client in the Same Directory as the Test

You will have to install the selenium-java client in the same directory where your keep your sample test.

Code Example

This code example illustrates setting up a simple Java test to find the title of a page hosted by Sauce Labs. 

You can clone this script directly from our GitHub repo

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.net.URL;

public class SampleSauceTest {

  public static final String USERNAME = "YOUR_USERNAME";
  public static final String ACCESS_KEY = "YOUR_ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + ACCESS_KEY + "@ondemand.saucelabs.com:443/wd/hub";

  public static void main(String[] args) throws Exception {

    DesiredCapabilities caps = DesiredCapabilities.chrome();
    caps.setCapability("platform", "Windows 10");
    caps.setCapability("version", "latest");

    WebDriver driver = new RemoteWebDriver(new URL(URL), caps);

    /**
     * Goes to Sauce Lab's guinea-pig page and prints title
     */

    driver.get("https://saucelabs.com/test/guinea-pig");
    System.out.println("title of page is: " + driver.getTitle());

    driver.quit();
  }
}


Compiling and Running the Test

Use the javac and java commands to compile and run your sample Java test.

The javac command is used to compile the Java test class and create a .class file. For instance, the SampleSauceTest.java test references all of the dependent .jar files as shown in this code sample.

Mac OS X or Linux javac Command to Compile a Java Class File
javac -cp ".:./selenium-2.46.0/selenium-java-2.46.0.jar:./selenium-2.46.0/libs/*" SampleSauceTest.java
Windows javac Command to Compile a Java Class File
javac -cp ".;./selenium-2.46.0/selenium-java-2.46.0.jar;./selenium-2.46.0/libs/*" -encoding UTF-8 SampleSauceTest.java

The java command is used to run the compiled .class file.

Mac OS X or Linux java Command to Run a Java Class File
java -cp ".:./selenium-2.46.0/selenium-java-2.46.0.jar:./selenium-2.46.0/libs/*" SampleSauceTest 
Windows java Command to Run a Java Class File
javac -cp ".;./selenium-2.46.0/selenium-java-2.46.0.jar;./selenium-2.46.0/libs/*" -encoding UTF-8 SampleSauceTest.java

Analyzing the Code

To run Selenium locally, you might initiate a driver instance for the browser that you want to test on as shown here:

WebDriver driver = new FirefoxDriver() 

 

To run on Sauce, you need to use the general RemoteWebDriver instance instead of the browser-specific FirefoxDriver instance. You must then pass two parameters: a URL that points to your test to Sauce Labs, and the DesiredCapabilities of your test. 

RemoteWebDriver

RemoteWebDriver is a standard Selenium interface that lets you perform all the same tests that you could with a local Selenium test. The only difference is the URL that causes the test to run using a browser on the Sauce Labs server.

 

Create the Authentication Instance

The first thing you need to send to RemoteWebdriver is a URL that authorizes your tests to be run on a browser in the Sauce Labs cloud. The URL, which includes with your Sauce Labs credentials, is built from the cocantenation of the string definitions in the first section of the example code, under Authentication Instance

Set the Desired Capabilities

The second argument that RemoteWebdriver takes is caps, which sets the DesiredCapabilities of your test. If you were running your test on a local Selenium instance, you would specify the browser to test against with something like FirefoxDriver(), but when you use RemoteWebDriver, you must explicitly set the platform, browser, operating system, and other test parameters as shown in the example code. 

Because you are not specifying FirefoxDriver() as you were in your local test, you must use DesiredCapabilities to specify what browser/OS combination(s) to spin up and execute against. DesiredCapabilities is a set of parameters and values that are sent to the Selenium server running in the Sauce Labs cloud. The parameters and values tell the Selenium server the specifications of the automated test that you plan to run. You can use the Platforms Configurator to easily determine the correct DesiredCapabilities for your test.

Setting Authentication and Desired Capabilities in Java
public class SampleSauceTest {

/**
* Creates an authentication instance using the supplied user name/access key.
*/

  public static final String USERNAME = "YOUR_USERNAME";
  public static final String ACCESS_KEY = "YOUR_ACCESS_KEY";
  public static final String URL = "http://" + USERNAME + ":" + ACCESS_KEY + "@ondemand.saucelabs.com:80/wd/hub";

/**
* Represents the browser type, version, and operating system to be used as part * of the test run.
*/

  public static void main(String[] args) throws Exception {

    DesiredCapabilities caps = DesiredCapabilities.internetExplorer();
    caps.setCapability("platform", "Windows 7");
    caps.setCapability("version", "11.0");
    caps.setCapability("name", "Sauce Sample Test");

    WebDriver driver = new RemoteWebDriver(new URL(URL), caps);
    ...

  }
} 

Running Tests Against Local Applications

Developing websites/apps within your local network is secure and efficient. The drawback to this method is that local assets are not publicly-accessible on the Internet, so the browsers/devices in the Sauce Labs cloud can't load and test your app. The solution is to use Sauce ConnectSauce Connect is a proxy server that creates a secure tunnel connection between the Sauce Labs virtual machine that runs your test and your local  network. You can also use Sauce Connect to test applications and websites that are located within your corporate firewall. Sauce Connect is not required to run tests on Sauce Labs, only in situations where the application or website you want to test is not publicly accessible. 

Running Tests in Parallel

Now that you’re running tests on Sauce, you may wonder how you can run your tests faster. One way to increase speed is by running tests in parallel across multiple virtual machines.

You can run your tests in parallel at two levels, and you can run your tests in parallel across multiple browsers. For example, if you have 10 tests and want to run on five browsers, this would be parallelism of five. You can also run tests across browsers and each test in parallel. Using our previous example this would be more like 50 parallel tests. Doing this requires that your tests are written in a way that they do not collide with one another, as described in our Best Practice topics avoiding external test dependencies and avoiding dependencies between tests.

Match Thread Count to Concurrency Limit

You should match your thread count to your concurrency limit, which is shown in the My Account section of your user profile information on the Sauce Labs dashboard.  

For more information, check out the example scripts in our GitHub repo

Most Java users use one of two popular third party testing frameworks: TestNG or Junit. These links are for two example projects written in each. They are designed to run in parallel. You can clone them and add your own test cases if you want:
  1. https://github.com/saucelabs-sample-test-frameworks/Java-Junit-Selenium
  2. https://github.com/saucelabs-sample-test-frameworks/Java-TestNG-Selenium

Running Tests in Parallel and Across Multiple Browsers

Tests can be run in parallel at two levels: you can run your tests in parallel,and you can run your tests in parallel across multiple browsers. For example, if you have 10 tests and run them serially on five browsers, this would be parallelism of five. You can also run tests across browsers and each test in parallel. Using our previous example, this would be 50 parallel tests (10 tests, five browsers). This requires that your tests are written in a way that they do not collide with one another. For more on this see Selenium WebDriver - Running Your Tests in Parallel blog.

Maven, Pom and Dependencies

The first thing you need to do, regardless of which framework you use, is to install a project management tool like Maven or Ant. For example purposes, this topic describes setting up Maven.

  1. Install Maven.
  2. Update the dependency list in the Maven POM (Project Object Model) file pom.xml with the dependencies for Selenium, your test framework (either JUnit or TestNG), and the Java Helper Library, as shown in these code examples. 

    pom.xml Dependencies

     The dependency list is the most important feature of a POM. Almost every project depends upon other pieces to build and run the project correctly. The dependency list is used to download and link the compiled dependencies.


Selenium Dependency

This tells your project which version of Selenium to use.

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.45.0</version>
    <scope>test</scope>
</dependency> 

 

Framework Dependency

This specifies whether your are using Junit or TestNG as your testing framework. 

JUnit
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency> 
TestNG
<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.1.1</version>
    <scope>test</scope>
</dependency> 

Java Helper Library Dependency

The Java Helper Library reports the results of your tests to your Sauce Labs dashboard, and has other useful features for handling authentication to Sauce Labs and using the Sauce OnDemand plugins for Bamboo and Jenkins CI platforms. 

JUnit
<dependency>
    <groupId>com.saucelabs</groupId>
    <artifactId>sauce_junit</artifactId>
    <version>2.1.18</version>
    <scope>test</scope>
</dependency> 
TestNG
<dependency>
    <groupId>com.saucelabs</groupId>
    <artifactId>sauce_testng</artifactId>
    <version>2.1.18</version>
    <scope>test</scope>
</dependency> 

Parallelizing JUnit

The Java helper library includes a Parallelized class that creates a dynamic thread pool that holds each thread that is running a test.

Parallelizing the WebDriverTest Class

In this example, we're parallelizing tests across different browsers on different platforms. Since testing an app in Firefox on Linux is independent of testing it in Chrome on Windows, we can safely run both tests in parallel. The static method browsersStrings() is annotated with com.saucelabs.junit.ConcurrentParameterized.Parameters, indicating it should be used to determine the parameters for each instance of the test. The method returns a LinkedList of parameters to use for each test instance's constructor. The SampleSauceTest constructor captures these parameters and setUp() uses them to configure the DesiredCapabilities.

Example of Java Test Parallelization
 @RunWith(ConcurrentParameterized.class)
public class SampleSauceTest implements SauceOnDemandSessionIdProvider {

    /**
     * Constructs a {@link SauceOnDemandAuthentication} instance using the supplied user name/access key.  To use the authentication
     * supplied by environment variables or from an external file, use the no-arg {@link SauceOnDemandAuthentication} constructor.
     */
    public SauceOnDemandAuthentication authentication = new SauceOnDemandAuthentication("${userName}", "${accessKey}");

    /**
     * JUnit Rule which will mark the Sauce Job as passed/failed when the test succeeds or fails.
     */
    @Rule
    public SauceOnDemandTestWatcher resultReportingTestWatcher = new SauceOnDemandTestWatcher(this, authentication);

    /**
     * Represents the browser to be used as part of the test run.
     */
    private String browser;
    /**
     * Represents the operating system to be used as part of the test run.
     */
    private String os;
    /**
     * Represents the version of the browser to be used as part of the test run.
     */
    private String version;
    /**
     * Instance variable which contains the Sauce Job Id.
     */
    private String sessionId;

    /**
     * The {@link WebDriver} instance which is used to perform browser interactions with.
     */
    private WebDriver driver;

    /**
     * Constructs a new instance of the test.  The constructor requires three string parameters, which represent the operating
     * system, version and browser to be used when launching a Sauce VM.  The order of the parameters should be the same
     * as that of the elements within the {@link #browsersStrings()} method.
     * @param os
     * @param version
     * @param browser
     */
    public SampleSauceTest(String os, String version, String browser) {
        super();
        this.os = os;
        this.version = version;
        this.browser = browser;
    }

    /**
     * @return a LinkedList containing String arrays representing the browser combinations the test should be run against. The values
     * in the String array are used as part of the invocation of the test constructor
     */
    @ConcurrentParameterized.Parameters
    public static LinkedList browsersStrings() {
        LinkedList browsers = new LinkedList();
        browsers.add(new String[]{"Windows 8.1", "11", "internet explorer"});
        browsers.add(new String[]{"OSX 10.8", "6", "safari"});
        return browsers;
    }


    /**
     * Constructs a new {@link RemoteWebDriver} instance which is configured to use the capabilities defined by the {@link #browser},
     * {@link #version} and {@link #os} instance variables, and which is configured to run against ondemand.saucelabs.com, using
     * the username and access key populated by the {@link #authentication} instance.
     *
     * @throws Exception if an error occurs during the creation of the {@link RemoteWebDriver} instance.
     */
    @Before
    public void setUp() throws Exception {

        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(CapabilityType.BROWSER_NAME, browser);
        if (version != null) {
            capabilities.setCapability(CapabilityType.VERSION, version);
        }
        capabilities.setCapability(CapabilityType.PLATFORM, os);
        capabilities.setCapability("name", "Sauce Sample Test");
        this.driver = new RemoteWebDriver(
                new URL("http://" + authentication.getUsername() + ":" + authentication.getAccessKey() + "@ondemand.saucelabs.com:80/wd/hub"),
                capabilities);
        this.sessionId = (((RemoteWebDriver) driver).getSessionId()).toString();

    }

    /**
     * Runs a simple test verifying the title of the amazon.com homepage.
     * @throws Exception
     */
    @Test
    public void amazon() throws Exception {
        driver.get("http://www.amazon.com/");
        assertEquals("Amazon.com: Online Shopping for Electronics, Apparel, Computers, Books, DVDs & more", driver.getTitle());
    }

    /**
     * Closes the {@link WebDriver} session.
     *
     * @throws Exception
     */
    @After
    public void tearDown() throws Exception {
        driver.quit();
    }

    /**
     *
     * @return the value of the Sauce Job id.
     */
    @Override
    public String getSessionId() {
        return sessionId;
    }
}

Setting a Parallelism Limit

To stop tests from timing out when you're already using all your Sauce Labs parallel slots, you need to limit the number of threads.

The Sauce Labs Parallelized JUnit runner uses the junit.parallel.threads System property to control how many threads it runs. You can set this by updating the <threadcount> in your Maven pom.xml file, as shown in the example. Similarly, if you were using Ant as your project comprehension tool, you would update the <threadCount> attribute in your Parallel task. 

Match Thread Count to Concurrency Limit

You should match your thread count to your concurrency limit, which is shown in the My Account section of your user profile information on the Sauce Labs dashboard.  

Example of Updating the Threadcount in a Maven pom.xml file
<build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12.4</version>
                <configuration>
                    <parallel>classes</parallel>
                    <threadCount>20</threadCount>
                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
                </configuration>
            </plugin>
        </plugins>
</build>

Parallelizing TestNG

TestNG has built-in support for running tests in parallel. All you need to do is set a parallelism limit in your Maven pom.xml file or your Ant Parallel task file by updating the <threadcount>.

Match Thread Count to Concurrency Limit

You should match your thread count to your concurrency limit, which is shown in the My Account section of your user profile information on the Sauce Labs dashboard.  

Example of Updating the <threadCount> in a Maven pom.xml file
<build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12.4</version>
                <configuration>
                    <parallel>classes</parallel>
                    <threadCount>20</threadCount>
                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
                </configuration>
            </plugin>
        </plugins>
</build>

Reporting Test Results to the Sauce Labs Dashboard

The Java Helper Library will automatically send test names and pass/fail results to your Sauce Labs dashboard if you are using TestNG or JUnit as your framework.

If using other frameworks, then use the SauceRest Java Library to update the pass or fail status of the test.

You should also check out the topic Best Practice: Use Build IDs, Tags, and Names to Identify Your Tests for more suggestions on how to improve test reporting and using build numbers for your continuous integration platform.