News from JUnit 5.x: From Revolution to Continuous Evolution

News from JUnit 5.x: From Revolution to Continuous Evolution

2017 marked a revolutionary year for the most popular Java testing framework: after two years of development, JUnit 5 was finally released – the first major release in over a decade. But work hasn’t stopped since then. If anything, the amount of feedback and the number of feature requests from the community have increased considerably. As a consequence, there have been 4 new 5.x releases with additional features and enhancements, and the JUnit team is committed to keeping up the pace and shipping a new 5.x release every few months. So it’s fair to say that JUnit is back to evolutionary releases, but the team intends to deliver them far more frequently than in the past.

In this session, we’ll take a closer look at the new features such as improved Kotlin support, module path scanning, programmatic extension registration, tag expressions, annotation-based conditional test execution, improved parameterized tests and, last but not least, parallel test execution. Moreover, we’ll see how the most popular Java build systems (Maven, Gradle, Ant) now provide built-in first-class support for running tests on the JUnit Platform. To round off the session, we will look at the roadmap of what’s still to come.

956c7d246841e8507a1e1b96842994db?s=128

Marc Philipp

April 27, 2019
Tweet

Transcript

  1. 5 NEWS FROM JUNIT 5 FROM REVOLUTION TO CONTINUOUS EVOLUTION

  2. 5 MARC PHILIPP So ware Engineer at JUnit commi er

    since 2012 team lead since 2016 Twi er: Web: @marcphilipp marcphilipp.de
  3. 5 ✋ SHOW OF HANDS

  4. 5 JUNIT 5 RELEASES 5.0 – September 10, 2017 5.1

    – February 18, 2018 5.2 – April 29, 2018 5.3 – September 11, 2018 5.4 – February 7, 2019
  5. 5 AGENDA 1. How to write tests and extensions using

    JUnit 5? 2. What is the JUnit Pla orm and why do we need it? 3. What’s s ll to come and how to get started?
  6. 5 JUNIT JUPITER JUNIT JUPITER JUNIT JUPITER JUNIT JUPITER JUNIT

    JUPITER THE NEW TESTING FRAMEWORK FOR JAVA THE NEW TESTING FRAMEWORK FOR JAVA THE NEW TESTING FRAMEWORK FOR JAVA THE NEW TESTING FRAMEWORK FOR JAVA THE NEW TESTING FRAMEWORK FOR JAVA Image: NASA
  7. 5 JUPITER? Nope, it’s just a new name so we

    can easily dis nguish it from the old JUnit and the other parts of JUnit 5. … and it’s the fi h planet from the sun. Is wri ng tests rocket science now?
  8. 5 BASICS (DEMO) h ps:/ /github.com/marcphilipp/junit5‑ demo/tree/20190427‑jeeconf

  9. 5 BASICS (RECAP) @Test is s ll a thing, but

    in org.junit.jupiter.api @Disabled instead of @Ignore @BeforeAll , @BeforeEach , @AfterEach , @AfterAll have new names Assertions look similar – a few new ones like assertThrows , assertAll Custom @DisplayNames to ease camel‑case fa gue @TestInstance(PER_METHOD or PER_CLASS) @Tag instead of @Category
  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) {/*...*/} }
  11. 5 TEST METHOD ORDERING 5.4 @TestMethodOrder(Random.class) to ensure tests don’t

    rely on any order @TestMethodOrder(Alphanumeric.class) and @TestMethodOrder(OrderAnnotation.class) for integra on tests Extensible: implement MethodOrderer
  12. 5 KOTLIN SUPPORT 5.1 import org.junit.jupiter.api.* class KotlinAssertionsDemo { @Test

    fun `expected exception testing`() { val exception = assertThrows<ArithmeticException> { Calculator().divide(1, 0) } assertEquals("/ by zero", exception.message) } @Test fun `grouped assertions`() { assertAll("Person properties", { assertEquals("Jane", person.firstName) }, { assertEquals("Doe", person.lastName) } ) } }
  13. 5 MORE WAYS TO TEST (DEMO) h ps:/ /github.com/marcphilipp/junit5‑ demo/tree/20190427‑jeeconf

  14. 5 MORE WAYS TO TEST (RECAP) @ParameterizedTest with different @Source

    annota ons @ValueSource , @EnumSource , @CsvSource , @CsvFileSource , @MethodSource , @NullSource 5.4 , @EmptySource 5.4 , @ArgumentsSource(MyProvider.class) , @YourCustomSource @RepeatedTest for flaky tests @TestFactory to produce dynamic tests
  15. 5 PARALLEL EXECUTION 5.3 (DEMO) h ps:/ /github.com/marcphilipp/junit5‑ demo/tree/20190427‑jeeconf

  16. 5 PARALLEL EXECUTION 5.3 (RECAP) Tests are run sequen ally

    by default Opt‑in and configure parallel execu on via configura on parameters @Execution(SAME_THREAD or CONCURRENT) Use @ResourceLock as declara ve synchroniza on mechanism
  17. 5 EXTENSIONS (DEMO) h ps:/ /github.com/marcphilipp/junit5‑ demo/tree/20190427‑jeeconf

  18. 5 EXTENSIONS (RECAP) Registra on (as many as you need):

    Declara ve: @ExtendWith on classes or methods Programma c: @RegisterExtension on fields 5.1 Global: Via ServiceLoader (see ) Implementa on: Extension marker interface one extension – n extension points/interfaces User Guide
  19. 5 COMPOSED ANNOTATIONS Use Jupiter annota ons as meta‑annota ons

    to create your own annota ons. @Retention(RUNTIME) @Target(METHOD) @ExtendWith(DisabledOnWeekdaysExtension.class) @Tag("example") public @interface DisabledOnWeekdays { DayOfWeek[] value(); }
  20. 5 EXTENSION POINTS Lifecycle: BeforeAllCallback , BeforeEachCallback , BeforeTestExecutionCallback ,

    TestExecutionExceptionHandler , AfterTestExecutionCallback , AfterEachCallback , AfterAllCallback Other: ExecutionCondition , ParameterResolver , TestInstanceFactory 5.3 , TestInstancePostProcessor , TestWatcher 5.4 , TestTemplateInvocationContextProvider
  21. 5 BUILT‑IN TEMP DIR SUPPORT 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<String> actualLines = Files.readAllLines(testFile); assertIterableEquals(asList("foo", "bar"), actualLines); }
  22. 5 BUILT‑IN CONDITIONS 5.1 @EnabledOnOs / @DisabledOnOs({LINUX, MAC, …}) @EnabledOnJre

    / @DisabledOnJre({JAVA_11, …}) @Enabled / DisabledIfSystemProperty(named = "someKey", matches = "someValue") @Enabled / DisabledIfEnvironmentVariable(named = "SOME_KEY", matches = "SOME_VALUE")
  23. 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
  24. 5 AGENDA 1. How to write tests and extensions using

    JUnit 5? ✅ 2. What is the JUnit Pla orm and why do we need it? 3. What’s s ll to come and how to get started?
  25. 5 JUNIT PLATFORM JUNIT PLATFORM JUNIT PLATFORM JUNIT PLATFORM JUNIT

    PLATFORM PLATFORM FOR TESTING ON THE JVM PLATFORM FOR TESTING ON THE JVM PLATFORM FOR TESTING ON THE JVM PLATFORM FOR TESTING ON THE JVM PLATFORM FOR TESTING ON THE JVM Image: NASA
  26. 5 JUNIT AS A PLATFORM? JUnit has always been a

    pla orm for IDEs and build tools for other tes ng frameworks Closely coupled (internal APIs, reflec on, serializa on)
  27. 5 COUPLING

  28. 5 If JUnit is a pla orm, let’s design for

    it!
  29. 5 SEPARATION OF CONCERNS 1. An API to write tests

    and extensions (Jupiter API) 2. Extensible mechanisms to discover and execute tests (Test Engine SPI) 3. An API for test execu on by tools (Launcher API)
  30. 5 DESIGN GOALS Flexibility: Adding new features should be easy.

    It should be clear whether a change might poten ally break a client. Backward Compa bility: Test wri en with JUnit 3 and 4 should s ll run Forward Compa bility: Old IDEs and build tools should be able to execute new tests
  31. 5

  32. 5 JUNIT 5 = JUPITER + VINTAGE + PLATFORM

  33. 5 COMPATIBILITY / MIGRATION Vintage Engine to run JUnit 3/4

    tests on the Pla orm @Category(UI.class) maps to com.acme.UI tag Limited support for JUnit 4 Rules to ease migra on Migra on support for @Ignore 5.4 IDEs provide tools to convert test classes to Jupiter API Community‑provided migra on tool: h ps:/ /github.com/boyarsky/convert‑junit4‑to‑junit5
  34. 5 BUILD TOOL SUPPORT Na ve support in Gradle (≥

    4.6), Ant (≥ 1.10.3), and Maven Surefire (≥ 2.22.0) ConsoleLauncher to run tests from the command line or to support other build tools (e.g. Bazel)
  35. 5 IDE SUPPORT Excellent support IntelliJ IDEA (≥ 2016.2) Eclipse

    (≥ 4.7.1a) Visual Studio Code (Java Test Runner ≥ 0.4.0) Netbeans (≥ 10.0) For other tools, there’s @RunWith(JUnitPlatform)
  36. 5 THIRD‑PARTY ENGINES Specsy, Spek, KotlinTest, Cucumber, Drools, jqwik, Brahms,

    Mainrunner, … h ps:/ /github.com/junit‑team/junit5/wiki/Third‑party‑ Extensions
  37. 5 USING MULTIPLE ENGINES (DEMO) h ps:/ /github.com/marcphilipp/junit5‑pla orm‑demo

  38. 5 USING MULTIPLE ENGINES (RECAP) Mul ple test engines can

    be used in a single test run Dis nc on between testImplementation and testRuntimeOnly dependencies Allows to gradually migrate tests from one test engine to another (e.g. from Vintage to Jupiter)
  39. 5 TAG EXPRESSIONS 5.1 Precisely specify which tests to run

    based on tags: test { useJUnitPlatform { includeTags("(smoke & feature-a) | (!smoke & feature-b)") } }
  40. 5 SUPPORT FOR JAVA MODULES 5.1 Execute all tests in

    a module: Scan the module path: $ 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
  41. 5 AGENDA 1. How to write tests and extensions using

    JUnit 5? ✅ 2. What is the JUnit Pla orm and why do we need it? ✅ 3. What’s s ll to come and how to get started?
  42. 5 ROADMAP AND ROADMAP AND ROADMAP AND ROADMAP AND ROADMAP

    AND RESOURCES RESOURCES RESOURCES RESOURCES RESOURCES Image: NASA
  43. 5 IMPORTANT FUTURE MILESTONES Reusable test discovery for test engines

    5.5 M1 Execu ng tests in user‑defined threads 5.5 M2 Declara ve/global meouts 5.5 M2 New repor ng format that supports new features (e.g. tags, display names, report entries) Declara ve Test Suites Parameterized Test Classes Your ideas?
  44. 5 GETTING STARTED User Guide: Sample projects for Ant, Bazel,

    Gradle, and 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/
  45. 5 WANTED: FEEDBACK! StackOverflow: Code & Issues: Chat with the

    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
  46. 5 SUPPORT JUNIT Support the JUnit team with dona ons:

    h ps:/ /junit.org/sponsoring
  47. 5 EXAMPLE CODE Jupiter: Pla orm: h ps:/ /github.com/marcphilipp/junit5‑ demo/tree/20190427‑jeeconf

    h ps:/ /github.com/marcphilipp/junit5‑pla orm‑demo
  48. 5 QUESTIONS? / on Twi er @marcphilipp @juni eam

  49. 5 ДЯКУЮ!