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.
Pingback :
This article was curated as a part of #42nd Issue of Software Testing Notes Newsletter.
https://softwaretestingnotes.substack.com/p/issue-42-software-testing-notes