Late-Binding 与 Pytest 模块冲突
Late-Binding conflict with Pytest module
我正在尝试迭代 pytest
函数,late-binding 的问题
使 pytest
仅将测试应用于最后一个函数。
为了简化示例,我编写了以下 test.py
文件:
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)}
# Iterating over the functions
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):
eval(func+'(param) == expected')
我阅读了有关 late-binding 问题的更多信息并采纳了以下建议:
def test(param, expected, func=func):
eval(func+'(param) == expected')
使用命令时:
pytest test.py -v
pytest
报告仅收集列表中的最后一个函数 (func_2
):
plugins: timeout-1.4.2, anyio-2.2.0, pudb-0.7.0
collected 1 item
1.py::test[func_2
] PASSED [100%]
============================================================================= 1 passed in 0.01s =============================================================================
func_1
从未收藏过
使用 pytest
时,late-binding 问题似乎更棘手。
我希望 pytest
报告收集两个函数和 return 它们的状态。
我真的需要解决这个问题。
这并没有直接回答您关于使用相同名称定义多个测试的问题,但是对于您发布的特定示例,将函数本身作为测试参数之一包括在内会容易得多:
import pytest
def func_1(x):
return (x+10)
def func_2(y):
return (y-10)
@pytest.mark.parametrize(
'func,param,expected', [
pytest.param(func_1, 10, 20, id='func_1'),
pytest.param(func_2, 10, 0, id='func_2'),
],
)
def test(func, param, expected):
assert func(param) == expected
请注意:您的测试函数没有 assert
,因此无论 eval(func+'(param) == expected')
是真还是假,它都会通过。
受Kale回答的启发,我认为没有很好的方法可以循环遍历pytest
parametize
装饰器(如果我错了希望有人纠正我)。
唯一实用的解决方案是在参数列表中包含函数 ID。
这是接近我想要的修改后的代码。
import pytest
def func_1(x):
return (x+10)
def func_2(y):
return (y-10)
func_test_cases = {'func_1': (10, 20, 'func_1'), 'func_2': (10, 3, 'func_2')}
@pytest.mark.parametrize('param, expected, func',
func_test_cases.values(), ids=func_test_cases.keys())
def test(param, expected, func):
assert eval(func+'(param) == expected')
我正在尝试迭代 pytest
函数,late-binding 的问题
使 pytest
仅将测试应用于最后一个函数。
为了简化示例,我编写了以下 test.py
文件:
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)}
# Iterating over the functions
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):
eval(func+'(param) == expected')
我阅读了有关 late-binding 问题的更多信息并采纳了以下建议:
def test(param, expected, func=func):
eval(func+'(param) == expected')
使用命令时:
pytest test.py -v
pytest
报告仅收集列表中的最后一个函数 (func_2
):
plugins: timeout-1.4.2, anyio-2.2.0, pudb-0.7.0 collected 1 item
1.py::test[
func_2
] PASSED [100%]============================================================================= 1 passed in 0.01s =============================================================================
func_1
从未收藏过
使用 pytest
时,late-binding 问题似乎更棘手。
我希望 pytest
报告收集两个函数和 return 它们的状态。
我真的需要解决这个问题。
这并没有直接回答您关于使用相同名称定义多个测试的问题,但是对于您发布的特定示例,将函数本身作为测试参数之一包括在内会容易得多:
import pytest
def func_1(x):
return (x+10)
def func_2(y):
return (y-10)
@pytest.mark.parametrize(
'func,param,expected', [
pytest.param(func_1, 10, 20, id='func_1'),
pytest.param(func_2, 10, 0, id='func_2'),
],
)
def test(func, param, expected):
assert func(param) == expected
请注意:您的测试函数没有 assert
,因此无论 eval(func+'(param) == expected')
是真还是假,它都会通过。
受Kale回答的启发,我认为没有很好的方法可以循环遍历pytest
parametize
装饰器(如果我错了希望有人纠正我)。
唯一实用的解决方案是在参数列表中包含函数 ID。
这是接近我想要的修改后的代码。
import pytest
def func_1(x):
return (x+10)
def func_2(y):
return (y-10)
func_test_cases = {'func_1': (10, 20, 'func_1'), 'func_2': (10, 3, 'func_2')}
@pytest.mark.parametrize('param, expected, func',
func_test_cases.values(), ids=func_test_cases.keys())
def test(param, expected, func):
assert eval(func+'(param) == expected')