如何使用pytest测试含默认参数的Python函数所有调用排列组合
解决方案
方案1:参数化关键字参数字典(原生pytest,无额外依赖)
直接将需要传入的关键字参数作为参数化项,完全避免分支判断,逻辑统一简洁:
import pytest @pytest.mark.parametrize("a", [1,2,3]) @pytest.mark.parametrize("b_kwargs", [{}, {"b":1}, {"b":2}, {"b":3}]) def test_foo(a, b_kwargs): foo(a, **b_kwargs)
空字典对应不传b的场景,自动触发默认值,带键值对的字典对应显式传b的场景,所有调用逻辑完全一致,参数语义也非常清晰。
如果函数后续新增更多带默认值的关键字参数,只需要扩展b_kwargs的参数化项即可,不用修改测试逻辑。如果参数数量多不想手动写排列组合,也可以配合itertools.product自动生成所有参数组合:
import itertools a_list = [1,2,3] b_kwargs_list = [{}, {"b":1}, {"b":2}, {"b":3}] test_cases = list(itertools.product(a_list, b_kwargs_list)) @pytest.mark.parametrize("a, b_kwargs", test_cases) def test_foo(a, b_kwargs): foo(a, **b_kwargs)
方案2:自定义哨兵值优化分支判断
如果你担心None可能是b的合法入参(比如函数本身允许b传None),可以自定义专属哨兵值避免逻辑冲突,比原来用None判断的写法更严谨:
# 定义全局唯一的哨兵值,和所有合法入参都不会重复 USE_DEFAULT = object() @pytest.mark.parametrize("a", [1,2,3]) @pytest.mark.parametrize("b", [1,2,3, USE_DEFAULT]) def test_foo(a, b): if b is USE_DEFAULT: foo(a) else: foo(a, b=b)
内容的提问来源于stack exchange,提问作者CIsForCookies
相关产品推荐
相关产品推荐

