Please note that enabling this property is only the first step required to execute tests in parallel. If enabled, test classes and methods will still be executed sequentially by default. Whether or not a node in the test tree is executed concurrently is controlled by its execution mode. The following two modes are available.
SAME_THREAD
Force execution in the same thread used by the parent. For example, when used on a test method, the test method will be executed in the same thread as any @BeforeAll
or @AfterAll
methods of the containing test class.
CONCURRENT
Execute concurrently unless a resource lock forces execution in the same thread.
By default, nodes in the test tree use the SAME_THREAD
execution mode. You can change the default by setting the junit.jupiter.execution.parallel.mode.default
configuration parameter. Alternatively, you can use the [@Execution](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/parallel/Execution.html)
annotation to change the execution mode for the annotated element and its subelements (if any) which allows you to activate parallel execution for individual test classes, one by one.
Configuration parameters to execute all tests in parallel
The default execution mode is applied to all nodes of the test tree with a few notable exceptions, namely test classes that use the Lifecycle.PER_CLASS
mode or a [MethodOrderer](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/MethodOrderer.html)
(except for [Random](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/MethodOrderer.Random.html)
). In the former case, test authors have to ensure that the test class is thread-safe; in the latter, concurrent execution might conflict with the configured execution order. Thus, in both cases, test methods in such test classes are only executed concurrently if the @Execution(CONCURRENT)
annotation is present on the test class or method.
All nodes of the test tree that are configured with the CONCURRENT
execution mode will be executed fully in parallel according to the provided while observing the declarative synchronization mechanism. Please note that needs to be enabled separately.
Configuration parameters to execute top-level classes in parallel but methods in same thread
The opposite combination will run all methods within one class in parallel, but top-level classes will run sequentially:
Configuration parameters to execute top-level classes sequentially but their methods in parallel
The following diagram illustrates how the execution of two top-level test classes A
and with two test methods per class behaves for all four combinations of junit.jupiter.execution.parallel.mode.default
and junit.jupiter.execution.parallel.mode.classes.default
(see labels in first column).
Default execution mode configuration combinations
If the junit.jupiter.execution.parallel.mode.classes.default
configuration parameter is not explicitly set, the value for junit.jupiter.execution.parallel.mode.default
will be used instead.
2.19.1. Configuration
Properties such as the desired parallelism and the maximum pool size can be configured using a [ParallelExecutionConfigurationStrategy](https://junit.org/junit5/docs/current/api/org.junit.platform.engine/org/junit/platform/engine/support/hierarchical/ParallelExecutionConfigurationStrategy.html)
. The JUnit Platform provides two implementations out of the box: dynamic
and fixed
. Alternatively, you may implement a custom
strategy.
To select a strategy, set the junit.jupiter.execution.parallel.config.strategy
configuration parameter to one of the following options.
Computes the desired parallelism based on the number of available processors/cores multiplied by the junit.jupiter.execution.parallel.config.dynamic.factor
configuration parameter (defaults to 1
).
fixed
Uses the mandatory junit.jupiter.execution.parallel.config.fixed.parallelism
configuration parameter as the desired parallelism.
custom
Allows you to specify a custom [ParallelExecutionConfigurationStrategy](https://junit.org/junit5/docs/current/api/org.junit.platform.engine/org/junit/platform/engine/support/hierarchical/ParallelExecutionConfigurationStrategy.html)
implementation via the mandatory configuration parameter to determine the desired configuration.
If no configuration strategy is set, JUnit Jupiter uses the dynamic
configuration strategy with a factor of 1
. Consequently, the desired parallelism will be equal to the number of available processors/cores.
2.19.2. Synchronization
In addition to controlling the execution mode using the [@Execution](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/parallel/Execution.html)
annotation, JUnit Jupiter provides another annotation-based declarative synchronization mechanism. The [@ResourceLock](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/parallel/ResourceLock.html)
annotation allows you to declare that a test class or method uses a specific shared resource that requires synchronized access to ensure reliable test execution. The shared resource is identified by a unique name which is a String
. The name can be user-defined or one of the predefined constants in [Resources](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/parallel/Resources.html)
: SYSTEM_PROPERTIES
, SYSTEM_OUT
, SYSTEM_ERR
, LOCALE
, or TIME_ZONE
.
If the tests in the following example were run in parallel without the use of @ResourceLock, they would be flaky. Sometimes they would pass, and at other times they would fail due to the inherent race condition of writing and then reading the same JVM System Property.
When access to shared resources is declared using the [@ResourceLock](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/parallel/ResourceLock.html)
annotation, the JUnit Jupiter engine uses this information to ensure that no conflicting tests are run in parallel.
In addition to the String
that uniquely identifies the shared resource, you may specify an access mode. Two tests that require READ
access to a shared resource may run in parallel with each other but not while any other test that requires access to the same shared resource is running.