Concurrent Test Execution in Spring 5 – Spring 5中的并发测试执行

最后修改: 2017年 3月 10日


1. Introduction


Starting with JUnit 4, tests can be run in parallel to gain speed for larger suites. The problem was concurrent test execution was not fully supported by the Spring TestContext Framework prior to Spring 5.

JUnit 4开始,测试可以并行运行,以提高大型套件的速度。问题是,在Spring 5之前,Spring TestContext Framework不完全支持并发测试执行。

In this quick article, we’ll show how to use Spring 5 to run our tests in Spring projects concurrently.

在这篇快速文章中,我们将展示如何使用Spring 5Spring项目中并发运行我们的测试

2. Maven Setup


As a reminder, to run JUnit tests in parallel, we need to configure the maven-surefire-plugin to enable the feature:



You can check out the reference documentation for a more detailed configuration on parallel test execution.


3. Concurrent Test


The following example test would fail when running in parallel for versions prior to Spring 5.

对于Spring 5之前的版本,以下示例测试在并行运行时会失败。

However, it will run smoothly in Spring 5:

然而,它将在Spring 5中顺利运行。

@ContextConfiguration(classes = Spring5JUnit4ConcurrentTest.SimpleConfiguration.class)
public class Spring5JUnit4ConcurrentTest implements ApplicationContextAware, InitializingBean {

    public static class SimpleConfiguration {}

    private ApplicationContext applicationContext;

    private boolean beanInitialized = false;

    public void afterPropertiesSet() throws Exception {
        this.beanInitialized = true;

    public void setApplicationContext(
      final ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

    public void whenTestStarted_thenContextSet() throws Exception {
          "The application context should have been set due to ApplicationContextAware semantics.",

    public void whenTestStarted_thenBeanInitialized() throws Exception {
          "This test bean should have been initialized due to InitializingBean semantics.",

When running sequentially, the tests above would take around 6 seconds to pass. With concurrent execution, it will only take about 4.5 seconds – which is quite typical for how much time we can expect to save in larger suites as well.


4. Under the Hood


The primary reason prior versions of the framework didn’t support running tests concurrently was due to the management of TestContext by the TestContextManager.


In Spring 5, the TestContextManager uses a thread local – TestContext – to ensure that operations on TestContexts in each thread would not interfere with each other. Thus thread-safety is guaranteed for most method level and class level concurrent tests:

Spring 5中,TestContextManager使用线程本地 – TestContext – 以确保每个线程中对TestContexts的操作不会相互干扰。因此,对于大多数方法级和类级的并发测试来说,线程安全是有保障的。

public class TestContextManager {

    // ...
    private final TestContext testContext;

    private final ThreadLocal<TestContext> testContextHolder = new ThreadLocal<TestContext>() {
        protected TestContext initialValue() {
            return copyTestContext(TestContextManager.this.testContext);

    public final TestContext getTestContext() {
        return this.testContextHolder.get();

    // ...

Note that the concurrency support does not apply to all kinds of tests; we need to exclude tests that:


  • change external shared states, such as states in caches, databases, message queues, etc.
  • require specific execution orders, for example, tests that use JUnit‘s @FixMethodOrder
  • modify the ApplicationContext, which are generally marked by @DirtiesContext

5. Summary


In this quick tutorial, we’ve shown a basic example using Spring 5 to run tests in parallel.

在这个快速教程中,我们展示了一个使用Spring 5来并行运行测试的基本例子。

As always, the example code can be found over on Github.