Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Neues von JUnit 5.x: From Revolution to Continuous Evolution

Neues von JUnit 5.x: From Revolution to Continuous Evolution

2017 war ein revolutionäres Jahr für das beliebteste Java Testing Framework: Nach zwei Jahren der Entwicklung wurde mit JUnit 5 das erste Major-Release seit mehr als 10 Jahren veröffentlicht. Das JUnit-Team hat danach jedoch keineswegs die Arbeit eingestellt. Im Gegenteil: Seitdem ist die Menge an Feedback und Feature Requests aus der Community merklich gestiegen. Das Resultat sind mittlerweile fünf weitere 5.x Releases, die zusätzliche Features und Verbesserungen beinhalten. Das JUnit-Team arbeitet daran, dieses Tempo beizubehalten und alle paar Monate ein weiteres 5.x Release zu veröffentlichen. Anstatt wie in Version 5.0 komplett neue Packages und Artefakte einzuführen, ist das Ziel die Evolution der bestehenden APIs. Allerdings soll das weitaus häufiger geschehen als in der Vergangenheit.

In diesem Vortrag werden wir uns nach einer kurzen Einführung in JUnit 5 auf die neuen Features der 5.x Releases konzentrieren. Dies sind unter anderem verbesserte Unterstützung für Kotlin, Scannen des Module Path, programmatische Registrierung von Extensions, Tag Expressions, Annotation-basierte bedingte Ausführung von Tests, verbesserte parametrisierte Tests und, zu guter Letzt, parallele Testausführung. Des Weiteren werfen wir eine kurzen Blick auf die meistbenutzten Build Tools für Java (Maven, Gradle, Ant) und deren mittlerweile erstklassige Unterstützung für die neue JUnit Platform. Zum Abschluss diskutieren wir, woran das JUnit-Team aktuell arbeitet und was zukünftige Releases versprechen.

Marc Philipp

June 03, 2019
Tweet

More Decks by Marc Philipp

Other Decks in Programming

