文章目录
官方概念
概念分析
在
pytest
的@pytest.mark.parametrize
装饰器中,indirect
参数用于指示是否应该从fixtures
中解析参数值,而不是直接使用提供的值。当 indirect=False(默认值)时:
argnames
参数被当成普通变量处理;argvalues
中提供的值会直接作为这些变量的值。- 此时,
argnames
中不需要引用任何已定义的fixture
;当 indirect=True 时:
argnames
参数被当成fixture
函数处理;pytest
会尝试从定义的fixtures
中查找具有相同名称的fixture
,- 如果存在则将
argvalues
值作为argnames
函数中的参数传参给这个fixture
,- 之后将
fixture
函数的返回值作为参数化数据,- 因此,必须先行定义与之匹配的
fixture
函数。理解
indirect
参数的关键是将其视为一个开关,用于控制argnames
的解析方式。这种机制使得我们可以灵活地管理测试数据,将复杂的数据生成逻辑封装在
fixtures
中,并通过参数化测试来复用这些数据。
官方示例
示例代码
python
import pytest
@pytest.fixture(scope='function')
def x(request):
return request.param * 3
@pytest.fixture(scope='function')
def y(request):
return request.param * 2
@pytest.mark.parametrize('x,y', [['a', 'b']], indirect=['x'])
def test_x(x, y):
assert x == 'aaa'
assert y == 'b'
@pytest.mark.parametrize('x,y', [['a', 'b']], indirect=['x','y'])
def test_x_y(x, y):
assert x == 'aaa'
assert y == 'bb'
执行结果
示例分析
示例代码
python
import pytest
@pytest.fixture(scope='function')
def x(request):
return request.param * 3
@pytest.fixture(scope='function')
def y(request):
return request.param * 2
@pytest.mark.parametrize(argnames='x,y', argvalues=[['a', 'b']], indirect=['x'])
def test_x(x, y):
print(f"x={x}, y={y}")
assert x == 'aaa'
assert y == 'b'
@pytest.mark.parametrize(argnames='x,y', argvalues=[['a', 'b']], indirect=['x', 'y'])
def test_x_y(x, y):
print(f"x={x}, y={y}")
assert x == 'aaa'
assert y == 'bb'
执行结果
验证indirect为True但不指定fixture
示例代码
python
import pytest
@pytest.fixture(scope='function')
def x(request):
return request.param * 3
@pytest.fixture(scope='function')
def y(request):
return request.param * 2
@pytest.mark.parametrize(argnames='x,y', argvalues=[['a', 'b']], indirect=['x'])
def test_x(x, y):
print(f"x={x}, y={y}")
assert x == 'aaa'
assert y == 'b'
@pytest.mark.parametrize(argnames='x,y', argvalues=[['a', 'b']], indirect=True)
def test_x_y(x, y):
print(f"x={x}, y={y}")
assert x == 'aaa'
assert y == 'bb'
执行结果
验证indirect为True但不存在fixture
示例代码
python
import pytest
@pytest.mark.parametrize(argnames='x,y', argvalues=[['a', 'b']], indirect=['x'])
def test_x(x, y):
print(f"x={x}, y={y}")
assert x == 'aaa'
assert y == 'b'
@pytest.mark.parametrize(argnames='x,y', argvalues=[['a', 'b']], indirect=True)
def test_x_y(x, y):
print(f"x={x}, y={y}")
assert x == 'aaa'
assert y == 'bb'
执行结果