参数化测试是什么
JUnit 5 的 @ParameterizedTest 让同一段测试逻辑按数据源自动展开为多次独立执行:每组数据是一条用例,在报告中单独列出、可单独定位失败。它替代了过去「复制多个 @Test 只改入参」的写法,把输入与断言逻辑分离。常见数据源:@ValueSource 单值列表、@CsvSource 表格化数据、@MethodSource 复杂对象、@EnumSource 枚举遍历。依赖为 junit-jupiter-params(聚合依赖 junit-jupiter 已包含)。
基本信息
| 适用平台 | Java 8+,JUnit 5(Jupiter API) |
|---|---|
| 依赖 | org.junit.jupiter:junit-jupiter-params |
| 常用注解 | @ParameterizedTest、@ValueSource、@CsvSource、@MethodSource、@EnumSource |
| 报告行为 | 每组数据计为一次执行,失败可定位到具体一组 |
典型使用场景
- 同一业务规则的批量回归:金额校验、日期解析、编码转换等输入集
- 边界与等价类打包成表:最小值、最大值、零、负数各占一行
- 用 @EnumSource 遍历全部枚举值,防止新增枚举漏测
- 数据由工厂或外部读取:@MethodSource 返回 Stream 或集合
- 配合 name 模板给每组数据生成可读用例名,报告可扫读
参数化示例
参数化示例
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
@ParameterizedTest(name = "{0} -> {1}") // 用参数值拼出可读用例名
@CsvSource({
"1, 2",
"2, 4",
"9, 18",
"0, 0", // 零值显式成行,不靠默认值覆盖
"-3, -6",
})
void doubleValue(int input, int expected) {
assertEquals(expected, doubleIt(input));
}数据源对照
| 注解 | 入参形式 | 适用 |
|---|---|---|
| @ValueSource | 单类型数组(ints、strings 等) | 单参数、有限取值 |
| @CsvSource | 每行一条逗号分隔记录 | 多参数、表格化数据 |
| @MethodSource | 静态方法返回 Stream/集合 | 复杂对象、动态生成 |
| @EnumSource | 枚举类,可按名字筛选 | 枚举全量或子集遍历 |
| @ArgumentsSource | 自定义 ArgumentsProvider | 复用统一数据提供逻辑 |
每一行数据独立执行、独立计分:一行失败不影响其余行,失败信息直接带上该组参数,排查比循环断言快得多。
@MethodSource 引用的方法默认必须是 static,且返回 Stream、Iterable 或数组等类型;方法名拼错或非静态时会报「找不到数据源」,错误信息较隐晦。
数据来源不止注解内联:@CsvFileSource 可读取 classpath 下的 CSV 文件,@ArgumentsSource 可挂接自定义提供器;把数据文件与断言逻辑分离后,业务同事也能补充用例数据。