What is JUnit5?
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. It also defines the Test Engine API for developing a testing framework that runs on the platform.
JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5. The Jupiter sub-project provides a Test Engine for running Jupiter-based tests on the platform.
JUnit Vintage provides a Test Engine for running JUnit 3 and JUnit 4 based tests on the platform. It requires JUnit 4.12 or later to be present on the classpath or module path.
To use JUnit5, add the Junit5 maven dependency to the POM.xml
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
JUnit Jupiter comes with many of the assertion methods that JUnit 4 already has and adds a few more that lend themselves well to being used with Java 8 lambdas. All JUnit Jupiter assertions are static methods. They come from class:
org.junit.jupiter.api.Assertions
JUnit 5 supports an additional Assertion feature called Grouped assertions. In JUnit4, when you have to assert let’s say – 3 different conditions, then you need to write 3 different assertions and they will be executed sequentially. Imagine, 2nd assertion fails, then the program stops there and will not go to the 3rd assertion. To overcome this problem, JUnit5 has a new assertion called Grouped assertion that execute all the conditions present within it using assertAll(), irrespective of the fact if any assertion fails or not and generate a consolidated report with all the failures. To be honest, I love this feature and use very frequently.
Grouped Assertions With Heading As Parameter
Example 1 – Below is an example of positive assertAll(). In the below example, all assertions are of the same type, assertEquals() within assertAll() assertion. It consists of the heading parameter with the value “GroupedAssertionsWithSameAssertionType”.
@Test
void allPositive1() {
assertAll(
"GroupedAssertionsWithSameAssertionType",
() -> assertEquals(8, 5+3, "8 is not sum of 5 and 3"),
() -> assertEquals("java", "JAVA".toLowerCase()),
() -> assertEquals(16,4*4,"16 is not product of 4 and 4")
);
}
Result
As all 3 assertions pass, so the final result passes.

Example 2 – In the below example, the assertions are of different types assertEquals(), assertNotNull and assertNotEquals() within assertAll() assertion. It consists of the heading parameter with the value “GroupedAssertionsWithDifferentAssertionType”.
@Test
void allPositive2() {
String str ="Spring";
assertAll(
"GroupedAssertionsWithDifferentAssertionType",
() -> assertEquals(8, 5+3, "8 is not sum of 5 and 3"),
() -> assertNotNull(str, () -> "The string should be null"),
() -> assertEquals("java", "JAVA".toLowerCase()),
() -> assertNotEquals(20,5*3,"20 is product of 5 and 3")
);
}
Result
As all 3 assertions pass, so the final result passes.

Example 3 – In the below example, out of 4 assertions, 3 assertions are failing, so the output will have the detail about all 3 assertion errors.
@Test
void allNegative() {
String str ="Spring";
Iterable<String> iterat1 = new ArrayList<>(asList("Java", "Junit4", "Test"));
Iterable<String> iterat2 = new ArrayList<>(asList("Java", "Junit5", "Test"));
// In a grouped assertion all assertions are executed, and all failures will be reported together
assertAll(
"Negative-GroupedAssertionsWithDifferentAssertionType",
() -> assertIterableEquals(iterat1, iterat2),
() -> assertNull(str, () -> "The string should be null"),
() -> assertEquals("java", "JAVA"),
() -> assertNotEquals(20,5*3,"20 is product of 5 and 3")
);
}
Result
As one of the asserts in the group fails, instead of AssertionFailureError it results in MultipleFailuresError thereby displaying the heading of the grouped assertion passed as the input parameter i.e. Negative-GroupedAssertionsWithDifferentAssertionType in this example. This image shows all the 3 assertion failures.
Assertion 1 fails as we were expecting JUnit4, but response has JUnit5
Assertion 2 fails as the string was not NULL.
Assertion 3 fails as Java is not equal to JAVA (case sensitivity).

Grouped Assertions Without Heading As Parameter
The assertAll () can be implemented without using the heading parameter. The below example is the same as the above one, we are just skipping the heading part.
@Test
void allNegative() {
String str ="Spring";
Iterable<String> iterat1 = new ArrayList<>(asList("Java", "Junit4", "Test"));
Iterable<String> iterat2 = new ArrayList<>(asList("Java", "Junit5", "Test"));
// In a grouped assertion all assertions are executed, and all failures will be reported together
assertAll(
() -> assertIterableEquals(iterat1, iterat2),
() -> assertNull(str, () -> "The string should be null"),
() -> assertEquals("java", "JAVA"),
() -> assertNotEquals(20,5*3,"20 is product of 5 and 3")
);
}
Result
The result displays without a heading.

Nested Or Dependent Grouped Assertions
When one assertAll() includes one or more assertAll() then these are referred to as Nested or Dependent grouped assertions.
Example 1 – In this case, first, the assertAll() validates if the sum is correct or not. The sum is correct here, so the control moves to the nested assertAll() to verify all the assertions present within it.
@Test
void allDependentPositive() {
String str ="Spring";
// Within a code block, if an assertion fails the subsequent code in the same block will be skipped.
assertAll(
"DependentPositiveAssertions",
() -> {
assertEquals(8, 5 + 3, "8 is not sum of 5 and 3");
// Executed only if the previous assertion is valid.
assertAll("sub-heading",
() -> assertNotNull(str, () -> "The string should be null"),
() -> assertEquals("java", "JAVA".toLowerCase()),
() -> assertEquals(20, 5 * 4, "20 is product of 5 and 4")
); // end of inner AssertAll()
}
); // end of outer AssertAll()
}
Result
All the assertions within nested assertAll() are passes. So the final result passes.

Example 2 – In the below example, outer AssertAll() fails, so all the assertions within nested/dependent assertAll() are not executed.
@Test
void allDependentNegative() {
String str ="Spring";
// Within a code block, if an assertion fails the subsequent code in the same block will be skipped.
assertAll(
"DependentPositiveAssertions",
() -> {
assertEquals(8, 5 + 4, "8 is not sum of 5 and 3");
// Executed only if the previous assertion is valid.
assertAll("sub-heading",
() -> assertNull(str, () -> "The string should be null"),
() -> assertNotEquals("java", "JAVA".toLowerCase()),
() -> assertNotEquals(20, 5 * 4, "20 is product of 5 and 4")
); // end of inner AssertAll()
}
); // end of outer AssertAll()
}
Result

Example 3 – In the below example, outer AssertAll() passes, so all the assertions within nested/dependent assertAll() are executed.
@Test
void allDependentNegative1() {
String str ="Spring";
// Within a code block, if an assertion passes the subsequent code in the same block will be executed.
assertAll(
"DependentNegativeAssertions",
() -> {
assertEquals(8, 5 + 3, "8 is not sum of 5 and 3");
// Executed only if the previous assertion is valid.
assertAll("sub-heading",
() -> assertNull(str, () -> "The string should be null"),
() -> assertNotEquals("java", "JAVA".toLowerCase()),
() -> assertNotEquals(20, 5 * 4, "20 is product of 5 and 4")
); // end of inner AssertAll()
}
); // end of outer AssertAll()
}
Result
The nested assertions have failed. So they can be seen in the execution status.

In short,
- When first assertAll() method passes, then all the subsequent assertions within that block will be executed and these assertions can further pass or fails.
- When the first assertAll() assertion fails, then the execution of subsequent assertions is skipped.
That’s it! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!