如何在pytest中结合多参数函数使用parametrize与CSV数据?
pytest结合CSV结构化数据测试含位置/关键字参数的函数
问题场景
需基于numpy结构化数组(模拟CSV导入数据),用pytest批量测试包含位置参数x和关键字-only参数y的函数,从数组中提取a、b作为函数入参,f_squared/f_cubed作为预期结果,遍历所有行完成测试。
解决方案
利用@pytest.mark.parametrize装饰器,将结构化数组的行数据转换为测试用例列表,实现批量测试。
可运行完整代码
import pytest import numpy as np import numpy.lib.recfunctions as rf def squared(x, *, y): return (x + y) ** 2 def cubed(x, *, y): return (x + y) ** 3 # 修正模拟CSV数据:每行对应a,b,f_squared,f_cubed四个字段 mycsv = np.array([ [1, 2, 9, 27], [5, 5, 100, 1000], [3, 4, 49, 343], [6, 8, 196, 2744] ]) dtypes = [("a", "f8"), ("b", "f8"), ("f_squared", "f8"), ("f_cubed", "f8")] mycsv = rf.unstructured_to_structured(mycsv, dtype=np.dtype(dtypes)) # 生成测试用例列表:每个元素是(a值, b值, 预期结果) squared_test_cases = [(row["a"], row["b"], row["f_squared"]) for row in mycsv] cubed_test_cases = [(row["a"], row["b"], row["f_cubed"]) for row in mycsv] @pytest.mark.parametrize("a, b, expected", squared_test_cases) def test_squared(a, b, expected): computed = squared(x=a, y=b) msg = f"测试失败:x={a}, y={b},预期值{expected},实际计算值{computed}" np.testing.assert_allclose(expected, computed, rtol=2e-2, err_msg=msg) @pytest.mark.parametrize("a, b, expected", cubed_test_cases) def test_cubed(a, b, expected): computed = cubed(x=a, y=b) msg = f"测试失败:x={a}, y={b},预期值{expected},实际计算值{computed}" np.testing.assert_allclose(expected, computed, rtol=2e-2, err_msg=msg)
关键说明
- 测试用例生成:通过列表推导遍历结构化数组的每一行,提取所需参数和预期值,组成元组列表,每个元组对应一组独立测试的输入与结果。
- parametrize用法:装饰器中指定测试函数的参数名(
a, b, expected),传入测试用例列表后,pytest会自动遍历每个用例执行测试,每个用例会生成独立的测试报告条目。 - 参数传递:被测函数中
y是关键字-only参数(通过*标记),调用时必须以y=b的形式传递,x作为位置参数可直接传值或显式指定x=a。 - 浮点断言:使用
np.testing.assert_allclose处理浮点数值的断言,设置rtol控制相对误差容限,避免因浮点精度问题导致测试失败。
内容的提问来源于stack exchange,提问作者a11
相关产品推荐
相关产品推荐

