---
title: Run parallel Selenium tests with Java and JUnit
description: Cross browser parallel testing with Java and JUnit. Run multiple tests
  concurrently.
source_url:
  html: https://testingbot.com/support/web-automate/selenium/java/parallel-junit
  md: https://testingbot.com/support/web-automate/selenium/java/parallel-junit/index.md
---
# Speed up JUnit tests by running them in parallel

By running multiple JUnit tests at the same time you can cut down on overall test time.

## Helper class needed to run JUnit tests in parallel

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    import org.junit.runners.Parameterized;
    import org.junit.runners.model.RunnerScheduler;
    
    public class Parallelized extends Parameterized {
    
        private static class ThreadPoolScheduler implements RunnerScheduler {
            private ExecutorService executor;
    
            public ThreadPoolScheduler() {
                String threads = System.getProperty("junit.parallel.threads", "16");
                int numThreads = Integer.parseInt(threads);
                executor = Executors.newFixedThreadPool(numThreads);
            }
    
            @Override
            public void finished() {
                executor.shutdown();
                try {
                    executor.awaitTermination(10, TimeUnit.MINUTES);
                } catch (InterruptedException exc) {
                    throw new RuntimeException(exc);
                }
            }
    
            @Override
            public void schedule(Runnable childStatement) {
                executor.submit(childStatement);
            }
        }
    
        public Parallelized(Class<?> klass) throws Throwable {
            super(klass);
            setScheduler(new ThreadPoolScheduler());
        }
    }

