Parallele Testausführung im Frühling 5

Gleichzeitige Testdurchführung im Frühjahr 5

1. Einführung

Beginnend mitJUnit 4 können Tests parallel ausgeführt werden, um die Geschwindigkeit für größere Suiten zu erhöhen. Das Problem war, dass die gleichzeitige Testausführung vonSpring TestContext Framework vorSpring 5 nicht vollständig unterstützt wurde.

In diesem kurzen Artikel zeigen wir, wie manuse Spring 5 to run our tests in Spring projects concurrently macht.

2. Maven Setup

UmJUnit Tests parallel auszuführen, müssen wir zur Erinnerung diemaven-surefire-plugin konfigurieren, um die Funktion zu aktivieren:


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

Sie könnenreference documentation überprüfen, um eine detailliertere Konfiguration für die parallele Testausführung zu erhalten.

3. Gleichzeitiger Test

Der folgende Beispieltest schlägt fehl, wenn er parallel für Versionen vorSpring 5 ausgeführt wird.

InSpring 5 läuft es jedoch reibungslos:

@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);
    }
}

Wenn die Tests nacheinander ausgeführt werden, dauert es ungefähr 6 Sekunden, bis sie bestanden sind. Bei gleichzeitiger Ausführung dauert es nur etwa 4,5 Sekunden - was ziemlich typisch für die Zeit ist, die wir auch in größeren Suiten einsparen können.

4. Unter der Haube

Der Hauptgrund dafür, dass frühere Versionen des Frameworks das gleichzeitige Ausführen von Tests nicht unterstützten, war die Verwaltung vonTestContext durchTestContextManager.

InSpring 5 verwendetTestContextManager einen lokalen Thread -TestContext -, um sicherzustellen, dass Operationen anTestContexts in jedem Thread sich nicht gegenseitig stören. Somit ist die Thread-Sicherheit für die meisten gleichzeitigen Tests auf Methoden- und Klassenebene gewährleistet:

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();
    }

    // ...
}

Beachten Sie, dass die Parallelitätsunterstützung nicht für alle Arten von Tests gilt. we need to exclude tests that:

  • Externe freigegebene Status ändern, z. B. Status in Caches, Datenbanken, Nachrichtenwarteschlangen usw.

  • erfordern bestimmte Ausführungsreihenfolgen, z. B. Tests, dieJUnit@FixMethodOrder verwenden

  • Ändern Sie dieApplicationContext, die im Allgemeinen durch@DirtiesContext gekennzeichnet sind

5. Zusammenfassung

In diesem kurzen Tutorial haben wir ein grundlegendes Beispiel gezeigt, in demSpring 5 verwendet werden, um Tests parallel auszuführen.

Der Beispielcode befindet sich wie immer inover on Github.