递归逻辑健壮性测试需覆盖边界输入、深度压力、错误传播和异常注入四类场景:验证终止条件失效时抛出明确异常、最小合法输入结果正确、超限输入被拦截或降级;用参数化与超时熔断测试临界递归深度,并断言调用栈深度;通过精准 patch 验证错误传播路径;结合错误猜测与变异测试检验非法输入处理及故障补偿机制。

递归逻辑的健壮性测试,核心是验证它在边界、异常输入、深度压力和错误传播等非理想场景下不崩溃、不误算、不无限循环。这不是单纯跑通几个用例,而是构建一套覆盖“输入—执行—恢复”全链路的防御性验证体系。
覆盖三类关键边界输入
递归函数最脆弱的点往往不在主体逻辑,而在边界判定是否严密。必须显式测试:
- 终止条件失效场景:如 factorial(-1)、fibonacci(-5),验证是否抛出明确异常(如 ValueError),而非陷入无限递归或返回错误值;
- 最小合法输入:如 factorial(0)、factorial(1),确认基础情形结果正确且无冗余调用;
- 超限输入:如传入极大数触发 Python 默认递归限制(通常 1000 层),检查是否提前拦截(如参数校验)或优雅降级(如改用迭代 fallback),而非直接 RecursionError 导致进程中断。
模拟深度压力与资源约束
递归深度既是功能路径,也是性能与稳定性风险点:
- 用 pytest.mark.parametrize 覆盖临界深度:[1, 10, 999, 1000, 1001],而非均匀采样;
- 为每个深度用 @pytest.mark.timeout(0.1) 加装熔断保护,防止单个用例拖垮整个测试套件;
- 在函数内部通过 len(inspect.stack()) 断言实际调用栈深度,确认未因逻辑缺陷意外加深。
隔离递归调用,验证错误传播路径
当递归嵌套多层、依赖外部状态或副作用时,需解耦验证单层逻辑与整体容错行为:
- 用 patch.object 替换递归调用本身,例如让第 3 层固定返回异常,验证上层是否捕获并处理,而非静默失败;
- mock 的目标必须是被测模块中 import 的函数名,而非定义位置,否则 patch 失效;
- 每次 mock 后检查 mock_func.assert_called_once() 或调用次数,确保递归确实被跳过,逻辑验证真实有效。
注入异常输入与非法状态
健壮性测试不止看“能算对”,更要看“错得明白”:
- 用错误猜测法构造典型非法输入:空字符串、None、NaN、超长列表、嵌套过深的 JSON 等;
- 结合变异测试思想,对输入做微小扰动(如把数字 1 改为字符串 "1"、把 list 改为 tuple),观察是否触发类型检查或降级逻辑;
- 主动插入故障:如在递归中间层手动 raise 自定义异常,验证事务回滚、缓存清理、资源释放等补偿机制是否生效。











