参数化测试每组参数到底算几次测试?CSV 里的引号和 null 怎么写?类型转换失败、参数个数不对、来源是空的会发生什么?每次调用有没有新实例和 @BeforeEach?这篇逐个运行,看树形输出里的真实显示名。
@ValueSource(ints = {1, 2, 3})
[BeforeEach] 实例 #1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
[BeforeEach] 实例 #3
[AfterEach] 实例 #3
│ └─ PT ✔
│ └─ valueSource(int) ✔
│ ├─ [1] 1 ✔
│ ├─ [2] 2 ✔
│ └─ [3] 3 ✔
汇总:3 tests found ] | 3 tests successful ] | 0 tests failed ]
@CsvSource + name = "[{index}] {0} + {1} = {2}",第三行故意写错
[BeforeEach] 实例 #1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
[BeforeEach] 实例 #3
[AfterEach] 实例 #3
[BeforeEach] 实例 #4
[AfterEach] 实例 #4
│ └─ PT ✔
│ └─ csv(int, int, int) ✔
│ ├─ [1] 1 + 2 = 3 ✔
│ ├─ [2] 4 + 5 = 9 ✔
│ ├─ [3] 10 + 20 = 31 ✘ expected: <31> but was: <30>
│ └─ [4] 7 + 0 = 7 ✔
Failures (1):
MethodSource [className = 'PT', methodName = 'csv', methodParameterTypes = 'int, int, int']
=> org.opentest4j.AssertionFailedError: expected: <31> but was: <30>
汇总:4 tests found ] | 3 tests successful ] | 1 tests failed ]
@CsvSource 的引号、nullValues 与空串
[BeforeEach] 实例 #1
收到 s=[apple] n=1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
收到 s=[banana, ripe] n=2
[AfterEach] 实例 #2
[BeforeEach] 实例 #3
收到 s=null n=3
[AfterEach] 实例 #3
[BeforeEach] 实例 #4
收到 s=[] n=4
[AfterEach] 实例 #4
[BeforeEach] 实例 #5
收到 s=null n=5
[AfterEach] 实例 #5
│ └─ PT ✔
│ └─ csvQuoting(String, int) ✔
│ ├─ [1] apple, 1 ✔
│ ├─ [2] banana, ripe, 2 ✔
│ ├─ [3] null, 3 ✔
│ ├─ [4] , 4 ✔
│ └─ [5] null, 5 ✔
汇总:5 tests found ] | 5 tests successful ] | 0 tests failed ]
@EnumSource(names = SECONDS, MINUTES)
[BeforeEach] 实例 #1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ enumSource(TimeUnit) ✔
│ ├─ [1] SECONDS ✔
│ └─ [2] MINUTES ✔
汇总:2 tests found ] | 2 tests successful ] | 0 tests failed ]
@EnumSource(mode = EXCLUDE, 排除前五个)
[BeforeEach] 实例 #1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ enumExclude(TimeUnit) ✔
│ ├─ [1] HOURS ✔
│ └─ [2] DAYS ✔
汇总:2 tests found ] | 2 tests successful ] | 0 tests failed ]
@MethodSource
[MethodSource 工厂方法被调用]
[BeforeEach] 实例 #1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ methodSource(String, int) ✔
│ ├─ [1] a, 1 ✔
│ └─ [2] bb, 2 ✔
汇总:2 tests found ] | 2 tests successful ] | 0 tests failed ]
@NullSource + @EmptySource + @ValueSource
[BeforeEach] 实例 #1
收到 null
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
收到 []
[AfterEach] 实例 #2
[BeforeEach] 实例 #3
收到 [ ]
[AfterEach] 实例 #3
[BeforeEach] 实例 #4
收到 [x]
[AfterEach] 实例 #4
│ └─ PT ✔
│ └─ nullEmpty(String) ✔
│ ├─ [1] null ✔
│ ├─ [2] ✔
│ ├─ [3] ✔
│ └─ [4] x ✔
汇总:4 tests found ] | 4 tests successful ] | 0 tests failed ] 隐式转换 String → LocalDate
[BeforeEach] 实例 #1
隐式转换 String → LocalDate:2024-02-29
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
隐式转换 String → LocalDate:2023-12-31
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ implicitConversion(LocalDate) ✔
│ ├─ [1] 2024-02-29 ✔
│ └─ [2] 2023-12-31 ✔
汇总:2 tests found ] | 2 tests successful ] | 0 tests failed ]
转换失败:"abc" → double
[BeforeEach] 实例 #1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ badConversion(double) ✔
│ ├─ [1] 3.14 ✔
│ └─ [2] abc ✘ Error converting parameter at index 0: Failed to convert String "abc" to type double
Failures (1):
MethodSource [className = 'PT', methodName = 'badConversion', methodParameterTypes = 'double']
=> org.junit.jupiter.api.extension.ParameterResolutionException: Error converting parameter at index 0: Failed to convert String "abc" to type double
Caused by: org.junit.jupiter.params.converter.ArgumentConversionException: Failed to convert String "abc" to type double
Caused by: org.junit.platform.commons.support.conversion.ConversionException: Failed to convert String "abc" to type double
Caused by: java.lang.NumberFormatException: For input string: "abc"
汇总:2 tests found ] | 1 tests successful ] | 1 tests failed ]
ArgumentsAccessor 聚合
[BeforeEach] 实例 #1
ArgumentsAccessor:alice,30,true(共 3 个)
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
ArgumentsAccessor:bob,25,false(共 3 个)
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ aggregation(ArgumentsAccessor) ✔
│ ├─ [1] alice, 30, true ✔
│ └─ [2] bob, 25, false ✔
汇总:2 tests found ] | 2 tests successful ] | 0 tests failed ]
显式 @ConvertWith
[BeforeEach] 实例 #1
显式转换器得到 Person[name=alice, age=0]
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
显式转换器得到 Person[name=bob, age=0]
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ explicitConverter(Person) ✔
│ ├─ [1] alice ✔
│ └─ [2] bob ✔
汇总:2 tests found ] | 2 tests successful ] | 0 tests failed ]
方法参数比来源多(两个参数、来源只有一个值)
[BeforeEach] 实例 #1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ tooMany(int, int) ✔
│ ├─ [1] 1 ✘ No ParameterResolver registered for parameter [int arg1] in method [void PT.tooMany(int,int)].
│ └─ [2] 2 ✘ No ParameterResolver registered for parameter [int arg1] in method [void PT.tooMany(int,int)].
Failures (2):
MethodSource [className = 'PT', methodName = 'tooMany', methodParameterTypes = 'int, int']
=> org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [int arg1] in method [void PT.tooMany(int,int)].
MethodSource [className = 'PT', methodName = 'tooMany', methodParameterTypes = 'int, int']
=> org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [int arg1] in method [void PT.tooMany(int,int)].
汇总:2 tests found ] | 0 tests successful ] | 2 tests failed ]
来源为空
│ └─ PT ✔
│ └─ emptySource(int) ✘ Exactly one type of input must be provided in the @ValueSource annotation, but there were 0
Failures (1):
MethodSource [className = 'PT', methodName = 'emptySource', methodParameterTypes = 'int']
=> org.junit.platform.commons.PreconditionViolationException: Exactly one type of input must be provided in the @ValueSource annotation, but there were 0
汇总:0 tests found ] | 0 tests successful ] | 0 tests failed ] 一次调用失败(n == 2)
[BeforeEach] 实例 #1
n=1 通过
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
[AfterEach] 实例 #2
[BeforeEach] 实例 #3
n=3 通过
[AfterEach] 实例 #3
│ └─ PT ✔
│ └─ oneFails(int) ✔
│ ├─ [1] 1 ✔
│ ├─ [2] 2 ✘ n 不能是 2 ==> expected: <true> but was: <false>
│ └─ [3] 3 ✔
Failures (1):
MethodSource [className = 'PT', methodName = 'oneFails', methodParameterTypes = 'int']
=> org.opentest4j.AssertionFailedError: n 不能是 2 ==> expected: <true> but was: <false>
汇总:3 tests found ] | 2 tests successful ] | 1 tests failed ]
每次调用都有新的测试类实例 #id 与 BeforeEach / AfterEach(@ValueSource(ints={1,2}) + TestInfo)
[BeforeEach] 实例 #1
TestInfo 参数:[1] 1
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
TestInfo 参数:[2] 2
[AfterEach] 实例 #2
│ └─ PT ✔
│ └─ withInfo(int, TestInfo) ✔
│ ├─ [1] 1 ✔
│ └─ [2] 2 ✔
汇总:2 tests found ] | 2 tests successful ] | 0 tests failed ]
@RepeatedTest(3)
[BeforeEach] 实例 #1
重复 1/3
[AfterEach] 实例 #1
[BeforeEach] 实例 #2
重复 2/3
[AfterEach] 实例 #2
[BeforeEach] 实例 #3
重复 3/3
[AfterEach] 实例 #3
│ └─ PT ✔
│ └─ repeated(RepetitionInfo) ✔
│ ├─ repetition 1 of 3 ✔
│ ├─ repetition 2 of 3 ✔
│ └─ repetition 3 of 3 ✔
汇总:3 tests found ] | 3 tests successful ] | 0 tests failed ]