2.14. Repeated Tests

JUnit Jupiter provides the ability to repeat a test a specified number of times by annotating a method with @RepeatedTest and specifying the total number of repetitions desired. Each invocation of a repeated test behaves like the execution of a regular @Test method with full support for the same lifecycle callbacks and extensions.

The following example demonstrates how to declare a test named repeatedTest() that will be automatically repeated 10 times.

  1. @RepeatedTest(10)
  2. void repeatedTest() {
  3. // ...
  4. }

In addition to specifying the number of repetitions, a custom display name can be configured for each repetition via the name attribute of the @RepeatedTest annotation. Furthermore, the display name can be a pattern composed of a combination of static text and dynamic placeholders. The following placeholders are currently supported.

  • [DisplayName](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/MethodOrderer.DisplayName.html): display name of the @RepeatedTest method

  • {currentRepetition}: the current repetition count

  • {totalRepetitions}: the total number of repetitions

The default display name for a given repetition is generated based on the following pattern: "repetition {currentRepetition} of {totalRepetitions}". Thus, the display names for individual repetitions of the previous repeatedTest() example would be: repetition 1 of 10, repetition 2 of 10, etc. If you would like the display name of the @RepeatedTest method included in the name of each repetition, you can define your own custom pattern or use the predefined RepeatedTest.LONG_DISPLAY_NAME pattern. The latter is equal to "[DisplayName](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/MethodOrderer.DisplayName.html) :: repetition {currentRepetition} of {totalRepetitions}" which results in display names for individual repetitions like repeatedTest() :: repetition 1 of 10, repeatedTest() :: repetition 2 of 10, etc.

In order to retrieve information about the current repetition and the total number of repetitions programmatically, a developer can choose to have an instance of RepetitionInfo injected into a @RepeatedTest, @BeforeEach, or @AfterEach method.

2.14.1. Repeated Test Examples

The RepeatedTestsDemo class at the end of this section demonstrates several examples of repeated tests.

The repeatedTest() method is identical to example from the previous section; whereas, repeatedTestWithRepetitionInfo() demonstrates how to have an instance of RepetitionInfo injected into a test to access the total number of repetitions for the current repeated test.

The next two methods demonstrate how to include a custom @DisplayName for the @RepeatedTest method in the display name of each repetition. customDisplayName() combines a custom display name with a custom pattern and then uses TestInfo to verify the format of the generated display name. Repeat! is the [DisplayName](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/MethodOrderer.DisplayName.html) which comes from the @DisplayName declaration, and 1/1 comes from {currentRepetition}/{totalRepetitions}. In contrast, customDisplayNameWithLongPattern() uses the aforementioned predefined RepeatedTest.LONG_DISPLAY_NAME pattern.

repeatedTestInGerman() demonstrates the ability to translate display names of repeated tests into foreign languages — in this case German, resulting in names for individual repetitions such as: Wiederholung 1 von 5, Wiederholung 2 von 5, etc.

