引言在做接口自动化测试时你可能遇到过这样的情况单独运行某个用例一切正常但批量跑测试时大量接口返回 401 或权限错误。这通常是fixture 生命周期与共享状态导致的问题。本文结合实际场景带你深入理解 Pytest 的 fixture 作用域并提供解决方案。一、Pytest Fixture 的作用域Pytest 提供了几种常用 fixture 生命周期scopescope创建次数生命周期说明function每个测试用例 1 次用例之间完全隔离class每个测试类 1 次同一类用例共享module每个模块 1 次同一文件的所有用例共享session整个测试运行 1 次测试全局共享资源本质理解短生命周期适合需要隔离状态的对象如接口客户端、登录 token长生命周期适合全局共享资源如数据库连接、Redis 客户端二、真实问题复现假设我们有两个 fixturepytest.fixture(scopesession)defrequest_util():returnRequestUtil()# 封装 HTTP 请求带 token 状态pytest.fixture(scopesession)defauth_token(request_util,test_data):usertest_data[users][test_user]resprequest_util.post(/public/login,json{account:user[account],password:user[password]})returnresp.json()[data][token]问题表现运行测试时批量用例报错ScopeMismatch: You tried to access the function scoped fixture request_util with a session scoped request object Token 不匹配或已失效分析request_util携带 token 状态每个用例可能修改 headerauth_token是 session 级 fixture全局依赖短生命周期 fixture → 生命周期冲突结果多个用例共享同一个 request_util 与 token状态污染 → 401三、为什么scopefunction可以解决问题1改法示例pytest.fixture(scopefunction)defrequest_util():returnRequestUtil()pytest.fixture(scopefunction)defauth_token(request_util,test_data):usertest_data[users][test_user]resprequest_util.post(/public/login,json{account:user[account],password:user[password]})returnresp.json()[data][token]2运行逻辑变化原来session创建 request_util token A只一次 用例1 → token A 用例2 → token A被污染 用例3 → token A被污染 ...改成 function用例1 → 新 request_util → 登录 → token A 用例2 → 新 request_util → 登录 → token B 用例3 → 新 request_util → 登录 → token C ...每个用例都是独立 sessiontoken 不会相互污染 → 401 消失四、什么时候用 session什么时候用 function✅ 适合 session共享资源不带状态pytest.fixture(scopesession)defdb_conn():returnconnect_mysql()❌ 不适合 session带状态对象pytest.fixture(scopesession)defrequest_util():utilRequestUtil()util.login()# 带 token 状态 → 多用例共享可能出问题returnutil