pytest之fixture

Python + pytest 是 API 测试最主流的组合:

1.最高频的使用场景

1. 从接口文档生成测试代码

把接口描述或 Swagger JSON 粘给 AI,直接产出:

# AI 生成的初稿结构

import pytest
import requests

class TestUserLogin:
BASE_URL = "https://api.example.com"

@pytest.mark.parametrize("payload,expected_status,expected_msg", [
({"username": "valid", "password": "valid"}, 200, "success"),
({"username": "", "password": "valid"}, 400, "用户名不能为空"),
({"username": "valid", "password": "wrong"}, 401, "密码错误"),
({"username": "a" * 256, "password": "valid"}, 400, None), # 边界值
])
def test_login(self, payload, expected_status, expected_msg):
resp = requests.post(f"{self.BASE_URL}/login", json=payload)
assert resp.status_code == expected_status

 

你只需要审查逻辑,不用从零写。

---
2. fixture 设计

告诉 AI 你的业务依赖关系,它帮你规划 fixture 层次:

@pytest.fixture(scope="session")
def auth_token():
# AI 帮你写好登录获取 token 的逻辑
...

@pytest.fixture
def created_order(auth_token):
# 依赖 token,创建订单并在测试后清理
order = create_order(auth_token)
yield order
delete_order(order["id"], auth_token)

 

---

代码解释:

 yield 在 pytest fixture 里是分隔"准备""清理"两个阶段的关键字。

  1)执行顺序:

  测试开始
    ↓
  order = create_order(auth_token)   ← 前置:创建订单
    ↓
  yield order                        ← 把 order 传给测试函数,然后【暂停在这里】
    ↓
  [测试函数执行]
    ↓
  delete_order(order["id"], ...)     ← 后置:测试结束后自动清理

 2)对比理解:

# 没有 yield —— 只有准备,没有清理
@pytest.fixture
def created_order(auth_token):
  order = create_order(auth_token)
  return order # 测试结束后订单留在系统里,产生脏数据


# 有 yield —— 准备 + 清理
@pytest.fixture
def created_order(auth_token):
  order = create_order(auth_token)
  yield order # 测试结束后自动执行 yield 下面的代码
  delete_order(order["id"], auth_token) # 清理掉

3)测试函数怎么用

def test_get_order(created_order):
  # created_order 就是 yield 传出来的那个 order 对象
  resp = requests.get(f"/orders/{created_order['id']}")
  assert resp.status_code == 200

---
核心记忆:yield 之前 = setUp,yield 本身 = 传值给测试,yield 之后 = tearDown。即使测试中途报错,yield 后面的清理代码也保证会执行。

4)@pytest.fixture这个装饰器表示什么意思

@pytest.fixture
def created_order(auth_token):
  order = create_order(auth_token)
  yield order
  delete_order(order["id"], auth_token)

# 测试函数只需要在参数里写同名变量,pytest 自动传进来
def test_get_order(created_order): # ← pytest 看到参数名,自动找同名 fixture 执行
assert created_order["status"] == "pending"

你不需要手动调用 created_order(),pytest 自动帮你执行并把结果传进来,这就是"注入"。

没有 fixture 的写法对比

# 没有 fixture —— 每个测试都要手动重复准备和清理
def test_get_order():
token = login()
order = create_order(token)
try:
assert order["status"] == "pending"
finally:
delete_order(order["id"], token)

def test_update_order():
token = login() # 重复
order = create_order(token) # 重复
try:
...
finally:
delete_order(order["id"], token) # 重复

# 有 fixture —— 准备/清理逻辑只写一次,测试函数专注断言
def test_get_order(created_order):
assert created_order["status"] == "pending"

def test_update_order(created_order):
...

scope 控制复用范围

@pytest.fixture(scope="function") # 默认,每个测试函数都重新执行一次
@pytest.fixture(scope="class") # 同一个测试类共享一次
@pytest.fixture(scope="module") # 同一个文件共享一次
@pytest.fixture(scope="session") # 整个测试会话只执行一次(如 auth_token)

一句话总结:@pytest.fixture 就是把"公共的准备+清理逻辑"抽出来复用,谁的参数里写了这个名字,pytest 就自动注入给谁。

 

5) yield 后面跟参数,表示把这个值传递给使用该 fixture 的测试函数。

对比

# yield 不带参数 —— 只做准备/清理,不传值
@pytest.fixture
def setup_database():
  db.connect()
  yield # 什么都不传
  db.disconnect()

def test_something(setup_database):
  # setup_database 是 None,你只是借用了它的准备/清理流程
  ...

# yield 带参数 —— 准备/清理 + 传值
@pytest.fixture
def created_order(auth_token):
  order = create_order(auth_token)
  yield order # 把 order 这个对象传出去

def test_get_order(created_order):
  # created_order 就是上面 yield 传出来的 order 对象
  print(created_order["id"]) # 可以直接用

 


3. conftest.py 结构规划

描述你的项目结构,AI 帮你设计合理的 conftest 分层,避免 fixture 混乱。

---
4. 断言增强

AI 会提示你除了 status_code 之外还应该断言什么:

- 响应时间阈值 assert resp.elapsed.total_seconds() < 2
- 必填字段存在性
- 字段类型校验(配合 jsonschema 或 pydantic)
- 业务逻辑一致性(创建后查询,数据要对应)

---
5. 日志分析与报错定位

测试跑失败时,把 pytest 输出直接粘给 AI,通常能快速给出根因和修复建议。

---
推荐的提问方式

┌──────────┬────────────────────────────────────┐
│ 场景 │ 给 AI 的信息 │
├──────────┼────────────────────────────────────┤
│ 生成用例 │ 接口路径 + 参数说明 + 业务规则 │
├──────────┼────────────────────────────────────┤
│ 生成脚本 │ 上面的用例 + 你用的 requests/httpx │
├──────────┼────────────────────────────────────┤
│ 调试失败 │ pytest 完整报错 + 相关代码片段 │
├──────────┼────────────────────────────────────┤
│ 优化结构 │ 当前 conftest.py 内容 │
└──────────┴────────────────────────────────────┘

 

posted @ 2026-06-05 13:53  苹果芒  阅读(8)  评论(0)    收藏  举报