pytest测试框架:如何确保登录模块先执行并共享登录状态

在接口自动化测试中,我们经常会遇到这样的场景:多个接口依赖登录接口返回的token。如果简单地将所有测试用例放在一起执行,可能会因为执行顺序不确定而导致后续接口因token不存在而失败。本文将介绍一种基于pytest的解决方案,通过控制用例执行顺序和共享登录数据,优雅地解决依赖登录的问题。

解决方案概述

我们将使用两个核心特性:

  • pytest-order 插件:控制登录用例第一个执行。
  • session 级别的 fixture:在多个测试用例之间共享登录后得到的 token 和用户名。

同时,我们还会处理一种边界情况:如果登录失败,后续依赖登录的用例应直接跳过,而不是全部失败,避免测试报告被大量错误淹没。

详细步骤

1. 安装 pytest-order

pytest-order 是一个pytest插件,可以通过标记(mark)来指定测试用例的执行顺序。

bash

css 复制代码
pip install pytest-order

2. 在 conftest.py 中定义共享存储

我们需要一个全局的存储空间,用于保存登录后的数据。使用 scope="session" 的 fixture 最为合适,它会在整个测试会话期间只创建一次,并在所有测试用例中共享。

python

python 复制代码
# conftest.py
import pytest

@pytest.fixture(scope="session")
def api_logined_data():
    """存储登录后得到的 token 和 username"""
    return {}  # 初始为空字典,后续由登录用例填充

3. 标记登录用例为第一个执行

在登录测试函数上使用 @pytest.mark.order(1),确保它第一个运行。

python

python 复制代码
# test_login.py
import pytest

@pytest.mark.order(1)
def test_api_login(api_client, api_logined_data):
    """登录接口测试用例,执行成功后保存 token 和 username"""
    response = api_client.post("/login", json={"username": "test", "password": "123456"})
    assert response.status_code == 200
    data = response.json()
    token = data.get("token")
    username = data.get("username")
    assert token is not None
    assert username is not None

    # 保存到共享 fixture 中
    api_logined_data["token"] = token
    api_logined_data["username"] = username
    print(f"登录成功,token: {token}, username: {username}")

注意api_client 是你可能自定义的 HTTP 请求 fixture,本文中仅作示意。

4. 在其他测试用例中使用共享数据

其他接口测试用例可以通过注入 api_logined_data 来获取 token 和 username,并在请求头中使用。

python

python 复制代码
# test_other.py
import pytest

def test_get_user_profile(api_client, api_logined_data):
    """获取用户信息接口,依赖登录 token"""
    token = api_logined_data.get("token")
    username = api_logined_data.get("username")
    # 后续会处理 token 不存在的情况,这里先假设存在
    headers = {"token": token, "username": username}
    response = api_client.get("/user/profile", headers=headers)
    assert response.status_code == 200

5. 处理登录失败的情况:跳过后续依赖用例

如果登录用例失败(例如断言失败或抛出异常),后续使用共享数据的用例会因为 api_logined_data 中没有 token 而报 KeyError,导致大量失败。更合理的做法是当登录数据不存在时,直接跳过当前用例,表示该用例因前置条件不满足而无法执行。

我们可以使用 pytest.skip 来实现:

python

ini 复制代码
# test_other.py
import pytest

def test_get_user_profile(api_client, api_logined_data):
    try:
        token = api_logined_data["token"]
        username = api_logined_data["username"]
    except KeyError:
        pytest.skip("登录失败或未执行,跳过当前用例")

    headers = {"token": token, "username": username}
    response = api_client.get("/user/profile", headers=headers)
    assert response.status_code == 200

这样,如果登录用例失败,后续所有依赖登录的用例都会被标记为 skipped,而不会显示为失败。测试报告会更清晰地反映出真正的问题所在。

完整示例代码结构

为了方便理解,这里给出一个简化后的项目结构示例:

text

bash 复制代码
.
├── conftest.py              # 存放共享 fixture
├── test_login.py            # 登录用例,标记 order=1
├── test_user.py             # 用户相关接口,依赖登录数据
└── test_order.py            # 其他模块,同样依赖登录数据

conftest.py

python

python 复制代码
import pytest

@pytest.fixture(scope="session")
def api_logined_data():
    return {}

test_login.py

python

python 复制代码
import pytest

@pytest.mark.order(1)
def test_api_login(api_logined_data):
    # 模拟登录成功,保存数据
    api_logined_data["token"] = "fake_token_123"
    api_logined_data["username"] = "test_user"
    assert True  # 实际测试中应有真实断言

test_user.py

python

python 复制代码
import pytest

def test_get_profile(api_logined_data):
    try:
        token = api_logined_data["token"]
        username = api_logined_data["username"]
    except KeyError:
        pytest.skip("登录失败,跳过")
    # 使用 token 和 username 发起请求...
    assert token == "fake_token_123"

注意事项

  1. pytest-order 的标记方式 :除了 @pytest.mark.order(1),还可以使用 beforeafter 等更灵活的标记,具体可参考其官方文档
  2. fixture 的 scope 选择 :这里使用 session 是因为登录数据只需获取一次,且在整个测试过程中保持不变。如果 token 会过期,可能需要考虑更复杂的刷新机制。
  3. 跳过与失败的取舍 :用 pytest.skip 跳过依赖用例,而不是让它们因为 KeyError 而失败,可以让测试报告更聚焦于真正的失败点(登录失败本身)。
  4. 数据隔离:如果有多组测试数据(例如不同用户),可以考虑将共享数据设计为字典的字典,或以其他方式隔离,避免数据污染。

总结

通过 pytest-order 控制用例顺序 + session 级别 fixture 共享数据,我们可以轻松实现"先登录,后执行其他接口"的测试需求。同时,使用 pytest.skip 优雅地处理登录失败的场景,让测试结果更加清晰。这套方案已经在多个接口自动化项目中实践,稳定可靠,值得一试。

相关推荐
_志哥_1 天前
Superpowers 技术指南:让 AI 编程助手拥有超能力
人工智能·ai编程·测试
FliPPeDround4 天前
浏览器扩展 E2E 测试的救星:vitest-environment-web-ext 让你告别繁琐配置
e2e·浏览器·测试
Apifox4 天前
Apifox 2 月更新|MCP Client 调试体验优化、测试套件持续升级、支持公用测试数据、测试报告优化
前端·后端·测试
infiniteWei4 天前
Skills、MCP、Agent 的边界与商业化定位(附项目筛选表)
人工智能·aigc·测试
洞窝技术6 天前
让AI帮我做测试用例,我来喝咖啡
ai编程·测试
洛_尘12 天前
测试6:自动化测试--概念篇(JAVA)
java·开发语言·测试
洛_尘15 天前
测试5:测试分类
测试
橘颂TA23 天前
【测试】高效浏览器操作:基础功能与优化设置大全
c++·功能测试·职场和发展·测试·web测试
wangsir.23 天前
测试之自动化测试常用函数
python·测试