Since the beforeEach() method is annotated with @BeforeEach it will get executed before each repetition of each repeated test. By having the TestInfo and RepetitionInfo injected into the method, we see that it’s possible to obtain information about the currently executing repeated test. Executing RepeatedTestsDemo with the INFO log level enabled results in the following output.

  1. INFO: About to execute repetition 1 of 10 for repeatedTest
  2. INFO: About to execute repetition 2 of 10 for repeatedTest
  3. INFO: About to execute repetition 3 of 10 for repeatedTest
  4. INFO: About to execute repetition 4 of 10 for repeatedTest
  5. INFO: About to execute repetition 5 of 10 for repeatedTest
  6. INFO: About to execute repetition 6 of 10 for repeatedTest
  7. INFO: About to execute repetition 7 of 10 for repeatedTest
  8. INFO: About to execute repetition 8 of 10 for repeatedTest
  9. INFO: About to execute repetition 9 of 10 for repeatedTest
  10. INFO: About to execute repetition 10 of 10 for repeatedTest
  11. INFO: About to execute repetition 1 of 5 for repeatedTestWithRepetitionInfo
  12. INFO: About to execute repetition 2 of 5 for repeatedTestWithRepetitionInfo
  13. INFO: About to execute repetition 3 of 5 for repeatedTestWithRepetitionInfo
  14. INFO: About to execute repetition 4 of 5 for repeatedTestWithRepetitionInfo
  15. INFO: About to execute repetition 5 of 5 for repeatedTestWithRepetitionInfo
  16. INFO: About to execute repetition 1 of 1 for customDisplayName
  17. INFO: About to execute repetition 1 of 1 for customDisplayNameWithLongPattern
  18. INFO: About to execute repetition 1 of 5 for repeatedTestInGerman
  19. INFO: About to execute repetition 2 of 5 for repeatedTestInGerman
  20. INFO: About to execute repetition 3 of 5 for repeatedTestInGerman
  21. INFO: About to execute repetition 4 of 5 for repeatedTestInGerman
  22. INFO: About to execute repetition 5 of 5 for repeatedTestInGerman
  1. import static org.junit.jupiter.api.Assertions.assertEquals;
  2. import java.util.logging.Logger;
  3. import org.junit.jupiter.api.BeforeEach;
  4. import org.junit.jupiter.api.DisplayName;
  5. import org.junit.jupiter.api.RepeatedTest;
  6. import org.junit.jupiter.api.RepetitionInfo;
  7. import org.junit.jupiter.api.TestInfo;
  8. class RepeatedTestsDemo {
  9. private Logger logger = // ...
  10. @BeforeEach
  11. void beforeEach(TestInfo testInfo, RepetitionInfo repetitionInfo) {
  12. int currentRepetition = repetitionInfo.getCurrentRepetition();
  13. int totalRepetitions = repetitionInfo.getTotalRepetitions();
  14. String methodName = testInfo.getTestMethod().get().getName();
  15. logger.info(String.format("About to execute repetition %d of %d for %s", //
  16. currentRepetition, totalRepetitions, methodName));
  17. }
  18. @RepeatedTest(10)
  19. void repeatedTest() {
  20. // ...
  21. }
  22. @RepeatedTest(5)
  23. void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
  24. assertEquals(5, repetitionInfo.getTotalRepetitions());
  25. }
  26. @RepeatedTest(value = 1, name = "{displayName} {currentRepetition}/{totalRepetitions}")
  27. @DisplayName("Repeat!")
  28. void customDisplayName(TestInfo testInfo) {
  29. assertEquals("Repeat! 1/1", testInfo.getDisplayName());
  30. }
  31. @RepeatedTest(value = 1, name = RepeatedTest.LONG_DISPLAY_NAME)
  32. @DisplayName("Details...")
  33. void customDisplayNameWithLongPattern(TestInfo testInfo) {
  34. assertEquals("Details... :: repetition 1 of 1", testInfo.getDisplayName());
  35. }
  36. @RepeatedTest(value = 5, name = "Wiederholung {currentRepetition} von {totalRepetitions}")
  37. void repeatedTestInGerman() {
  38. // ...
  39. }
  40. }

When using the ConsoleLauncher with the unicode theme enabled, execution of RepeatedTestsDemo results in the following output to the console.

  1. ├─ RepeatedTestsDemo
  2. ├─ repeatedTest()
  3. ├─ repetition 1 of 10
  4. ├─ repetition 2 of 10
  5. ├─ repetition 3 of 10
  6. ├─ repetition 4 of 10
  7. ├─ repetition 5 of 10
  8. ├─ repetition 6 of 10
  9. ├─ repetition 7 of 10
  10. ├─ repetition 8 of 10
  11. ├─ repetition 9 of 10
  12. └─ repetition 10 of 10
  13. ├─ repeatedTestWithRepetitionInfo(RepetitionInfo)
  14. ├─ repetition 1 of 5
  15. ├─ repetition 2 of 5
  16. ├─ repetition 3 of 5
  17. ├─ repetition 4 of 5
  18. └─ repetition 5 of 5
  19. ├─ Repeat!
  20. └─ Repeat! 1/1
  21. ├─ Details...
  22. └─ Details... :: repetition 1 of 1
  23. └─ repeatedTestInGerman()
  24. ├─ Wiederholung 1 von 5
  25. ├─ Wiederholung 2 von 5
  26. ├─ Wiederholung 3 von 5
  27. ├─ Wiederholung 4 von 5
  28. └─ Wiederholung 5 von 5