Transcript

  1. 5
    NEUES VON JUNIT 5
    FROM REVOLUTION TO CONTINUOUS
    EVOLUTION

    View Slide

  2. 5
    MARC PHILIPP
    So ware Engineer bei
    JUnit Commi er seit 2012
    Team Lead seit 2016
    Twi er:
    Web:
    @marcphilipp
    marcphilipp.de

    View Slide

  3. 5

    SHOW OF HANDS

    View Slide

  4. 5
    JUNIT 5 RELEASES
    5.0 – 10. September 2017
    5.1 – 18. Februar 2018
    5.2 – 29. April 2018
    5.3 – 11. September 2018
    5.4 – 7. Februar 2019
    5.5 – Juni 2019

    View Slide

  5. 5
    AGENDA
    1. Wie schreibt man Tests und Extensions mit JUnit 5?
    2. Was ist die JUnit Pla orm und wozu ist sie gut?
    3. Was kommt noch und die fängt man mit JUnit 5 an?

    View Slide

  6. 5
    JUNIT JUPITER
    JUNIT JUPITER
    JUNIT JUPITER
    JUNIT JUPITER
    JUNIT JUPITER
    DAS NEUE TESTING FRAMEWORK FÜR JAVA
    DAS NEUE TESTING FRAMEWORK FÜR JAVA
    DAS NEUE TESTING FRAMEWORK FÜR JAVA
    DAS NEUE TESTING FRAMEWORK FÜR JAVA
    DAS NEUE TESTING FRAMEWORK FÜR JAVA
    Image: NASA

    View Slide

  7. 5
    JUPITER?
    Nein, “Jupiter” ist einfach ein neuer Name zur besseren
    Unterscheidung der verschiedenen Teile von JUnit 5.
    … und es ist der fün e Planet von der Sonne aus gezählt.
    Is wri ng tests rocket science now?

    View Slide

  8. 5
    BASICS (DEMO)
    h ps:/
    /github.com/marcphilipp/junit5‑
    demo/tree/20190603‑etka

    View Slide

  9. 5
    BASICS (RECAP)
    @Test ist jetzt in org.junit.jupiter.api
    @Disabled ansta @Ignore
    @BeforeAll , @BeforeEach , @AfterEach , @AfterAll
    haben neue Namen
    Assertions sehen ähnlich aus – zusätzlich
    assertThrows , assertAll
    Eigene @DisplayNames sta Camel Case
    @TestInstance(PER_METHOD oder PER_CLASS)
    @Tag ansta @Category

    View Slide

  10. 5
    DISPLAY NAME GENERATORS 5.4
    @DisplayNameGeneration(ReplaceUnderscores.class)
    class A_year_is_not_supported {
    @Test
    void if_it_is_zero() {/*...*/}
    @ParameterizedTest
    @ValueSource(ints = { -1, -4 })
    void if_it_is_negative(int year) {/*...*/}
    }

    View Slide

  11. 5
    TEST METHOD ORDERING 5.4
    @TestMethodOrder(Random.class) hil sicherzustellen,
    dass Tests nicht Reihenfolge‑abhängig sind
    @TestMethodOrder(Alphanumeric.class) und
    @TestMethodOrder(OrderAnnotation.class) für
    Integra onstests
    Erweiterbar: MethodOrderer implemen eren

    View Slide

  12. 5
    KOTLIN SUPPORT 5.1
    import org.junit.jupiter.api.*
    class KotlinAssertionsDemo {
    @Test
    fun `expected exception testing`() {
    val exception = assertThrows {
    Calculator().divide(1, 0)
    }
    assertEquals("/ by zero", exception.message)
    }
    @Test
    fun `grouped assertions`() {
    assertAll("Person properties",
    { assertEquals("Jane", person.firstName) },
    { assertEquals("Doe", person.lastName) }
    )
    }
    }

    View Slide

  13. 5
    WEITERE TESTARTEN (DEMO)
    h ps:/
    /github.com/marcphilipp/junit5‑
    demo/tree/20190603‑etka

    View Slide

  14. 5
    WEITERE TESTARTEN (RECAP)
    @ParameterizedTest mit versch. @Source ‑Annota onen
    @ValueSource , @EnumSource , @CsvSource ,
    @CsvFileSource , @MethodSource , @NullSource 5.4 ,
    @EmptySource 5.4 ,
    @ArgumentsSource(MyProvider.class) ,
    @YourCustomSource
    @RepeatedTest für “flaky” Tests
    @TestFactory um dynamisch Tests zu produzieren

    View Slide

  15. 5
    PARALLEL EXECUTION 5.3 (DEMO)
    h ps:/
    /github.com/marcphilipp/junit5‑
    demo/tree/20190603‑etka

    View Slide

  16. 5
    PARALLEL EXECUTION 5.3 (RECAP)
    Tests laufen standardmäßig sequenziell
    Parallele Ausführung lässt sich per Configura on
    Parameter ak vieren
    @Execution(SAME_THREAD oder CONCURRENT)
    @ResourceLock zur deklara ven Synchronisa on

    View Slide

  17. 5
    EXTENSIONS (DEMO)
    h ps:/
    /github.com/marcphilipp/junit5‑
    demo/tree/20190603‑etka

    View Slide

  18. 5
    EXTENSIONS (RECAP)
    Registrierung (beliebig viele gleichzei g):
    Deklara v: @ExtendWith an Klassen oder Methoden
    Programma sch: @RegisterExtension an Feldern 5.1
    Global: per ServiceLoader (s. )
    Implemen erung:
    Extension Marker Interface
    1 Extension – n Extension Points/Interfaces
    User Guide

    View Slide

  19. 5
    COMPOSED ANNOTATIONS
    Jupiter‑Annota on können als Meta‑Annota on verwendet
    werden, um eigene Annota onen zu definieren.
    @Retention(RUNTIME)
    @Target(METHOD)
    @ExtendWith(DisabledOnWeekdaysExtension.class)
    @Tag("example")
    public @interface DisabledOnWeekdays {
    DayOfWeek[] value();
    }

    View Slide

  20. 5
    EXTENSION POINTS
    Lifecycle: BeforeAllCallback , BeforeEachCallback ,
    BeforeTestExecutionCallback ,
    TestExecutionExceptionHandler ,
    LifecycleMethodExecutionExceptionHandler 5.5 ,
    AfterTestExecutionCallback , AfterEachCallback ,
    AfterAllCallback , InvocationInterceptor 5.5
    Andere: ExecutionCondition , ParameterResolver ,
    TestInstanceFactory 5.3 ,
    TestInstancePostProcessor , TestWatcher 5.4 ,
    TestTemplateInvocationContextProvider

    View Slide

  21. 5
    TEMPORÄRE VERZEICHNISSE 5.4
    import org.junit.jupiter.api.io.TempDir;
    @Test
    void writeAndReadFile(@TempDir Path tempDir) throws Exception {
    Path testFile = tempDir.resolve("test.txt");
    Files.write(testFile, asList("foo", "bar"));
    List actualLines = Files.readAllLines(testFile);
    assertIterableEquals(asList("foo", "bar"), actualLines);
    }

    View Slide

  22. 5
    BEDINGTE AUSFÜHRUNG 5.1
    @EnabledOnOs / @DisabledOnOs({LINUX, MAC, …})
    @EnabledOnJre / @DisabledOnJre({JAVA_11, …})
    @Enabled / DisabledIfSystemProperty(named =
    "someKey", matches = "someValue")
    @Enabled / DisabledIfEnvironmentVariable(named =
    "SOME_KEY", matches = "SOME_VALUE")

    View Slide

  23. 5
    DEKLARATIVE TIMEOUTS 5.5
    @BeforeEach
    @Timeout(10)
    void setUp() {
    // schlägt fehl, falls Ausführung länger als 10 Sekunden dauert
    }
    @Test
    @Timeout(value = 500, unit = MILLISECONDS)
    void someTest() {
    // schlägt fehl, falls Ausführung länger als 500 Millisekunden dauert
    }

    View Slide

  24. 5
    THIRD‑PARTY EXTENSIONS
    JUnit Pioneer, Spring, Mockito, Testcontainers, Docker,
    Wiremock, JPA, Selenium/WebDriver, DbUnit, Ka a, Jersey,
    GreenMail, S3Mock, Citrus Framework, XWiki, …
    h ps:/
    /github.com/junit‑team/junit5/wiki/Third‑party‑
    Extensions

    View Slide

  25. 5
    AGENDA
    1. Wie schreibt man Tests und Extensions mit JUnit 5? ✅
    2. Was ist die JUnit Pla orm und wozu ist sie gut?
    3. Was kommt noch und die fängt man mit JUnit 5 an?

    View Slide

  26. 5
    JUNIT PLATFORM
    JUNIT PLATFORM
    JUNIT PLATFORM
    JUNIT PLATFORM
    JUNIT PLATFORM
    PLATTFORM ZUM TESTEN AUF DER JVM
    PLATTFORM ZUM TESTEN AUF DER JVM
    PLATTFORM ZUM TESTEN AUF DER JVM
    PLATTFORM ZUM TESTEN AUF DER JVM
    PLATTFORM ZUM TESTEN AUF DER JVM
    Image: NASA

    View Slide

  27. 5
    JUNIT ALS PLATTFORM?
    JUnit war schon immer eine Pla orm
    für IDEs und Build Tools
    für andere Tes ng Frameworks
    Enge Kopplung (interne APIs, Reflec on, Serializa on)

    View Slide

  28. 5
    COUPLING

    View Slide

  29. 5
    Wenn JUnit eine Pla orm ist, dann sollten
    wir die Architektur darauf auslegen!

    View Slide

  30. 5
    TRENNUNG VON
    VERANTWORTLICHKEITEN
    1. API zum Schreiben von Tests und Extensions (Jupiter API)
    2. Erweiterbarer Mechanismus zum Auffinden und
    Ausführen von Tests (Test Engine SPI)
    3. API zur Testausführung durch IDEs und Build Tools
    (Launcher API)

    View Slide

  31. 5
    DESIGN‑ZIELE
    Flexibilität: Neue Features hinzuzufügen ist einfach. Es ist
    klar, ob eine Änderung problema sch ist oder nicht.
    Rückwärtskompa bilität: JUnit 3/4 Tests laufen immer
    noch
    Vorwärtskompa bilität: Alte IDEs und Build Tools können
    neue Tests ausführen

    View Slide

  32. 5

    View Slide

  33. 5
    JUNIT 5
    =
    JUPITER + VINTAGE + PLATFORM

    View Slide

  34. 5
    THIRD‑PARTY ENGINES
    Specsy, Spek, KotlinTest, Cucumber, Drools, jqwik, Brahms,
    Mainrunner, …
    h ps:/
    /github.com/junit‑team/junit5/wiki/Third‑party‑
    Extensions

    View Slide

  35. 5
    MEHRERE TEST ENGINES (DEMO)
    h ps:/
    /github.com/marcphilipp/junit5‑pla orm‑demo

    View Slide

  36. 5
    MEHRERE TEST ENGINES (RECAP)
    Mehrere Test Engines können in einem Testlauf verwendet
    werden
    Unterscheidung zwischen Abhängigkeiten in
    testImplementation und testRuntimeOnly
    Erlaubt eine schri weise Migra on von einer Test Engine
    zur anderen (z.B. von Vintage nach Jupiter)

    View Slide

  37. 5
    KOMPATIBILITÄT / MIGRATION
    Vintage Engine führt JUnit 3/4 Tests auf der Pla orm aus
    @Category(UI.class) entspricht com.acme.UI ‑Tag
    Teilweise Unterstützung von JUnit 4 Rules
    Unterstützung von @Ignore 5.4
    IDEs können Testklassen in die Jupiter API konver eren
    Migra onswerkzeug aus der Community:
    h ps:/
    /github.com/junit‑pioneer/convert‑junit4‑to‑junit5

    View Slide

  38. 5
    BUILD TOOLS
    Gradle (≥ 4.6), Ant (≥ 1.10.3) und Maven Surefire (≥ 2.22.0)
    unterstützen die JUnit Pla orm
    Mit dem ConsoleLauncher kann man Tests über die
    Kommandozeile ausführen und in andere Build Tools (z.B.
    Bazel) integrieren

    View Slide

  39. 5
    IDES
    Sehr gute Unterstützung
    IntelliJ IDEA (≥ 2016.2)
    Eclipse (≥ 4.7.1a)
    Visual Studio Code (Java Test Runner ≥ 0.4.0)
    Netbeans (≥ 10.0)
    Für andere IDEs gibt es @RunWith(JUnitPlatform)

    View Slide

  40. 5
    TAG EXPRESSIONS 5.1
    Erlauben präzise anzugeben, welche Tests basierend auf Tags
    ausgeführt werden sollen:
    test {
    useJUnitPlatform {
    includeTags("(smoke & feature-a) | (!smoke & feature-b)")
    }
    }

    View Slide

  41. 5
    UNTERSTÜTZUNG FÜR
    MODULE 5.1
    Alle Tests in einem Modul ausführen:
    Den Modulpfad scannen:
    $ java -jar junit-platform-console-standalone-1.4.0.jar \
    --select-module com.acme.foo
    $ java -jar junit-platform-console-standalone-1.4.0.jar \
    --scan-modules

    View Slide

  42. 5
    AGENDA
    1. Wie schreibt man Tests und Extensions mit JUnit 5? ✅
    2. Was ist die JUnit Pla orm und wozu ist sie gut? ✅
    3. Was kommt noch und die fängt man mit JUnit 5 an?

    View Slide

  43. 5
    ROADMAP UND
    ROADMAP UND
    ROADMAP UND
    ROADMAP UND
    ROADMAP UND
    RESSOURCEN
    RESSOURCEN
    RESSOURCEN
    RESSOURCEN
    RESSOURCEN
    Image: NASA

    View Slide

  44. 5
    ROADMAP
    Wiederverwendbare Discovery für Test Engines 5.5 M1
    Testausführung in nutzerdefinierten Threads 5.5 RC1
    Deklara ve/globale Timeouts 5.5 RC1
    Repor ng‑Format, das neue Features unterstützt
    (z.B. Tags, Display Names, Report Entries) 5.6 M1
    Deklara ve Test Suiten
    Parametrisierte Testklassen
    Eure Ideen?

    View Slide

  45. 5
    LOSLEGEN? LOSLEGEN!
    User Guide:
    Beispielprojekte für Ant, Bazel, Gradle und Maven:
    Javadoc:
    h p:/
    /junit.org/junit5/docs/current/user‑guide/
    h ps:/
    /github.com/junit‑team/junit5‑samples
    h p:/
    /junit.org/junit5/docs/current/api/

    View Slide

  46. 5
    GESUCHT: FEEDBACK!
    StackOverflow:
    Code & Issues:
    Chat mit dem Team:
    Twi er:
    h p:/
    /stackoverflow.com/ques ons/tagged/junit5
    h ps:/
    /github.com/junit‑team/junit5/
    h ps:/
    /gi er.im/junit‑team/junit5
    h ps:/
    /twi er.com/juni eam

    View Slide

  47. 5
    UNTERSTÜTZT DAS JUNIT‑TEAM!
    h ps:/
    /junit.org/sponsoring

    View Slide

  48. 5
    BEISPIEL‑CODE
    Jupiter:
    Pla orm:
    h ps:/
    /github.com/marcphilipp/junit5‑
    demo/tree/20190603‑etka
    h ps:/
    /github.com/marcphilipp/junit5‑pla orm‑demo

    View Slide

  49. 5
    FRAGEN?
    / auf Twi er
    @marcphilipp @juni eam

    View Slide

  50. 5
    VIELEN DANK!

    View Slide

  51. Bitte geben Sie uns jetzt Ihr Feedback!
    Neues von JUnit 5.x: From Revolution to
    Continuous Evolution
    Marc Philipp
    Nächste Vorträge in diesem Raum
    11:45 Best Practices für moderne
    Multicore‑Programmierung, Prof. Dr. Jörg
    Hettel
    13:30 GraphQL als Schnittstelle zum
    Backend, Christian Kumpe, Thorben
    Hischke
    14:30 Integration ist schwer,
    Integrationstests umso mehr, Benjamin
    Muskalla
    5

    View Slide