必须隔离 session 和 headers:用 session 实例作 fixture 复用连接,headers 从配置读取,登录态通过依赖 fixture 分层注入,响应断言需含错误详情,环境通过 pytest 参数化加载 yaml 配置。

requests请求封装必须隔离 session 和 headers 配置
直接在测试用例里写 requests.post(url, json=data) 看似简单,但一旦接口需要登录态、统一鉴权头、重试逻辑或环境切换,就会重复写十几遍 headers、反复处理 401 或 ConnectionError。核心是把「连接管理」和「请求构造」拆开。
- 用
requests.Session()实例做类属性或 fixture,避免每次新建 TCP 连接;不要在每个测试函数里调requests.get() -
headers必须从配置读(比如config.py里的DEFAULT_HEADERS),而不是硬编码在方法参数里;否则换环境要改二十个地方 - 登录接口返回的
token要存进 session 的auth或自定义属性(如session.auth_token),别塞进全局变量——pytest 多进程下会丢 - 示例:在 conftest.py 里定义 fixture
import pytest
import requests
@pytest.fixture(scope="session")
def api_session():
s = requests.Session()
s.headers.update({"Content-Type": "application/json", "User-Agent": "test-client"})
return s
pytest fixture 设计要区分「基础会话」和「带登录态会话」
很多人只写一个 api_client fixture,结果所有测试都得先调一次登录,或者手动在 setup 里补 token——这既拖慢执行,又让用例耦合登录流程。真实场景里,有的接口要登录(如 /user/profile),有的不用(如 /health),必须分层。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 基础 fixture(如
guest_session)只配通用 headers 和 timeout,不带任何认证信息 - 登录 fixture(如
authed_session)依赖基础 session,并在内部调用登录接口、提取access_token、注入到Authorizationheader - 注意
scope="function"和scope="session"的区别:登录态一般用function,防止用例间 token 冲突;但 session 实例本身可session级复用 - 别在 fixture 里 print 日志——pytest -s 才能看见,CI 环境默认不显示,建议用
logging或 pytest 的record_property
断言失败时看不到原始响应体?必须重写 assert 逻辑
直接写 assert resp.status_code == 200,报错只显示 AssertionError,根本不知道返回了什么 JSON 或 HTML 错误页。调试时还得加 print(resp.text),又脏又漏——尤其 CI 上根本看不到。
- 所有请求调用后,立刻用
resp.raise_for_status(),它会在非 2xx 时抛出带状态码和 reason 的异常,比裸 assert 强 - 对 JSON 响应,用
resp.json()前先检查resp.headers.get("Content-Type")是否含json,否则可能抛JSONDecodeError并掩盖真实错误 - 推荐封装一个
safe_json()方法:捕获JSONDecodeError后返回{"error": "invalid json", "raw": resp.text[:200]},方便定位 - 示例断言写法:
resp = authed_session.get("/api/user")
assert resp.status_code == 200, f"expected 200, got {resp.status_code}: {resp.text[:100]}"
data = resp.json()
assert data["id"] == user_id
环境配置不能靠 if-else 切换 host
用 if env == "prod": base_url = "https://api.example.com" 是最常见也最危险的做法。一来硬编码分散在各处,二来无法被 pytest 参数化控制,三来 CI 构建时容易因本地 env 变量污染线上测试。
- 用 pytest 的
--env自定义命令行参数(通过pytest_addoption),再在 fixture 中读取request.config.getoption("--env") - 配置文件按环境拆分:
config/staging.yaml、config/prod.yaml,用pyyaml加载,key 统一为base_url、timeout、cert_path等 - 绝对不要在代码里拼接 URL:
f"{base_url}/v1/users/{uid}"容易漏斜杠或双斜杠;改用urljoin(base_url, "/v1/users") - 证书路径(
cert_path)这类敏感配置,必须设为可选——本地开发常关 TLS 验证,但 CI 必须开;用session.verify = config.get("verify_ssl", True)
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










