You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pytest测试依赖型API的最佳实践及相关疑问

API测试实践与工具选型解答

一、创建行项目接口测试的最佳实践

针对POST /api/purchase-orders/line-item的测试,推荐使用Pytest Fixture封装依赖创建逻辑的方案,兼顾测试独立性与代码复用性,比你提到的两种单一方式更高效:

两种方案的优劣势对比

  • 在测试函数内直接创建依赖对象:
    优点是每个测试用例完全独立,不会受其他测试失败影响;缺点是重复代码多,测试执行时间长,且如果依赖创建逻辑复杂,会让测试函数臃肿,可读性差。
  • 独立测试文件创建后注入:
    优点是避免重复创建,但依赖对象的生命周期难控制,容易出现测试环境数据残留,且如果依赖测试失败,后续所有依赖它的测试都会失效,排查问题更麻烦。

推荐的Fixture实现方式

用Pytest的Fixture封装供应商、零件、服务订单的创建/清理逻辑,测试函数直接引用Fixture获取所需ID:

import pytest
import requests

# 封装供应商创建逻辑,模块级作用域,每个测试模块只创建一次
@pytest.fixture(scope="module")
def vendor_id():
    # 发送创建供应商请求
    create_response = requests.post("/api/vendors", json={"name": "Test_Vendor"})
    create_response.raise_for_status()
    vendor_data = create_response.json()
    vendor_id = vendor_data["id"]
    
    yield vendor_id  # 向测试函数返回ID
    
    # 测试完成后清理数据,避免环境污染
    delete_response = requests.delete(f"/api/vendors/{vendor_id}")
    delete_response.raise_for_status()

# 同理封装零件和服务订单的Fixture
@pytest.fixture(scope="module")
def part_id():
    create_response = requests.post("/api/parts", json={"name": "Test_Part"})
    create_response.raise_for_status()
    part_data = create_response.json()
    part_id = part_data["id"]
    
    yield part_id
    
    requests.delete(f"/api/parts/{part_id}").raise_for_status()

@pytest.fixture(scope="module")
def service_order_id():
    create_response = requests.post("/api/service-orders", json={"status": "pending"})
    create_response.raise_for_status()
    so_data = create_response.json()
    so_id = so_data["id"]
    
    yield so_id
    
    requests.delete(f"/api/service-orders/{so_id}").raise_for_status()

# 行项目测试函数
def test_line_item_creation(vendor_id, part_id, service_order_id):
    payload = {
        "service_order_id": service_order_id,
        "part_id": part_id,
        "vendor_id": vendor_id,
        "component": {
            "component_serial_number": "Test_SN",
            "component_name": "Test_Component",
        },
        "part_description": "Test_Part_Desc",
        "total_qty": 1,
    }
    
    response = requests.post("/api/purchase-orders/line-item", json=payload)
    # 断言状态码与返回数据
    assert response.status_code == 201
    line_item_data = response.json()
    assert line_item_data["service_order_id"] == service_order_id
    assert line_item_data["part_id"] == part_id
    assert line_item_data["vendor_id"] == vendor_id

这种方式的好处:

  • 测试函数只关注核心业务逻辑,代码简洁可读;
  • Fixture的作用域可灵活配置(如scope="session"适合全局共享的依赖);
  • 自带清理步骤,保证测试环境干净,避免数据干扰。

二、测试类型与Pytest适用性

  1. 测试类型判定:
    你当前的测试不属于单元测试,而是集成测试/API端到端测试。单元测试的核心是隔离外部依赖,测试单个函数或模块的逻辑;而你直接调用真实API,依赖多个服务模块的协作,属于验证系统各组件集成后的功能是否正常。

  2. Pytest的适用性:
    Pytest完全适合这类测试场景。它的Fixture机制完美解决依赖复用问题,支持参数化测试(比如测试不同数量的行项目、不同参数组合),断言语法灵活,还能配合插件生成测试报告、并行执行测试,完全能应对复杂API测试的需求。

内容的提问来源于stack exchange,提问作者Masterstack8080

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:47:27