JUnit 5 Tutorial : Display name

In JUnit 5, we can use @DisplayName to declare custom display names for test classes and test methods.

Display Name Example

package com.bootng.display;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class DisplayCustomNameTest {

	@Test
	public void test_if_it_will_rain() {
	}

	@Test
	public void test_if_it_will_be_cloudy() {
	}

	@Test
	public void test_if_it_will_be_sunny() {
	}

}

Output




Display CustomName Example

package com.bootng.display;
@DisplayName("Vacation Weather Test")
public class DisplayCustNameTest {
	@DisplayName("🌧")
	@Test
	public void test_if_it_will_rain() {
	}

	@DisplayName("🌨")
	@Test
	public void test_if_it_will_be_cloudy() {
	}

	@DisplayName("🌞")
	@Test
	public void test_if_it_will_be_sunny() {
	}
}
Output

Custom Name Generator Example

We can also use a Custom Name generator to generate the test names. As of Version 5.4 it comes with the following generators out of the box.

DisplayNameGenerator.IndicativeSentences
DisplayNameGenerator.ReplaceUnderscores
DisplayNameGenerator.Simple
DisplayNameGenerator.Standard

Each of the above generators has different implementations of how to generate test name. 

In the Following example we are using ReplaceUnderscores.  As a result the test names will be generated by replacing the "_" from respective names.
package com.bootng.display;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@DisplayName("Weather Test DisplayExample ")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
public class DisplayGeneratorExampleTest {

	@Test
	public void test_if_it_will_rain() {
	}

	@Test
	public void test_if_it_will_be_cloudy() {
	}

	@Test
	public void test_if_it_will_be_sunny() {
	}
}

Output


JUnit5 Important Annotations

Junit 5 comes with some new annotations that were not available in previous releases. Understanding these Annotations will help in writing efficient tests. This article covers some of the most commonly used annotations. In the next section, we will example of those annotations.
The following are some of the important annotations in JUnit 5.

@Test

@Test : Denotes that a method is a test method. Without this annotation, JUnit will ignore the method

@ParameterizedTest

Denotes a method to be a parameterized test method. Parameterized tests make it possible to run a test multiple times with different arguments.

@RepeatedTest

@RepeatedTest : Test methods marked with @RepeatedTest can be executed repeatedly

@TestMethodOrder

@TestMethodOrder: Helps maintain order in which test methods are executed.

@DisplayName

@DisplayName : Helps in using a custom name to be printed either in the console or test report for the test method.

@DisplayNameGeneration

@DisplayNameGeneration : Declares a custom display name generator for the test class

@BeforeEach

@BeforeEach: Analogous to JUnit 4 @Before. Denotes the annotated method should be executed before each test. The method should not return any value, should not be private.

@AfterEach

@AfterEach : Analogous to JUnit 4 @After. Denotes the annotated method should be executed after each test. The method should not return any value, should not be private.

@BeforeAll

@BeforeAll: Denotes that the annotated method should be executed before all @Test, @RepeatedTest, @ParameterizedTest, and @TestFactory methods in the current class; analogous to JUnit 4’s @BeforeClass. Such methods are inherited (unless they are hidden or overridden) and must be static (unless the "per-class" test instance lifecycle is used).

@AfterAll

@AfterAll: Denotes that the annotated method should be executed after all @Test, @RepeatedTest, @ParameterizedTest, and @TestFactory methods in the current class; analogous to JUnit 4’s @AfterClass. A method marked with @AfterAll is inherited (unless they are hidden or overridden) and must be static.

@Nested

@Nested:Denotes that the annotated class is a non-static nested test class. @BeforeAll and @AfterAll methods cannot be used directly in a @Nested test class unless the "per-class" test instance lifecycle is used. Such annotations are not inherited.

@Tag

@Tag: Used to declare tags for filtering tests, either at the class or method level; analogous to test groups in TestNG or Categories in JUnit 4. Such annotations are inherited at the class level but not at the method level.

@Disabled

@Disabled : Used to disable a test class or test method; analogous to JUnit 4’s @Ignore. Such annotations are not inherited.

@Timeout

@Timeout: Used to fail a test, test factory, test template, or lifecycle method if its execution exceeds a given duration. Such annotations are inherited.

Next

JUnit 5 Test Suites

The test suite is a container that has a set of tests that can be executed together. For instance, say we have multiple tests and want to execute all of them or subset of them under certain conditions. Like we want to run all the tests in the integration stage, a subset of tests in the developer environment before pushing code. All these can be done using Test Suite. Using JUnit 5 test suites, we can run tests spread into multiple test classes and different packages. JUnit 5 provides two annotations: @SelectPackages and @SelectClasses to create test suites. Additionally, you can use other annotations for filtering test packages, classes, or even test methods.

Filtering Tests in Suites

Tests in JUnit5 can be executed with @RunWith. The same annotation is also used for Junit 4. The only difference Is in Junit 5 we pass JUnitPlatform as a parameter. In this article we will go though some sample use cases of creating TestSuite in JUnit 5 and how to filter test classes, test methods in the test suite etc.

@SelectPackages

With this annotation, we can tell the Test Suite to scan all the mention packages and its sub-packages and execute all the Test Classes. We can also specify a signal package or multiple packages. Following example demonstrates this.
Select a single package
With @SelectPackages we can select test classes only from a specified package or list of packages. In the following example, all the Test classes from package com.bootng will be executed.
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.runner.RunWith;

@RunWith(JUnitPlatform.class)
@SelectPackages({ "com.bootng" })
public class TestSuiteWithPackageSingle {

}
Select multiple packages
Similarly, if we want to support multiple packages then we can specify multiple package names. The following example will execute tests from the two packages.
@RunWith(JUnitPlatform.class)
@SelectPackages({ "com.bootng.assertions", "com.bootng.display" })
public class TestSuiteWithPackageMultiple {

}

