Рубрики
Без рубрики

Параллельное выполнение теста весной 5

Быстрый пример параллельного выполнения теста в Spring 5.

Автор оригинала: baeldung.

1. введение

Начиная с JUnit 4 , тесты могут выполняться параллельно, чтобы увеличить скорость для больших наборов. Проблема заключалась в том, что параллельное выполнение тестов не полностью поддерживалось платформой Spring TestContext до Spring 5 .

В этой краткой статье мы покажем, как использовать Spring 5 для одновременного выполнения наших тестов в Spring проектах .

2. Настройка Maven

Напомним, что для параллельного запуска тестов JUnit нам необходимо настроить плагин maven-surefire-plugin , чтобы включить эту функцию:


    
        org.apache.maven.plugins
        maven-surefire-plugin
        2.19.1
        
            methods
            true
        
    

Вы можете ознакомиться с справочной документацией для получения более подробной конфигурации параллельного выполнения тестов.

3. Параллельный тест

Следующий пример теста завершится неудачей при параллельном запуске для версий до Spring 5 .

Тем не менее, он будет работать гладко в Весна 5 :

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

    @Configuration
    public static class SimpleConfiguration {}

    private ApplicationContext applicationContext;

    private boolean beanInitialized = false;

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

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

    @Test
    public void whenTestStarted_thenContextSet() throws Exception {
        TimeUnit.SECONDS.sleep(2);
 
        assertNotNull(
          "The application context should have been set due to ApplicationContextAware semantics.",
          this.applicationContext);
    }

    @Test
    public void whenTestStarted_thenBeanInitialized() throws Exception {
        TimeUnit.SECONDS.sleep(2);
 
        assertTrue(
          "This test bean should have been initialized due to InitializingBean semantics.",
          this.beanInitialized);
    }
}

При последовательном выполнении описанные выше тесты займут около 6 секунд. При параллельном выполнении это займет всего около 4,5 секунд – что довольно типично для того, сколько времени мы можем ожидать сэкономить и в больших наборах.

4. Под капотом

Основная причина, по которой предыдущие версии фреймворка не поддерживали одновременное выполнение тестов, заключалась в управлении TestContext с помощью TestContextManager .

В Spring 5 в TestContextManager используется локальный поток – TestContext – для обеспечения того , чтобы операции над TestContexts в каждом потоке не мешали друг другу. Таким образом, потокобезопасность гарантируется для большинства параллельных тестов на уровне методов и классов:

public class TestContextManager {

    // ...
    private final TestContext testContext;

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

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

    // ...
}

Обратите внимание, что поддержка параллелизма не применяется ко всем видам тестов; нам нужно исключить тесты, которые :

  • изменение внешних общих состояний, таких как состояния в кэшах, базах данных, очередях сообщений и т. Д.
  • требуются конкретные заказы на выполнение, например, тесты, использующие JUnit ‘s @fixmethod order
  • измените ApplicationContext , которые обычно помечены @DirtiesContext

5. Резюме

В этом кратком руководстве мы показали базовый пример использования Spring 5 для параллельного выполнения тестов.

Как всегда, пример кода можно найти на Github .