pytest循环定义测试用例遭遇晚绑定仅收集最后一个函数问题求解
问题根因
你遇到的问题有两个核心原因:
- 测试函数重名覆盖:循环内每次定义的
test函数都会覆盖上一次迭代定义的同名函数,pytest收集测试用例时只能识别到最后一次迭代生成的test函数。 - 原测试逻辑缺失断言:即使修复了收集问题,你的代码没有加
assert判断表达式结果,测试永远会返回通过。
解决方案1:修改循环生成逻辑(适配你原本的写法)
通过给每个迭代生成的测试函数指定唯一名称,注册到模块全局作用域,同时修复晚绑定和断言问题:
import pytest def func_1(x): return (x+10) def func_2(y): return (y-10) func_1_test_cases = {'func_1': (10, 20)} func_2_test_cases = {'func_2': (10, 0)} for func in ['func_1', 'func_2']: @pytest.mark.parametrize('param, expected', globals()[func + '_test_cases'].values(), ids=list(globals()[func + '_test_cases'].keys())) def test(param, expected, func=func): # 加上assert断言,直接获取函数对象避免eval的安全风险 assert globals()[func](param) == expected # 给测试函数指定唯一名称,注册到全局作用域 globals()[f'test_{func}'] = test
执行pytest test.py -v后可以看到两个测试用例被收集执行:
collected 2 items test.py::test_func_1[func_1] PASSED test.py::test_func_2[func_2] PASSED
解决方案2:更符合pytest规范的写法(推荐)
不需要循环生成测试函数,直接将函数、测试参数、预期结果打包为参数化列表,一次参数化即可完成所有测试,规避变量绑定、函数重名等所有问题,也不需要使用风险较高的eval:
import pytest def func_1(x): return (x+10) def func_2(y): return (y-10) # 统一整理所有测试数据:(测试函数, 入参, 预期结果, 用例ID) test_cases = [ (func_1, 10, 20, "func_1"), (func_2, 10, 0, "func_2") ] @pytest.mark.parametrize('test_func, param, expected', test_cases, ids=lambda x: x[3]) def test_all(test_func, param, expected): assert test_func(param) == expected
内容的提问来源于stack exchange,提问作者Maged Eltorkoman
相关产品推荐
相关产品推荐

