Pytest 如何给 Fixture 传递参数?
Pytest 给 fixture 传参的三种方式:@pytest.fixture(params=[...]) 参数化、间接参数化 @pytest.mark.parametrize 加 indirect=True、以及 request 对象读取上下文。本文给出完整示例。
两种主路径:fixture 自身参数化——@pytest.fixture(params=[...]) 中通过 request.param 取值;或测试侧间接传参——@pytest.mark.parametrize(..., indirect=True)。
方式一:fixture 自带参数列表
import pytest
@pytest.fixture(params=["mysql", "postgres"])
def db(request):
conn = create_connection(request.param) # request.param 取当前参数
yield conn
conn.close()
def test_query(db):
assert db.query("SELECT 1") # 自动跑两遍:mysql 和 postgres
create_connection 和 create_user 是应用需自行实现的辅助函数,上面仅演示 fixture 生命周期。
方式二:测试侧传参(indirect)
@pytest.fixture
def user(request):
return create_user(role=request.param)
@pytest.mark.parametrize("user", ["admin", "guest"], indirect=True)
def test_permission(user):
...
参数从测试用例流向 fixture——测试控制数据,fixture 控制构造。
方式三:命令行/配置读取
# conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption("--env-url", default="http://localhost:8000")
@pytest.fixture
def base_url(request):
return request.config.getoption("--env-url")
常见问题(FAQ)
Q:params 支持对象吗? 支持任意 Python 对象,用 ids 参数给每个参数起可读的名字。
Q:fixture 之间能传参吗? fixture 可依赖其他 fixture;测试侧直接参数化的名字也可由依赖链接收。需要让目标 fixture 用 request.param 构造资源时,使用 indirect 参数化。