单元测试用例生成的目标是用尽可能少的用例,覆盖代码中的关键逻辑、边界条件和异常路径,帮助开发者在代码变更后快速获得反馈。实际的用例生成通常结合等价类划分、边界值分析和逻辑覆盖等方法,既不冗余,也不遗漏重要场景。
1. 从函数的输入输出出发
先明确被测函数的功能、参数类型和返回值。以计算折扣的函数 double calcDiscount(double price, boolean isVip) 为例:
- 普通会员满200减20,不满200不打折;
- VIP会员满200减50,不满200打9折。
确定等价类:价格 < 0(无效)、0 ≤ price < 200、price ≥ 200,以及 isVip 的 true/false。组合后可筛选出有效等价类,并为每个有效类设计一个典型用例。
2. 关注边界值
边界容易出错,需要专门设计用例。在上例中,price 的边界为 0、199.99、200、200.01,以及负数边界。为每个边界结合两种会员状态生成用例,例如:
- (199.99, false) → 期望 199.99
- (200.00, false) → 期望 180.00
- (199.99, true) → 期望 179.99 (9折)
- (200.00, true) → 期望 150.00
3. 覆盖异常和非法输入
如果代码内对非法输入有检查(如抛出异常或返回错误码),则必须覆盖这些路径。例如 price < 0 或参数为 null 的情况,需要用一个用例触发并验证预期的异常行为。
4. 利用工具辅助生成
现代 IDE(如 IntelliJ IDEA、VS Code)和测试框架(JUnit、pytest)支持自动生成测试方法骨架,开发者只需填写参数和断言。对于重复性高的验证,可以编写参数化测试,用一组输入数据驱动同一个测试逻辑,减少模板代码。
5. 用例表格示例(简洁写法)
在实际项目中,可以用表格梳理用例,再转成代码:
| 用例编号 | price | isVip | 预期结果 |
|----------|--------|-------|----------|
| TC01 | -10 | false | 抛出异常 |
| TC02 | 0 | false | 0 |
| TC03 | 199.99 | false | 199.99 |
| TC04 | 200 | false | 180 |
| TC05 | 0 | true | 0 |
| TC06 | 199.99 | true | 179.991 |
| TC07 | 200 | true | 150 |
6. 真实场景的取舍
时间有限时,优先覆盖主流程、高频调用路径和已知易错点。对于自动生成的用例,必须由开发者审查断言是否合理,避免“假通过”的测试。结合代码覆盖率工具(如 JaCoCo、Coverage.py)查看未覆盖的分支,针对性补充用例,而不是盲目追求 100% 覆盖率。
通过以上步骤,可以用适度的用例数量构建出一套可靠、可维护的单元测试集合,有效降低回归风险。