Below is a JUnit Test example, which uses the above helper class to run the test in parallel.

    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.Map;
    
    import org.apache.commons.io.FileUtils;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    import org.openqa.selenium.MutableCapabilities;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.TakesScreenshot;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.remote.RemoteWebDriver;
    
    @RunWith(Parallelized.class)
    public class JUnitParallel {
        private String platform;
        private String browserName;
        private String browserVersion;
    
        @Parameterized.Parameters
        public static LinkedList<String[]> getEnvironments() throws Exception {
            LinkedList<String[]> env = new LinkedList<>();
            env.add(new String[]{"WIN11", "chrome", "latest"});
            env.add(new String[]{"WIN11", "firefox", "latest"});
            env.add(new String[]{"WIN11", "MicrosoftEdge", "latest"});
    
            // Add more browser configurations here
    
            return env;
        }
    
        public JUnitParallel(String platform, String browserName, String browserVersion) {
            this.platform = platform;
            this.browserName = browserName;
            this.browserVersion = browserVersion;
        }
    
        private WebDriver driver;
    
        @Before
        public void setUp() throws Exception {
            String key = System.getenv("TESTINGBOT_KEY");
            String secret = System.getenv("TESTINGBOT_SECRET");
            String hubURL = "https://" + key + ":" + secret + "@hub.testingbot.com/wd/hub";
    
            MutableCapabilities options = new MutableCapabilities();
            options.setCapability("browserName", browserName);
            options.setCapability("browserVersion", browserVersion);
            options.setCapability("platformName", platform);
    
            Map<String, Object> tbOptions = new HashMap<>();
            tbOptions.put("name", "Parallel JUnit Test");
            tbOptions.put("build", "build-1");
            options.setCapability("tb:options", tbOptions);
    
            driver = new RemoteWebDriver(new URL(hubURL), options);
        }
    
        @Test
        public void testSimple() throws Exception {
            driver.get("https://www.google.com");
            String title = driver.getTitle();
            System.out.println("Page title is: " + title);
    
            File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
            try {
                FileUtils.copyFile(srcFile, new File("Screenshot.png"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @After
        public void tearDown() throws Exception {
            driver.quit();
        }
    }

## Specify Browsers & Devices

To let TestingBot know on which browser/platform/device you want to run your test on, you need to specify the browsername, version, OS and other optional options in the capabilities field.

  ![OS selected](https://testingbot.com/assets/environments/svg/windows11-0e1b28bc0fdd5034d3e4d3dc8d346c500a8c6522facf4b45d0da56537c1f1c6d.svg) Windows 11 › ![Browser Selected](https://testingbot.com/assets/environments/svg/chrome-c4081ff447d2d898d4afcb8f074a907c960e6f007716c1a1d119eee6803c4042.svg) Chrome 139 

Loading environments...

Please wait while we load the available browsers and platforms.

    

## Testing Internal Websites

We've built [TestingBot Tunnel](https://testingbot.com/support/tunnel), to provide you with a secure way to run tests against your staged/internal webapps.  
Please see our [TestingBot Tunnel documentation](https://testingbot.com/support/tunnel) for more information about this easy to use tunneling solution.

The example below shows how to easily run a JUnit test with our Tunnel:

1. [Download our tunnel](https://testingbot.com/support/tunnel) and start the tunnel:

    java -jar testingbot-tunnel.jar key secret

2. Adjust your test: instead of pointing to `'hub.testingbot.com/wd/hub'` like the example above - change it to point to your tunnel's IP address.   
 Assuming you run the tunnel on the same machine you run your tests, change to `'localhost:4445/wd/hub'`. localhost is the machine running the tunnel, 4445 is the default port of the tunnel.

This way your test will go securely through the tunnel to TestingBot and back:

    @Before
    public void setUp() throws Exception {
        MutableCapabilities options = new MutableCapabilities();
        options.setCapability("browserName", browserName);
        options.setCapability("browserVersion", browserVersion);
        options.setCapability("platformName", platform);
    
        Map<String, Object> tbOptions = new HashMap<>();
        tbOptions.put("name", "Parallel Tunnel Test");
        tbOptions.put("build", "build-1");
        options.setCapability("tb:options", tbOptions);
    
        driver = new RemoteWebDriver(new URL("http://localhost:4445/wd/hub"), options);
    }

## Mark tests as passed/failed

To see if a test passed or not in our member area, or to send additional meta-data to TestingBot, you need to use our [API](https://testingbot.com/support/api).

TestingBot has a [Java client](https://github.com/testingbot/testingbot-java) for using the TestingBot API.

**Maven:**

    <dependency>
        <groupId>com.testingbot</groupId>
        <artifactId>testingbotrest</artifactId>
        <version>1.0.10</version>
    </dependency>

**Gradle:**

    implementation 'com.testingbot:testingbotrest:1.0.10'

Once included with your tests, you can send back test status and other meta-data to TestingBot:

    import com.testingbot.testingbotrest.TestingbotREST;
    import java.util.HashMap;
    import java.util.Map;
    
    @After
    public void tearDown() throws Exception {
        TestingbotREST api = new TestingbotREST(System.getenv("TESTINGBOT_KEY"), System.getenv("TESTINGBOT_SECRET"));
        Map<String, String> data = new HashMap<>();
        data.put("success", "1");
        data.put("name", "My Test");
        api.updateTest(driver.getSessionId().toString(), data);
        driver.quit();
    }

## Other Java Framework examples

- [JUnit](https://testingbot.com/support/web-automate/selenium/java/junit)

JUnit is a unit testing framework for the Java programming language.

- [Parallel JUnit](https://testingbot.com/support/web-automate/selenium/java/parallel-junit)

By running multiple JUnit tests at the same time you can cut down on overall test time.

- [TestNG](https://testingbot.com/support/web-automate/selenium/java/testng)

TestNG is a framework similar to JUnit and NUnit, which supports some additional commands and features.

- [TestNG + Cucumber](https://testingbot.com/support/web-automate/selenium/java/testng-cucumber)

Run tests with TestNG and BDD Cucumber.

### Looking for more help?

Have questions or need more information? Reach out via email or Slack.

[Email us](https://testingbot.com/contact/new)[Slack Join our Slack](https://join.slack.com/t/testingb0t/shared_invite/zt-3bcw9xch-jk19~6XPs_xBrsAgAedkCw)
