Next Generation Java Testing with JUnit 5

What is JUnit 5?

Unlike previous versions of JUnit, JUnit 5 is composed of several different modules from three different sub-projects.

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

The JUnit Platform serves as a foundation for launching testing frameworks on the JVM.

JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5.

JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform.

Why the word “Jupiter”?

Because it starts with “JU”, and it’s the 5th planet from the Sun.

All the packages associated with JUnit 5 have the word “jupiter” in there.

Setup

Use Gradle or Maven

@Test

New package: org.junit.jupiter.api

Other test annotations:

  • @RepeatedTest
  • @ParameterizedTest
  • @TestFactory

Lifecycle Annotations

Each test gets @Test

@BeforeEach, @AfterEach

@BeforeAll, @AfterAll

Disabled tests

@Disabled -> skip a particular test or tests

Method level or class level

Optional parameter to give a reason

Replaces @Ignored in JUnit 4

Test names

Use @DisplayName on class or methods

Supports Unicode and even emojis

Assertions

New methods in JUnit 5

  • assertAll
  • assertThrows, assertDoesNotThrow
  • assertTimeout
  • assertTimeoutPreemptively

Assumptions

Let you test pre-conditions

Static methods in org.junit.jupiter.api.Assumptions

Conditional Execution

Can make tests or test classes conditional, based on:

  • Operating system
  • Java version
  • Some boolean condition
  • Tagging and Filtering

Test Execution Order

By default, test methods will be ordered using an algorithm that is deterministic but intentionally nonobvious. This ensures that subsequent runs of a test suite execute test methods in the same order, thereby allowing for repeatable builds.

To control the order in which test methods are executed, annotate your test class or test interface with @TestMethodOrder and specify the desired MethodOrderer implementation. You can implement your own custom MethodOrderer or use one of the following built-in MethodOrderer implementations.

Test Instance Lifecycle

Nested Test Classes

Use @Nested on non-static inner classes

Nesting can be as deep as you want

Constructor and Method Parameters

In JUnit 4, no parameters in constructors or test methods

Now, parameters can be injected automatically

  • TestInfo
  • TestReporter
  • RepetitionInfo
  • Other custom ParameterResolvers supplied by extensions

Parameterized Tests

Arguably more useful than just repeated

Run a test multiple times with different arguments

@ParameterizedTest

Need at least one source of parameters

NOTE: Stable as of 5.7 (finally!)

Dynamic Tests

Generated at runtime by a factory method

Annotated with @TestFactory

Leave a comment