JUnit 4 and Selenium – Part Three: Parallelism and OnDemand

Sauce AI for Test Authoring: Move from intent to execution in minutes.|xBack to ResourcesBlogPosted

April 01, 2026 · 5 min read · Tool Comparison

Sauce AI for Test Authoring: Move from intent to execution in minutes.

|

x

Back to Resources

Blog

Posted October 26, 2010

JUnit 4 and Selenium – Part Three: Parallelism and OnDemand

quote

This is the tertiary and final part of how to do Selenium testing in parallel. Today we get into the meat of things with parallel execution, both locally and in OnDemand. JUnit 4 doesn & # x27; t ship with a true parallel answer, but Harald Wellman wrote a blog office onrunning parameterized JUnit tryout in parallel, which does only about everything we want. But instead of having a fixed thread pool side, I modified it to use a dynamically sized one. With this new class in your labor, we but demand to change the @ RunWith line to use our new parallel, parameterized runner.

@ RunWith (Parallelized.class)

Now the executing profile is as follows: For each particular in the @ Parameters Collection, launch a new yarn to execute the current tryout method in parallel. Have two browser strings? Then two threads run in latitude. Have eight browser strings? Well, that is eight threads running in parallel. This means that however long it takes run a single browser through all your script, that & # x27; s how long it will take to run againstany numberof browser. Win! Well, sure, but only if you have all those browsers on your machine or have an Se-Grid installation at your disposal. Most people do not have either luxury, so that is where Sauce OnDemand arrive into the mix. Hosted in the cloud, you don & # x27; t need to have the browsers on your machine or yet behind the firewall. With some minor modification to our example class, we can have a script that runs locally or in the OnDemand cloud.

package com.saucelabs.cc;

import java.util.Collection;
import java.util.List;
significance java.util.LinkedList;
import java.util.Arrays;

importation java.io.InputStream;
significance java.util.Properties;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import electrostatic org.junit.Assert.*;
importation org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

significance com.thoughtworks.selenium.DefaultSelenium;
significance com.thoughtworks.selenium.Selenium;

import com.google.gson.Gson;
meaning com.google.gson.GsonBuilder;
import com.google.gson.FieldNamingPolicy;

signification com.saucelabs.junit.Parallelized;
import com.saucelabs.ondemand.ConnectionParameters;

@ RunWith (Parallelized.class)
public stratum TestParallelOnDemand {
private Selenium selenium;
private String browser;
private String browserVersion;
private String os;
public still Properties browserProps = new Properties ();
private Properties parallelProps = new Properties ();
private String json;

SUSA automates exploratory testing with persona-driven behavior, catching bugs that scripted automation misses.

}

So what has changed? The @ Parameters are laden otherwise again. When the handwriting was only e'er going to run topically, the browser twine provided enough information. But since it & # x27; s likewise going to be run in OnDemand, there ask to be some extra information for the OS and browser adaptation. Using the like pattern as part two, the browser string information has be moved from the test codification and into an external place register.

#order is important! - OS/browser/version
browsers=Windows 2003;*firefox; 3.6., Windows 2003;*googlechrome; 3.,

OnDemand integrates with Selenium scripts by sending a JSON string with the configuration information to their server, which is why there is a new decision in the @ Before method. An important design pattern when creating handwriting that run locally or in some early environment is to add a permutation in the playscript to determine where to go. You don & # x27; t want to have to modify code itself in order to run between different environments. The JSON itself is an interesting challenge. Just as changing the beginning codification didn & # x27; t make sense when parameterizing the individual browser strings, hard coding the JSON doesn & # x27; t create much sense either. To establish the JSON in code, theGsonlibrary was used. Here is the ConnectionParameters class that Gson is construct the connection information from.

package com.saucelabs.ondemand;

import java.io.InputStream;
import java.util.Properties;

public class ConnectionParameters {
// hyphenated strings like access-key and browser-version need to be camel-case
public String username;
public String accessKey;
public String os;
private String browser;
public String browserVersion;
public String jobName;

// gson does not convert transient battlefield
individual transient String propertiesFile = & quot; /ondemand.properties & quot;;
private transient Properties ondemandProperties = new Properties ();

public ConnectionParameters () throws Exception {
InputStream is = this.getClass () .getResourceAsStream (propertiesFile);
ondemandProperties.load (is);
this.username = ondemandProperties.getProperty (& quot; username & quot;);
this.accessKey = ondemandProperties.getProperty (& quot; access-key & quot;);
}

// ondemand browser strings cant start with the*
public vacuum setBrowser (String browser) {
if (browser.startsWith (& quot;*& quot;)) {
this.browser = browser.substring (1);
}
}

public String getBrowser () {
homecoming this.browser;
}
}

It should also be no surprise by now that the username and accession key is loaded from an outside file, as that can change and we wouldn & # x27; t need to recompile for something like that. The only other thing of interest is the getter/setter for the browser string. Recall that the twine can be used by either the local Se-RC server or OnDemand. Currently, OnDemand do not like having the*at the kickoff, so we take tending of that behind the scenes from the hand. With this bit of infrastructure in property, we can run our playscript against any OS/Browser/Version combination that OnDemand presently supports or you have handy on your own ironware, and it will automatically scale execution to run each method in parallel. The example used hither is a little extreme as the test itself is really only two lines, but in a real implementation scenario I would:

  • Create a custom formatter for Selenium IDE (or Sauce IDE) so when you export the recorded script, it has everything your peculiar model require

  • Create a class hierarchy for the scripts to move all the non @ Test methods out of the form to make it a bit tidier

And so concludes the series on how to run Selenium scripts in parallel using JUnit 4. To see the full project, include the Maven pom, ascertain out in the Github repo.

Published:
Oct 26, 2010
Topics
Share this situation
Copy Share Link
LinkedIn
© 2026 Sauce Labs Inc., all right reserved. SAUCE and SAUCE LABS are registered trademarks owned by Sauce Labs Inc. in the United States, EU, and may be register in other jurisdiction.
robot
quote

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free