In this article, we are going to look at the @RepeatedTest annotation introduced in JUnit 5.
The @RepeatedTest annotation provides us with a powerful way to write any test that we want to repeat several times.
The @RepeatedTest annotation provides us with a powerful way to write any test that we want to repeat several times.
Simple @RepeatedTest Example
Creating a repeated test is simple – just add the @RepeatedTest annotation on top of the test method:
@RepeatedTest(3)
void repeatedTest(TestInfo testInfo) {
System.out.println("Executing repeated test");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
Note that instead of standard @Test annotation, we are using @RepeatedTest for our unit test. The above test will be executed three times as if the same test was written three times.
Output: The test reports (the report files or the results in the JUnit tab of your IDE) will display all the executions:
repetition 1 of 3(repeatedTest(TestInfo))
repetition 2 of 3(repeatedTest(TestInfo))
repetition 3 of 3(repeatedTest(TestInfo))
@RepeatedTest(3)
void repeatedTest(TestInfo testInfo) {
System.out.println("Executing repeated test");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
repetition 1 of 3(repeatedTest(TestInfo))
repetition 2 of 3(repeatedTest(TestInfo))
repetition 3 of 3(repeatedTest(TestInfo))
Lifecycle Support for @RepeatedTest
Each execution of the @RepeatedTest will behave like a regular @Test having full JUnit test life cycle support. Meaning that, during each execution, the @BeforeEach and @AfterEach methods will be called. To demonstrate this, just add the appropriate methods in the test class:
@BeforeEach
void beforeEachTest() {
System.out.println("Before Each Test");
}
@AfterEach
void afterEachTest() {
System.out.println("After Each Test");
System.out.println("=====================");
}
If we run our previous test, the results will be displayed on the console:
Before Each Test
Executing repeated test
After Each Test
=====================
Before Each Test
Executing repeated test
After Each Test
=====================
Before Each Test
Executing repeated test
After Each Test
=====================
As we can see, the @BeforeEach and @AfterEach methods are called around each execution.
@BeforeEach
void beforeEachTest() {
System.out.println("Before Each Test");
}
@AfterEach
void afterEachTest() {
System.out.println("After Each Test");
System.out.println("=====================");
}
Before Each Test
Executing repeated test
After Each Test
=====================
Before Each Test
Executing repeated test
After Each Test
=====================
Before Each Test
Executing repeated test
After Each Test
=====================
Configuring the Test Name
In the first example, we have observed that the output of the test report does not contain any identifiers. This can be configured further using the name attribute:
@RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME)
void repeatedTestWithLongName() {
System.out.println("Executing repeated test with long name");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
The output will now contain the method name along with the repetition index:
repeatedTestWithLongName() :: repetition 1 of 3(repeatedTestWithLongName())
repeatedTestWithLongName() :: repetition 2 of 3(repeatedTestWithLongName())
repeatedTestWithLongName() :: repetition 3 of 3(repeatedTestWithLongName())
Another option is to use RepeatedTest.SHORT_DISPLAY_NAME which will produce the short name of the test:
repetition 1 of 3(repeatedTestWithShortName())
repetition 2 of 3(repeatedTestWithShortName())
repetition 3 of 3(repeatedTestWithShortName())
If however, we need to use our customized name, it is very much possible:
@RepeatedTest(value = 3, name = "Custom name {currentRepetition}/{totalRepetitions}")
void repeatedTestWithCustomDisplayName(TestInfo testInfo) {
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
The {currentRepetition} and {totalRepetitions} are the placeholders for the current repetition and the total number of repetitions. These values are automatically provided by JUnit at the runtime, and no additional configuration is required. The output is pretty much what we expected:
Custom name 1/3(repeatedTestWithCustomDisplayName())
Custom name 2/3(repeatedTestWithCustomDisplayName())
Custom name 3/3(repeatedTestWithCustomDisplayName())
@RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME)
void repeatedTestWithLongName() {
System.out.println("Executing repeated test with long name");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
repeatedTestWithLongName() :: repetition 1 of 3(repeatedTestWithLongName())
repeatedTestWithLongName() :: repetition 2 of 3(repeatedTestWithLongName())
repeatedTestWithLongName() :: repetition 3 of 3(repeatedTestWithLongName())
repetition 1 of 3(repeatedTestWithShortName())
repetition 2 of 3(repeatedTestWithShortName())
repetition 3 of 3(repeatedTestWithShortName())
@RepeatedTest(value = 3, name = "Custom name {currentRepetition}/{totalRepetitions}")
void repeatedTestWithCustomDisplayName(TestInfo testInfo) {
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
Custom name 1/3(repeatedTestWithCustomDisplayName())
Custom name 2/3(repeatedTestWithCustomDisplayName())
Custom name 3/3(repeatedTestWithCustomDisplayName())
Accessing the RepetitionInfo
Apart from the name attribute, JUnit provides access to the repetition metadata in our test code as well. This is achieved by adding a RepetitionInfo parameter to our test method:
@RepeatedTest(3)
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
System.out.println("Repetition #" + repetitionInfo.getCurrentRepetition());
assertEquals(3, repetitionInfo.getTotalRepetitions());
}
The output will contain the current repetition index for each of the execution:
Repetition #1
Repetition #2
Repetition #3
The RepetitionInfo is provided by RepetitionInfoParameterResolver and is available only in the context of @RepeatedTest.
@RepeatedTest(3)
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
System.out.println("Repetition #" + repetitionInfo.getCurrentRepetition());
assertEquals(3, repetitionInfo.getTotalRepetitions());
}
Repetition #1
Repetition #2
Repetition #3
Complete Example for Reference
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.TestInfo;
public class RepeatedTestExample {
@BeforeEach
void beforeEachTest() {
System.out.println("Before Each Test");
}
@AfterEach
void afterEachTest() {
System.out.println("After Each Test");
System.out.println("=====================");
}
@RepeatedTest(3)
void repeatedTest(TestInfo testInfo) {
System.out.println("Executing repeated test");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME)
void repeatedTestWithLongName() {
System.out.println("Executing repeated test with long name");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(value = 3, name = RepeatedTest.SHORT_DISPLAY_NAME)
void repeatedTestWithShortName() {
System.out.println("Executing repeated test with long name");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(value = 3, name = "Custom name {currentRepetition}/{totalRepetitions}")
void repeatedTestWithCustomDisplayName() {
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(3)
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
System.out.println("Repetition #" + repetitionInfo.getCurrentRepetition());
assertEquals(3, repetitionInfo.getTotalRepetitions());
}
}
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.TestInfo;
public class RepeatedTestExample {
@BeforeEach
void beforeEachTest() {
System.out.println("Before Each Test");
}
@AfterEach
void afterEachTest() {
System.out.println("After Each Test");
System.out.println("=====================");
}
@RepeatedTest(3)
void repeatedTest(TestInfo testInfo) {
System.out.println("Executing repeated test");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME)
void repeatedTestWithLongName() {
System.out.println("Executing repeated test with long name");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(value = 3, name = RepeatedTest.SHORT_DISPLAY_NAME)
void repeatedTestWithShortName() {
System.out.println("Executing repeated test with long name");
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(value = 3, name = "Custom name {currentRepetition}/{totalRepetitions}")
void repeatedTestWithCustomDisplayName() {
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
}
@RepeatedTest(3)
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
System.out.println("Repetition #" + repetitionInfo.getCurrentRepetition());
assertEquals(3, repetitionInfo.getTotalRepetitions());
}
}
Conclusion
In this tutorial, we have explored the @RepeatedTest annotation provided by JUnit 5 and learned different ways of configuring it.
The source code for this post is available on GitHub
JUnit 5 Related Posts
- Overview of JUnit 5
- JUnit 5 Maven Example
- JUnit 5 Standard Test Class Basic Template
- JUnit 5 Annotations with Examples
- JUnit 5 Assertions with Examples
- JUnit 5 Nested Tests Example
- JUnit 5 Disabling Tests Examples
- JUnit 5 Display Names Example
- JUnit 5 Repeated Tests with Examples
- JUnit 5 Exception Testing with Example
- Overview of JUnit 5
- JUnit 5 Maven Example
- JUnit 5 Standard Test Class Basic Template
- JUnit 5 Annotations with Examples
- JUnit 5 Assertions with Examples
- JUnit 5 Nested Tests Example
- JUnit 5 Disabling Tests Examples
- JUnit 5 Display Names Example
- JUnit 5 Repeated Tests with Examples
- JUnit 5 Exception Testing with Example
Comments
Post a Comment
Leave Comment