Page History
...
Below you have just a taste of some of the new features JUnit 5 has got to offer. Check out the user guide for a more complete list.
@DisplayName
A display name can now be set for a test. This will be shown instead of the method name and will make output both easier to read and format. You can even include spaces and emojis.
Code Block | ||||
---|---|---|---|---|
| ||||
@DisplayName("Single test successful") @Test void successTest() { log.info("Success"); } |
Dynamic Tests
Dynamic on-the-fly tests can be made using @TestFactory and lambdas. These tests must return instances of Streams, Collections, Iterables, or Iterators of DynamicNode instances. These cases are executed lazily and so is generated at run-time.
...
Code Block | ||||
---|---|---|---|---|
| ||||
@Test void multipleAssertionsTest() { assertAll( () -> assertEquals(1, 2), () -> assertTrue(3 < 4), ); } |
Assumptions
These were already present in JUnit 4 but I thought they were worth a mention because in JUnit 5 they can also use Java 8 lambdas. According to the JUnit 5 user guide “Assumptions provide a basic form of dynamic behavior but are intentionally rather limited in their expressiveness”. They are useful because a failed Assumption does not fail a test, it aborts it. This is useful if you only want to perform tests under certain conditions like on certain platforms or only if certain variables are present in the current runtime environment.
Code Block | ||||
---|---|---|---|---|
| ||||
@Test void testOnlyOnCertainMachines() { assumeTrue("dev".equals(System.getenv("ENV")), () -> "Aborting test as not needed on this computer"); // rest of the test to run } |
ParameterizedTests
These allow you to run a test case multiple times with different arguments. These arguments can be strings, literal values, methods, Enums, CSV files, etc. @ParameterisedTest ultimately lets you avoid using unnecessary testing loops or duplicating test code.
Code Block | ||||
---|---|---|---|---|
| ||||
@ParameterizedTest @ValueSource(ints = { 1, 2, 3 }) void testWithValueSource(int argument) { assertTrue(argument > 0 && argument < 4); } |
Declarative Timeouts@Timeout
isn’t limited to being placed on test cases themselves. Along with the aforementioned test cases, @Timeout
can also be placed at the type level, where it will provide a default timeout for all test cases declared in the class, this can be overridden by adding a @Timeout
to a test case. @Timeout
can also be added to lifecycle methods, @BeforeAll
, @BeforeEach
, @AfterEach
, @AfterAll
.
Code Block | ||||
---|---|---|---|---|
| ||||
@Test @Timeout(unit = TimeUnit.MILLISECONDS, value = 500L) // Default unit is seconds, but other options available public void testTestCaseTimeout() throws InterruptedException { Thread.sleep(600); } |
Asserting exceptions
The @Test
annotation no longer takes an expected argument. The Jupiter API provides a much tidier way of writing this type of test.
Code Block | ||||
---|---|---|---|---|
| ||||
@Test void exceptionThrownIfTryToSetAlertStatusToNull() { IllegalArgumentException actual = assertThrows(IllegalArgumentException.class, () -> testee.setAlertStatus(null)); assertEquals("Alert status cannot be set to null.", actual.getMessage()); } |
Temporary Directory Extension
The built-in TempDirectory
extension is used to create and clean up a temporary directory for an individual test or all tests in a test class. It is registered by default. To use it, annotate a non-private field of type java.nio.file.Path
orjava.io.File
with @TempDir
or add a parameter of type java.nio.file.Path
or java.io.File
annotated with @TempDir
to a lifecycle method or test method.
Code Block | ||||
---|---|---|---|---|
| ||||
@Test void writeItemsToFile(@TempDir Path tempDir) throws IOException { Path file = tempDir.resolve("test.txt"); new ListWriter(file).write("a", "b", "c"); assertEquals(singletonList("a,b,c"), Files.readAllLines(file)); } |
Declarative Extension Registration
Developers can register one or more extensions declaratively by annotating a test interface, test class, test method, or custom composed annotation with @ExtendWith(…)
and supplying class references for the extensions to register.
...