@SelectClasses

Select Two Classes
In this example rather than selecting packages, we can specify individual test classes that we want to include in the Test Suite. In the following example essentially we will have only two Test classes in the Test Suite.
@RunWith(JUnitPlatform.class)
@SelectClasses({ DisplayExampleTest.class, DisplayGeneratorExampleTest.class })
public class TestSuiteWithSelectClass {

}

@IncludePackages and @ExcludePackages

@IncludePackages and @ExcludePackages work only at the specified package level and it won't scan sub-packages. This annotation is used with @SelectPackages annotation to fine-tune the filtering. Son in the following example Test Classes from only com.bootng.assertions will be included.
IncludePackages Example
Here
@RunWith(JUnitPlatform.class)
@SelectPackages({ "com.bootng" })
@IncludePackages({ "com.bootng.assertions" })
public class TestSuite_IncludePackage {

}
ExcludePackages Example
Includes all the test form package com.bootng, but excludes tests from sub package com.bootng.assertions.
@RunWith(JUnitPlatform.class)
@SelectPackages({ "com.bootng" })
@IncludePackages({ "com.bootng.assertions" })
public class TestSuite_IncludePackage {

}

@IncludeClassNamePatterns and @ExcludeClassNamePatterns

Rather than filtering the test class from packages, we can also filter them based on the name of the Test Classes. To specify test class names patterns to exclude or include, you can use @IncludeClassNamePatterns and @ExcludeClassNamePatterns annotations.
IncludeClassNamePatterns Example
In this example, we can including only the test whose name ends with "Test" from the package (and sub packages) of com.bootng
@RunWith(JUnitPlatform.class)
@SelectPackages({ "com.bootng" })
@IncludeClassNamePatterns("^.*Test*$")
public class TestSuite_NamePattern {

}

@IncludeTags and @ExcludeTags

IncludeTags Example
With IncludeTags and Exclude Tags we can filter Classes or Methods that are Tagged with the specified tag. For Instance, the following example, we are scanning package com.bootng.assertions and then only interested in including Test Classes or Test Methods tagged with Weather.
@RunWith(JUnitPlatform.class)
@SelectPackages({ "com.bootng.assertions" })
@IncludeTags({ "Weather" })
public class TestSuite_TagInclude {

}
ExcludeTags Example
Similar to IncludeTags tag to filter Test Methods or Test Classes but for exclusion. The following example will exclude all the Tests tagged with "Weather"
@RunWith(JUnitPlatform.class)
@SelectPackages({ "com.bootng.assertions" })
@ExcludeTags({ "Weather" })
public class TestSuite_TagExclude {

}

Summary

JUnit 5 provides powerful ways to filter Test cases in Test Suites. We have several options starting from including/excluding a specific packages to include/exclude specific Classes to Include/Exclude specific methods.

Test Classes and Methods Requirement

JUnit 5 is the latest version of Junit. It has a brand new architecture and more capabilities compared to the previous generation of Junit. In this article, we will quickly go through some of the main features and concepts of JUnit 5. In this article we go over the high-level structural requirement for writing Unit Tests. Generally, we write test method to represent a test case or a certain scenario which we want to validate. Such test methods would reside inside a Class. With Junit5 we don't need to mark or annotate the main class with any special JUnit specific annotations. Junit5 will be able to

Test Class

Any top-level class, static member class, or @Nested class that contains at least one test method. We don't need to annotate the Class, JUnit5 will be able to find test methods defined inside it.
Class Requirement
The Class should contain only one Constructor and the Class should not be an abstract Class.

Test Method

Any not abstract instance method that is annotated with @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, or @TestTemplate.
Test Method
The test method should not return any value and should not be abstract.

Lifecycle Method

Any method that is directly annotated or meta-annotated with @BeforeAll, @AfterAll, @BeforeEach, or @AfterEach Lifecycle methods can be inherited from parent class. Lifecycle methods should not be private and should not return any value.
Lifecycle Method
Should not be private and should not return value. @BeforeAll and @AfterAll should be used on a static method

Example

Following Example shows a Test Class with one test method annotated with @Test and four Lifecylcle emthods
SimpleHelloTest3
package com.bootng.start;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;

public class SimpleHelloTest3 {

	@BeforeAll
	public static void method1() {
		System.out.println("method 1");
	}
	
	@BeforeEach
	public void method2() {
		System.out.println("method 2");
	}
	
	@AfterAll
	public static void method3() {
		System.out.println("method 3");
	}
	
	@AfterEach
	public void method4() {
		System.out.println("method 4");
	}
	
	@Test
	public void test_hello() {
		String msg = "hello";
		assertEquals(msg, "hello", " message is equal Hello");
		System.out.println("");
	}

}
Running the above test would output the following. method1 and method2 would be executed before the actual test and then method4 and method3 would be executed.
Console Output
method 1 method 2 test_hello method 4 method 3

JUnit5 Writing first Test

JUnit 5 is the latest version of Junit. It has a brand new architecture and more capabilities compared to the previous generation of Junit. In this article, we will quickly go through some of the main features and concepts of JUnit 5. In this Article we will start with our first JUnit 5 Test.
SimpleHelloTest
First Junit5 Test. This test has only one test method which asserts that the message string is equal to "hello"
package com.bootng.start;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class SimpleHelloTest {

	@Test
	public void test_hello() {
		String msg = "hello";
		assertEquals(msg, "hello", " message is equal Hello");

	}

}
When running this test, the test will surely pass since the assert condition will be successfull.