Running Selenium tests in parallel

In the posting on Selenium Testing, the tests run one after the other. For very small tests this is usually fine, but as the test pack increases in size, it will be advantageous to decrease the test execution time by running the tests in parallel.

JUnit 5 options

The JUnit 5 documentation details options for writing tests for parallel execution, and for the purposes of the Selenium tests, running the tests whereby top-level classes execute in parallel but methods execute in the same thread is required, as the tests are structured such that while ordering does not matter, the WebDriver object is created before all the tests run, and terminated afterwards.

These options are:

junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = same_thread
junit.jupiter.execution.parallel.mode.classes.default = concurrent

Choosing at runtime

Hard coding the tests for any reason makes maintance very complex so rather than set these in a properties file, for maximum flexibility anything that could be changed should passed to the tests as an argument.

Passing the command line arguments:

mvn clean test -Djunit.jupiter.execution.parallel.enabled=true -Djunit.jupiter.execution.parallel.mode.default=same_thread -Djunit.jupiter.execution.parallel.mode.classes.default=concurrent

To the tests that reside in the PageObjects directory in the repository https://github.com/ObjectiveTester/AllThingsTesting.com-examples.git results in a series of test failures stemming from the WebDriver object being used by both groups of tests at the same time, and is caused by the way JUnit5 runs test in parallel.

ThreadLocal

The ThreadLocal class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialised copy of the variable.

static ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>();

The ThreadLocal variable in the base class holds the WebDriver object which is then unique to each thread rather than being shared. The get method allows access to the stored WebDriver object with calls such as:

driver.get().navigate().to(url);

Refactoring the tests to store the WebDriver object is relatively simple, and an updated version of the PageObjects tests with those changes reside in the SeleniumParallel directory in the repository https://github.com/ObjectiveTester/AllThingsTesting.com-examples.git

With the changes made, the tests now execute in parallel successfully on the local machine.

One thought on “Running Selenium tests in parallel

Comments are closed.