pytest fixture 的 request 参数是 pytest 内置上下文对象,非 HTTP 请求工具;需用 requests 库手动发起请求,参数化须配合 @pytest.fixture(params=...) 使用 request.param,且 fixture 不支持运行时传参。

因为 pytest fixture 本身不接收“请求参数”——它接收的是 pytest 内部的 request 对象,而这个对象不是你发 HTTP 请求用的 requests 库。
把 request 当成 HTTP 请求对象是常见误解
很多人看到 fixture 函数签名里有 request 参数(比如 def my_fixture(request):),就以为这是用来发网络请求的。其实它是 pytest 自带的 request fixture,提供当前测试上下文信息(如 request.param、request.scope、request.node 等)。
- 它和
import requests完全无关,名字撞车纯属巧合 - 直接传入字符串、字典或 URL 给它会报
TypeError: 'str' object is not callable或类似错误 - 如果你真想发 HTTP 请求,得自己在 fixture 里调用
requests.get()等函数,而不是依赖request参数
request.param 只在参数化 fixture 中有效
只有当你用 @pytest.fixture(params=[...]) 显式参数化时,request.param 才有值;否则访问它会触发 AttributeError。
- 错误写法:
def api_client(request): return requests.get(request.param)—— 没参数化却硬读request.param - 正确写法:先加
@pytest.fixture(params=["/users", "/posts"]),再在函数体内用requests.get(f"https://api.example.com{request.param}") - 注意:每次参数值都会触发一次 fixture 初始化,所以每个
request.param对应一个独立的 HTTP 调用
fixture 无法“接收外部传参”的本质原因
pytest 的 fixture 是声明式依赖注入,不是普通函数调用。你不能像 my_fixture("https://x") 这样传参,因为:
立即学习“Python免费学习笔记(深入)”;
- pytest 在收集阶段就锁定 fixture 图,运行时只按依赖关系注入,不支持运行时动态传参
- 如果需要不同 URL,应该用参数化(
params)、工厂 fixture(返回可调用对象)、或通过配置项(如request.config.getoption("--base-url"))间接控制 - 试图在测试函数里“传参给 fixture”会导致
ScopemismatchError或TypeError: missing 1 required positional argument
最易被忽略的一点:fixture 的参数名只是占位符,request 是特例(pytest 自动注入),其他名字(如 url、data)不会自动获得任何值——除非它们本身也是被 pytest 管理的 fixture。


















