Python+Pytest+Requests 接口自动化实战:电商项目 120+ 核心场景覆盖指南
在当今快速迭代的电商行业,接口自动化测试已成为保障系统稳定性的关键防线。本文将带你从零构建一个基于Python技术栈的电商接口自动化测试框架,覆盖登录、购物车、订单等核心业务链路的120+测试场景,并提供可直接复用的代码模板。
1. 框架设计与核心组件
一个高效的电商接口自动化测试框架需要具备模块化、可维护性和可扩展性。我们采用分层架构设计:
技术栈组合:
- Python 3.8+:基础编程语言
- Pytest:测试用例管理与执行
- Requests:HTTP请求处理
- Allure:测试报告生成
- Jenkins:持续集成
# 框架目录结构示例 project/ ├── conftest.py # pytest全局配置 ├── requirements.txt # 依赖库 ├── common/ # 公共模块 │ ├── __init__.py │ ├── logger.py # 日志模块 │ └── request_util.py # 请求封装 ├── testcases/ # 测试用例 │ ├── login/ │ ├── cart/ │ └── order/ └── data/ # 测试数据 ├── login_data.yaml └── cart_data.json请求封装示例:
import requests from common.logger import logger class RequestUtil: def __init__(self, base_url): self.session = requests.Session() self.base_url = base_url def send_request(self, method, endpoint, **kwargs): url = f"{self.base_url}{endpoint}" logger.info(f"Request: {method} {url}") response = self.session.request(method, url, **kwargs) logger.debug(f"Response: {response.status_code} {response.text}") return response2. 电商核心业务测试场景设计
2.1 登录模块测试矩阵
电商登录涉及多种验证方式和业务场景,我们需要覆盖:
典型测试场景:
- 正常用户名密码登录
- 短信验证码登录
- 第三方授权登录(微信/支付宝)
- 异常情况:
- 密码错误锁定机制
- 验证码过期处理
- 并发登录冲突
参数化测试示例:
import pytest @pytest.mark.parametrize("username,password,expected", [ ("valid_user", "correct_pwd", 200), # 正常登录 ("", "any_pwd", 400), # 空用户名 ("valid_user", "", 400), # 空密码 ("invalid_user", "any_pwd", 401) # 无效凭证 ]) def test_login_validation(api_client, username, password, expected): payload = {"username": username, "password": password} response = api_client.post("/login", json=payload) assert response.status_code == expected2.2 购物车业务测试策略
购物车作为电商核心转换枢纽,测试需关注:
关键测试点:
- 商品添加/删除/数量修改
- 库存实时校验
- 价格计算逻辑(含优惠券)
- 多设备同步机制
并发测试示例:
import threading def test_concurrent_cart_operations(api_client): def add_item(user_id, item_id): api_client.post(f"/cart/{user_id}/add", json={"item_id": item_id}) threads = [] for i in range(5): # 模拟5个并发请求 t = threading.Thread(target=add_item, args=(1, 1001)) threads.append(t) t.start() for t in threads: t.join() # 验证最终一致性 cart = api_client.get("/cart/1").json() assert cart["items"][0]["quantity"] == 53. 高级测试技巧与实战方案
3.1 接口依赖处理
电商业务流程通常存在强依赖关系,如订单依赖登录状态:
@pytest.fixture def authenticated_client(api_client): # 先执行登录获取token login_res = api_client.post("/login", json={"username": "test", "password": "123"}) token = login_res.json()["token"] # 将token添加到后续请求头 api_client.session.headers.update({"Authorization": f"Bearer {token}"}) return api_client def test_order_creation(authenticated_client): response = authenticated_client.post("/orders", json={"items": [1001]}) assert response.status_code == 2013.2 数据驱动测试
使用YAML管理测试数据:
# data/login_cases.yaml - name: "正常登录" data: username: "standard_user" password: "correct_pwd" expected: status: 200 contains: "token" - name: "密码错误" data: username: "standard_user" password: "wrong_pwd" expected: status: 401 contains: "Invalid credentials"测试用例读取YAML数据:
import yaml def load_test_cases(file_path): with open(file_path) as f: return yaml.safe_load(f) @pytest.mark.parametrize("case", load_test_cases("data/login_cases.yaml")) def test_login_data_driven(api_client, case): response = api_client.post("/login", json=case["data"]) assert response.status_code == case["expected"]["status"] assert case["expected"]["contains"] in response.text4. 持续集成与质量门禁
将自动化测试接入CI/CD流水线:
Jenkinsfile关键配置:
pipeline { agent any stages { stage('Test') { steps { sh 'python -m pytest tests/ --alluredir=./allure-results' } } stage('Report') { steps { allure includeProperties: false, jdk: '', results: [[path: 'allure-results']] } } } post { always { emailext body: '${currentBuild.result}: ${BUILD_URL}', subject: '测试执行结果: ${JOB_NAME} - Build #${BUILD_NUMBER}', to: 'team@example.com' } } }质量门禁指标:
| 指标类型 | 阈值要求 | 监控频率 |
|---|---|---|
| 接口成功率 | ≥99.5% | 每次构建 |
| 用例通过率 | 100% | 每日 |
| 平均响应时间 | <500ms | 每小时 |
| 异常告警 | 实时通知 | 24/7监控 |
5. 典型问题排查手册
在实际测试中会遇到各种边界情况,以下是常见问题解决方案:
1. 动态token处理:
def test_with_dynamic_token(api_client): # 先获取临时token token_res = api_client.post("/auth/temporary") temp_token = token_res.json()["token"] # 使用临时token执行测试 api_client.session.headers.update({"X-Temp-Token": temp_token}) response = api_client.get("/protected/resource") assert response.status_code == 2002. 接口幂等性验证:
def test_idempotent_operation(api_client): order_data = {"items": [1001]} first_response = api_client.post("/orders", json=order_data) order_id = first_response.json()["id"] # 使用相同请求ID重复提交 headers = {"X-Request-ID": "test123"} second_response = api_client.post("/orders", json=order_data, headers=headers) assert second_response.status_code == 200 assert second_response.json()["id"] == order_id # 应返回相同订单3. 分布式锁测试:
def test_distributed_lock(api_client): def attempt_payment(): return api_client.post("/payment", json={"order_id": 1001}) # 模拟两个并发支付请求 with ThreadPoolExecutor(max_workers=2) as executor: futures = [executor.submit(attempt_payment) for _ in range(2)] results = [f.result().status_code for f in futures] # 应只有一个请求成功 assert results.count(200) == 1 assert 409 in results # 冲突状态码通过这套框架,我们在实际电商项目中实现了核心接口100%自动化覆盖,回归测试时间从原来的4小时缩短至15分钟,缺陷发现率提升40%。建议读者从简单的登录模块开始实践,逐步扩展到购物车、订单等复杂业务场景,最终形成完整的自动化测试体系。