In this article we will see how Junit 5 repeated tests works, how to use @RepeatedTest
, RepetitionInfo
in writing test cases, display custom names in writing repeated tests, how test methods execution order works with repeated tests and how to create a custom annotation using repeated tests with several examples.
1. Junit 5 repeated tests
@RepeatedTest
is used to signal that the annotated method is a test template method that should be repeated a specified number of times with a configurable display name.
1.1. @RepeatedTest example
The @RepeatedTest
test method is just like a regular @Test
method, the same life cycle. @RepeatedTest
methods must not be private
or static
and must return void
.
public class Junit5_RepeatedTest_Test { @RepeatedTest(1) static void test_Add() { System.out.println("test_Add()"); assertEquals(5, MathUtil.add(3, 2)); } @Test void test_Multiply() { System.out.println("test_Multiply()"); assertEquals(15, MathUtil.multiple(3, 5)); } @RepeatedTest(3) void test_Devide() { System.out.println("test_Devide()"); assertEquals(5, MathUtil.devide(25, 5)); } @RepeatedTest(2) void test_IsPrime() { System.out.println("test_IsPrime()"); assertTrue(MathUtil.isPrime(13)); } }
Output :
test_IsPrime() test_IsPrime() test_Devide() test_Devide() test_Devide() test_Multiply()
1.2. @RepeatedTest custom test name example
We can configure the custom name of the @RepeatedTest
method. Following are the place holders can be used to display custom names for Repeated tests Or we can use RepeatedTest.LONG_DISPLAY_NAME
or RepeatedTest.LONG_DISPLAY_NAME
.
{displayName}
: Name of the test method.{currentRepetition}
: The current repetition count.{totalRepetitions}
: The total number of repetitions.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) public class Junit5_RepeatedTest_CustomDisplayName_Test { @Test void test_Add() { System.out.println("test_Add()"); assertEquals(5, MathUtil.add(3, 2)); } @RepeatedTest(value = 1, name = RepeatedTest.SHORT_DISPLAY_NAME) void test_Multiply() { System.out.println("test_Multiply()"); assertEquals(15, MathUtil.multiple(3, 5)); } @RepeatedTest(value = 3, name = "{displayName} - {currentRepetition}/{totalRepetitions}") void test_Devide() { System.out.println("test_Devide()"); assertEquals(5, MathUtil.devide(25, 5)); } @RepeatedTest(value = 2, name = RepeatedTest.LONG_DISPLAY_NAME) void test_IsPrime() { System.out.println("test_IsPrime()"); assertTrue(MathUtil.isPrime(13)); } }
Results in Eclipse :
2. Injecting RepetitionInfo with example
RepetitionInfo
is used to inject information about the current repetition of a repeated test into@RepeatedTest
,@BeforeEach
,@AfterEach
methods.- If a method parameter is of type
RepetitionInfo
, JUnit will supply an instance ofRepetitionInfo
corresponding to the current repeated test as the value for the parameter. RepetitionInfo
cannot be injected into a@BeforeEach
or@AfterEach
method if the corresponding test method is not a@RepeatedTest
.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) public class Junit5_RepeatedTest_RepetitionInfo_Test { @BeforeEach void beforeEach(TestInfo testInfo, RepetitionInfo repetitionInfo) { int currentRepetition = repetitionInfo.getCurrentRepetition(); int totalRepetitions = repetitionInfo.getTotalRepetitions(); String methodName = testInfo.getTestMethod().get().getName(); System.out.println(String.format("About to execute repetition %d of %d for %s", // currentRepetition, totalRepetitions, methodName)); } @Test void test_Add(RepetitionInfo repetitionInfo) { System.out.println("test_Add()"); assertEquals(5, MathUtil.add(3, 2)); } @RepeatedTest(1) void test_Multiply() { System.out.println("test_Multiply()"); assertEquals(15, MathUtil.multiple(3, 5)); } @RepeatedTest(3) void test_Devide() { System.out.println("test_Devide()"); assertEquals(5, MathUtil.devide(25, 5)); } @RepeatedTest(2) void test_IsPrime(RepetitionInfo repetitionInfo) { assertEquals(2, repetitionInfo.getTotalRepetitions()); System.out.println("test_IsPrime()"); assertTrue(MathUtil.isPrime(13)); } }
Output :
About to execute repetition 1 of 2 for test_IsPrime test_IsPrime() About to execute repetition 2 of 2 for test_IsPrime test_IsPrime() About to execute repetition 1 of 3 for test_Devide test_Devide() About to execute repetition 2 of 3 for test_Devide test_Devide() About to execute repetition 3 of 3 for test_Devide test_Devide() About to execute repetition 1 of 1 for test_Multiply test_Multiply()
Results in Eclipse
3. Repeated tests method execution order
By default test methods order not defined, but Junit 5 algorithm ensures same method order for the subsequent tests runs by default. To control the order annotate your test class with @TestMethodOrder
.
@TestMethodOrder(Alphanumeric.class) public class Junit5_RepeatedTest_MethodOrder_Test { @RepeatedTest(1) static void test_Add() { System.out.println("test_Add()"); assertEquals(5, MathUtil.add(3, 2)); } @Test void test_Multiply() { System.out.println("test_Multiply()"); assertEquals(15, MathUtil.multiple(3, 5)); } @RepeatedTest(3) void test_Devide() { System.out.println("test_Devide()"); assertEquals(5, MathUtil.devide(25, 5)); } @RepeatedTest(2) void test_IsPrime() { System.out.println("test_IsPrime()"); assertTrue(MathUtil.isPrime(13)); } }
Output :
test_Devide() test_Devide() test_Devide() test_IsPrime() test_IsPrime() test_Multiply()
4. Create Custom RepeatedTest annotation
If we are using same number of repetitions, Junit 5 supports to create a custom annotation for repeated test annotation.
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @RepeatedTest(value = 3, name = "{displayName} - {currentRepetition}/{totalRepetitions}") public @interface MyRepeatedTest { }
public class Junit5_RepeatedTest_CustomAnnotation_Test { @MyRepeatedTest static void test_Add() { System.out.println("test_Add()"); assertEquals(5, MathUtil.add(3, 2)); } @MyRepeatedTest void test_Multiply() { System.out.println("test_Multiply()"); assertEquals(15, MathUtil.multiple(3, 5)); } @MyRepeatedTest void test_Devide() { System.out.println("test_Devide()"); assertEquals(5, MathUtil.devide(25, 5)); } @MyRepeatedTest void test_IsPrime() { System.out.println("test_IsPrime()"); assertTrue(MathUtil.isPrime(13)); } }
Output :
test_IsPrime() test_IsPrime() test_IsPrime() test_Devide() test_Devide() test_Devide() test_Multiply() test_Multiply() test_Multiply()
Conclusion
In this article we have seen how Junit 5 repeated tests works, how to use @RepeatedTest
, RepetitionInfo
in writing test cases, display custom names in writing repeated tests, how test methods execution order works with repeated tests and how to create a custom annotation using repeated tests with several examples.
You also might be interested in following examples :
- Junit 5 Dynamic Tests
- Junit 5 tags and filter test cases
- Junit 5 Timeout tests
- Junit 5 test order
- Junit 5 parameterized tests
- Junit 5 Parameter Resolvers
“@RepeatedTest methods must not be private or static and must return void.”
But as I saw its a static method, can you clarify it? Thanks!
Yes, In Junit 5 @RepeatedTest or @Test methods must not be private or static and must return void. Otherwise those methods will not be treated as test method and being silently ignored by Junit Platform test engine without any error. They can be considered as regular static/private methods within a test class.