重复测试

JUnit Jupiter通过使用@RepeatedTest注解方法并指定所需的重复次数,提供了重复测试指定次数的功能。每次重复测试的调用都像执行常规的@Test方法一样,完全支持相同的生命周期回调和扩展。

以下示例演示了如何声明名为repeatedTest()的测试,该测试将自动重复10次。

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

除了指定重复次数外,还可以通过@RepeatedTest注解的name属性为每次重复配置自定义显示名称。此外,显示名称可以是模式,由静态文本和动态占位符的组合而成。目前支持以下占位符:

  • {displayName}: @RepeatedTest方法的显示名称

  • {currentRepetition}: 当前重复次数

  • {totalRepetitions}: 重复的总次数

给定重复的默认显示名称基于以下模式生成:"repetition {currentRepetition} of {totalRepetitions}"。 因此,前面的repeatedTest()示例的单个重复的显示名称将是:repetition 1 of 10, repetition 2 of 10等等。如果您希望每个重复的名称中包含@RepeatedTest方法的显示名称,您可以定义自己的自定义模式或使用预定义的RepeatedTest.LONG_DISPLAY_NAME模式。后者相当于"{displayName} :: repetition {currentRepetition} of {totalRepetitions}",这会导致重复测试的显示名称变成这样:repeatedTest() :: repetition 1 of 10, repeatedTest() :: repetition 2 of 10等。

为了以编程方式获取有关当前重复和总重复次数的信息,开发人员可以选择将RepetitionInfo的实例注入@RepeatedTest@BeforeEach@AfterEach方法。

重复测试示例

本节末尾的RepeatedTestsDemo类将演示重复测试的几个示例。

repeatedTest()方法与上一节中的示例相同; 而repeatedTestWithRepetitionInfo()演示了如何将RepetitionInfo的实例注入到测试中,以获取当前重复测试的总重复次数。

接下来的两个方法演示了如何在每个重复的显示名称中包含@RepeatedTest方法的自定义@DisplayNamecustomDisplayName()用自定义模式组合自定义显示名称,然后使用TestInfo来验证生成的显示名称的格式。Repeat!是来自@DisplayName,来自{displayName}声明,1/1来自{currentRepetition}/{totalRepetitions}。相反,customDisplayNameWithLongPattern()使用前面提到的预定义的RepeatedTest.LONG_DISPLAY_NAME模式。

repeatedTestInGerman()展示了将重复测试的显示名称翻译成外语的能力 - 在这种情况下是德语,从而得到单个重复的名称,例如:Wiederholung 1 von 5Wiederholung 2 von 5等。

由于beforeEach()方法用@BeforeEach标注,所以在每次重复测试之前都会执行它。通过将TestInfoRepetitionInfo注入到方法中,我们可以看到,有可能获得有关当前正在执行的重复测试的信息。在启用了INFO日志级别的情况下,执行RepeatedTestsDemo会得到以下输出。

  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(testInfo.getDisplayName(), "Repeat! 1/1");
  30. }
  31. @RepeatedTest(value = 1, name = RepeatedTest.LONG_DISPLAY_NAME)
  32. @DisplayName("Details...")
  33. void customDisplayNameWithLongPattern(TestInfo testInfo) {
  34. assertEquals(testInfo.getDisplayName(), "Details... :: repetition 1 of 1");
  35. }
  36. @RepeatedTest(value = 5, name = "Wiederholung {currentRepetition} von {totalRepetitions}")
  37. void repeatedTestInGerman() {
  38. // ...
  39. }
  40. }

在启用了unicode主题的情况下,使用ConsoleLauncherjunitPlatformTest Gradle插件时,执行RepeatedTestsDemo会将以下输出给控制台。

  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