Pytest 接口关联

在接口自动化测试中,接口之间通常存在关联关系,比如前一个接口返回的数据需要传递给后续接口使用。以下是 Pytest 中实现接口关联的方法和详细讲解。


1. 什么是接口关联?

接口关联指的是一个接口的输出作为另一个接口的输入。常见的场景包括:

  • 登录接口返回的 token 需要传递给后续的接口。
  • 查询接口返回的 ID 用于更新或删除操作。
  • 多接口之间的数据依赖,比如依赖创建的资源进行操作。

2. 实现接口关联的常见方法

方法一:使用全局变量

直接使用全局变量存储接口返回值,供其他接口使用。

示例代码:

复制代码
import pytest
import requests

# 全局变量
global_data = {}

def test_login():
    url = "http://example.com/api/login"
    data = {"username": "user", "password": "pass"}
    response = requests.post(url, json=data)
    assert response.status_code == 200
    # 提取 token 并存储在全局变量中
    global_data["token"] = response.json().get("token")

def test_get_user_info():
    url = "http://example.com/api/user"
    headers = {"Authorization": f"Bearer {global_data['token']}"}
    response = requests.get(url, headers=headers)
    assert response.status_code == 200

优点:

  • 简单易用,适合小型测试场景。

缺点:

  • 全局变量可能导致测试数据污染,尤其在并发测试时。

方法二:使用 Fixture

通过 Pytest 的 Fixture 动态传递数据,避免全局变量的污染问题。

示例代码:

复制代码
import pytest
import requests

@pytest.fixture
def login():
    url = "http://example.com/api/login"
    data = {"username": "user", "password": "pass"}
    response = requests.post(url, json=data)
    assert response.status_code == 200
    # 返回 token
    return response.json().get("token")

def test_get_user_info(login):
    url = "http://example.com/api/user"
    headers = {"Authorization": f"Bearer {login}"}
    response = requests.get(url, headers=headers)
    assert response.status_code == 200

优点:

  • Fixture 的作用域可以控制数据的生命周期,适合中小型测试。
  • 代码结构清晰,易于维护。

缺点:

  • Fixture 的嵌套复杂性可能增加。

方法三:上下文管理(Context)

通过上下文类集中管理接口之间的关联数据,适合复杂项目。

示例代码:

复制代码
import pytest
import requests

class Context:
    def __init__(self):
        self.data = {}

    def set(self, key, value):
        self.data[key] = value

    def get(self, key):
        return self.data.get(key)

@pytest.fixture(scope="session")
def context():
    return Context()

def test_login(context):
    url = "http://example.com/api/login"
    data = {"username": "user", "password": "pass"}
    response = requests.post(url, json=data)
    assert response.status_code == 200
    # 存储 token
    context.set("token", response.json().get("token"))

def test_get_user_info(context):
    url = "http://example.com/api/user"
    headers = {"Authorization": f"Bearer {context.get('token')}"}
    response = requests.get(url, headers=headers)
    assert response.status_code == 200

优点:

  • 数据管理集中化,适合大型测试项目。
  • 支持复杂的关联数据。

缺点:

  • 代码稍微复杂,需要额外维护上下文类。

方法四:参数化动态传递数据

通过参数化结合接口调用动态传递数据。

示例代码:

复制代码
import pytest
import requests

def login():
    url = "http://example.com/api/login"
    data = {"username": "user", "password": "pass"}
    response = requests.post(url, json=data)
    assert response.status_code == 200
    return response.json().get("token")

@pytest.mark.parametrize("token", [login()])
def test_get_user_info(token):
    url = "http://example.com/api/user"
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(url, headers=headers)
    assert response.status_code == 200

优点:

  • 简洁,适合测试用例数量少的场景。

缺点:

  • 需要提前调用依赖接口,无法动态更新参数。

方法五:测试用例之间共享数据

通过 request.node 实现测试用例之间的数据共享。

示例代码:

复制代码
import pytest
import requests

@pytest.fixture(scope="module")
def shared_data(request):
    request.node.shared_data = {}
    return request.node.shared_data

def test_login(shared_data):
    url = "http://example.com/api/login"
    data = {"username": "user", "password": "pass"}
    response = requests.post(url, json=data)
    assert response.status_code == 200
    # 存储 token
    shared_data["token"] = response.json().get("token")

def test_get_user_info(shared_data):
    url = "http://example.com/api/user"
    headers = {"Authorization": f"Bearer {shared_data['token']}"}
    response = requests.get(url, headers=headers)
    assert response.status_code == 200

优点:

  • 测试用例之间可以共享数据。
  • 避免全局变量污染。

缺点:

  • 不支持多线程并发测试。

3. 各方法适用场景对比

方法 适用场景 优点 缺点
全局变量 简单的测试场景 实现简单快速 容易污染全局数据,线程不安全
Fixture 中小型测试项目 数据隔离性好,生命周期可控 嵌套复杂时维护困难
上下文管理 大型复杂测试项目 数据管理集中化,适合复杂数据共享 增加额外代码复杂性
参数化传递数据 测试用例较少的简单场景 代码简洁,适合批量测试 无法动态更新
用例之间共享数据 依赖较强的测试用例 避免全局变量污染,模块化强 不适合并发测试
相关推荐
@大迁世界7 分钟前
Vue 设计模式 实战指南
前端·javascript·vue.js·设计模式·ecmascript
程序新视界8 分钟前
MySQL中,IS NULL和IS NOT NULL不会走索引?错!
数据库·mysql·dba
tao35566713 分钟前
【Python刷力扣hot100】283. Move Zeroes
开发语言·python·leetcode
wdfk_prog21 分钟前
闹钟定时器(Alarm Timer)初始化:构建可挂起的定时器基础框架
java·linux·数据库
芭拉拉小魔仙29 分钟前
Vue项目中如何实现表格选中数据的 Excel 导出
前端·vue.js·excel
许长安29 分钟前
Redis(二)——Redis协议与异步方式
数据库·redis·junit
jump_jump1 小时前
妙用 localeCompare 获取汉字拼音首字母
前端·javascript·浏览器
小宁爱Python1 小时前
从零搭建 RAG 智能问答系统1:基于 LlamaIndex 与 Chainlit实现最简单的聊天助手
人工智能·后端·python
java_python源码1 小时前
python高校心理健康服务小程序(源码+文档+调试+基础修改+答疑)
数据库·sqlite
U.2 SSD1 小时前
Echarts单轴坐标系散点图
前端·javascript·echarts