✅ 简单回答:
使用 fixture ≠ 不独立。
只要你的 fixture 是每次测试都能自己运行、自己产生数据的,那么测试用例依然是“逻辑独立”的。
情况 | 是否影响独立性 | 说明 |
---|---|---|
fixture 中 硬编码共享数据(如共享 token) | ❌ 是耦合的 | 多个用例依赖同一数据,顺序或状态会影响结果 |
fixture 每次调用都能 重新生成独立数据 | ✅ 不影响 | 比如每个测试都生成新 token、新用户 |
fixture 被多个用例共享,且包含有状态操作 | ❌ 可能影响 | 比如 fixture 中做了前置清理,多个测试共享它就有影响 |
fixture 被一个用例专用 | ✅ 安全 | 就像把准备步骤封装起来,依然独立 |
python
import pytest
import requests
@pytest.fixture
def valid_token():
# 每次都调用登录接口,获取新 token
response = requests.post("http://example.com/api/login", json={
"username": "testuser",
"password": "123456"
})
assert response.status_code == 200
return response.json()["token"]
def test_user_info(valid_token):
headers = {"Authorization": f"Bearer {valid_token}"}
resp = requests.get("http://example.com/api/user/info", headers=headers)
assert resp.status_code == 200
✔️ 这个 valid_token fixture 每次都是“自给自足”的,不依赖其他测试状态,所以仍然是独立用例。
python
# 假设 login_fixture 中手动生成了 token 或写死一个 token
@pytest.fixture(scope="session")
def shared_token():
return "abc1234567" # 固定写死,或者由前置用例创建
def test_user_info(shared_token):
...
这个 shared_token fixture:
不一定来自当前测试生成
可能是别的用例产生或初始化时产生的
这种就存在耦合风险。如果别的地方修改了 token 或状态,可能影响这个用例。
做法 | 推荐程度 | 理由 |
---|---|---|
每个用例内部写登录逻辑 | 简单但冗余少量可接受 | ✅ 保证测试完全独立,无需依赖外部状态或 fixture,适合初学或用例量较少时 |
用 fixture 封装登录,但每次自动重新登录 | ✅ 最推荐 | ✅ 实现代码复用 + 独立性兼顾,每个用例拿到的 token 都是最新、唯一、干净的 |
共享全局 token、session 作为 fixture | ⚠️ 仅限于性能优化场景,否则不推荐 | ⚠️ 存在用例状态耦合、测试顺序依赖等风险,若 token 被修改或过期会影响所有用例 |
只要 fixture 是“每个用例都能独立用”的工具,它就是帮助测试保持独立的;只有当它变成“多个测试共用的状态容器”,才会破坏独立性。
✅ 简短回答:
不是所有 scope=“session” 的 fixture 都导致耦合,关键在于你放了什么内容进去。
scope 值 | 生命周期 | 举例 |
---|---|---|
“function” | 每个用例都执行一次(默认) | 最独立、最干净 |
“class” | 每个类只执行一次 | 类内测试共享 |
“module” | 每个测试文件只执行一次 | 跨函数共享 |
“session” | 整个测试执行过程只执行一次 | 所有用例共享,最广 |
python
# 这是一个静态配置类 fixture,和用例无状态相关
@pytest.fixture(scope="session")
def base_url():
return "http://example.com/api"
✔️ 这个不会耦合,因为它只是一个静态值,多个用例共享没有问题。
python
@pytest.fixture(scope="session")
def shared_token():
# 登录一次,所有用例共用
resp = requests.post("http://example.com/api/login", json={
"username": "testuser", "password": "123456"
})
return resp.json()["token"]
如果某个测试改变了用户状态(比如禁用账号、修改密码),其它测试就会失败。这就是“隐性耦合”。
python
@pytest.fixture
def fresh_token():
# 每个用例登录一次,独立、干净
...
python
@pytest.fixture(scope="session")
def env_config():
return {
"base_url": "http://example.com/api",
"headers": {"Content-Type": "application/json"}
}
scope=“session” 本身不是坏事,但如果 fixture 中包含用户态、系统态、会变的内容,就可能导致耦合问题。配置类 OK,状态类要谨慎。