玩界WanJie购物商城接口自动化项目架构介绍
一.项目介绍
基于Python+pytest+sqlalchemy+requests+allure+jsonpath+yaml+Jenkins+Linux
该项目是⼀个专注于游戏生态的在线购物平台,致力于为全球玩家打造⼀站式的购物体验。平台涵盖热门游戏本体、电竞外设、虚拟道具、会员订阅、游戏周边等丰富商品,⽀持用户注册、登录、商品浏览、下单支付、商家上架/下架管理等功能模块
二.项目结构说明
点击查看代码
project-root/ # 项目根目录
├─ base/ # 基础类封装(核心功能)
│ ├─ api_request.py # 接口请求基类(封装requests)
│ ├─ test_case_tools.py # 测试用例工具类(如数据处理、断言)
│ └─ driver.py # 浏览器驱动封装(可选,UI自动化用)
├─ common/ # 公共方法封装(可复用工具)
│ ├─ log_utils.py # 日志处理工具
│ ├─ excel_parser.py # Excel数据解析工具
│ ├─ yaml_parser.py # YAML数据解析工具
│ └─ db_operation.py # 数据库操作工具(如MySQL)
├─ conf/ # 全局配置目录
│ ├─ config.ini # 环境配置文件(API地址、账号等)
│ ├─ allure_config.yml # Allure报告自定义配置
│ └─ env.py # 环境变量管理文件
├─ data/ # 测试数据目录
│ ├─ api_data/ # 接口测试数据
│ │ ├─ login_data.yaml # 登录接口测试用例数据
│ │ └─ order_data.xlsx # 订单接口Excel数据
│ └─ ui_data/ # UI自动化测试数据(可选)
│ └─ page_elements.yaml # 页面元素定位数据
├─ logs/ # 测试日志目录(自动生成)
│ └─ test_20231001.log # 按日期命名的日志文件
├─ report/ # 测试报告目录
│ ├─ allure_html/ # Allure交互式报告(自动生成)
│ ├─ tm_report/ # TMReport表格报告(自动生成)
│ └─ report_config.py # 报告生成配置文件
├─ testcase/ # 测试用例目录
│ ├─ api_test/ # 接口测试用例
│ │ ├─ test_login.py # 登录接口测试类
│ │ └─ test_order.py # 订单接口测试类
│ └─ ui_test/ # UI自动化测试用例(可选)
│ └─ test_homepage.py # 首页UI测试类
├─ venv/ # 虚拟环境目录(自动生成)
├─ conftest.py # pytest全局钩子文件(固定名称)
├─ environment.xml # Allure报告环境信息文件
├─ extract.yaml # 接口依赖参数存储文件
├─ pytest.ini # pytest配置文件(固定名称)
├─ requirements.txt # 第三方库依赖清单
└─ run.py # 主程序入口(执行测试和生成报告)
三.核心代码
1.程序入口 run.py
点击查看代码
import shutil
import pytest
import os
import webbrowser
from conf.setting import REPORT_TYPE
if __name__ == '__main__':
if REPORT_TYPE == 'allure':
pytest.main(
['-s', '-v', '--alluredir=./report/temp', './testcase', '--clean-alluredir',
'--junitxml=./report/results.xml'])
shutil.copy('./environment.xml', './report/temp')
os.system(f'allure serve ./report/temp')
elif REPORT_TYPE == 'tm':
pytest.main(['-vs', '--pytest-tmreport-name=testReport.html', '--pytest-tmreport-path=./report/tmreport'])
webbrowser.open_new_tab(os.getcwd() + '/report/tmreport/testReport.html')
代码说明:
主程序入口
if __name__ == '__main__':
- Python 标准写法,表示当脚本作为主程序运行时才执行以下代码块。
- 防止模块被其他脚本导入时意外执行测试逻辑。
Allure报告处理逻辑
点击查看代码
if REPORT_TYPE == 'allure':
pytest.main(
['-s', '-v', '--alluredir=./report/temp', './testcase', '--clean-alluredir',
'--junitxml=./report/results.xml'])
参数说明:
| 参数 | 含义 |
|---|---|
| -s | 输出所有打印信息(不屏蔽 stdout) |
| -v | 显示详细测试结果 |
| --alluredir=./report/temp | 将 Allure 报告数据保存到指定目录 |
| ./testcase | 指定测试用例所在目录 |
| --clean-alluredir | 在每次运行前清空之前的报告数据 |
| --junitxml=./report/results.xml | 生成 JUnit XML 格式的测试结果文件 |
shutil.copy('./environment.xml', './report/temp')
- 复制环境信息文件 environment.xml 到报告目录中。
- Allure 报告会读取此文件并显示当前测试环境信息。
os.system(f'allure serve ./report/temp')
- 使用 Allure CLI 命令启动本地服务器并展示生成的报告页面。
- 会在默认浏览器中自动打开报告。
2.测试用例testcase
商务管理代码示例:
点击查看代码
import allure
import pytest
from common.readyaml import get_testcase_yaml
from base.apiutil_business import RequestBase
from base.generateId import m_id, c_id
# 注意:业务场景的接口测试要调用base目录下的apiutil_business文件
@allure.feature(next(m_id) + '电子商务管理系统(业务场景)')
class TestEBusinessScenario:
@allure.story(next(c_id) + '商品列表到下单支付流程')
@pytest.mark.parametrize('case_info', get_testcase_yaml('./testcase/Business interface/BusinessScenario.yml'))
def test_business_scenario(self, case_info):
allure.dynamic.title(case_info['baseInfo']['api_name'])
RequestBase().specification_yaml(case_info)
代码说明:
@pytest.mark.parametrize 参数化装饰器
@pytest.mark.parametrize('case_info', get_testcase_yaml('./testcase/Business interface/BusinessScenario.yml'))
作用:
- 实现参数化测试,即一个测试方法可以运行多组不同的输入数据。
- 每一组 case_info 数据都会触发一次完整的测试执行。
参数说明:
- 'case_info':表示每组测试数据的变量名,在测试函数中作为参数使用。
- get_testcase_yaml(...):调用函数读取指定路径下的 YAML 文件内容,返回一个包含多个测试用例的列表。
测试方法定义
def test_business_scenario(self, case_info):
- 这是一个 pytest 测试方法,每个参数化的 case_info 都会触发一次该方法的执行。
- self 表示这是类中的一个实例方法(属于 TestEBusinessScenario 类)。
- case_info 是从 YAML 文件中加载的一条测试用例的数据字典。
执行接口请求和校验
RequestBase().specification_yaml(case_info)
作用:
- 创建 RequestBase 实例,并调用其 specification_yaml() 方法。
- 该方法接收当前的测试用例数据 case_info,并根据其中的配置(如 URL、方法、请求头、预期结果等)发送 HTTP 请求。
- 同时会进行响应断言、日志记录等操作,完成整个接口测试流程。
3.接口测试 specification_yaml() 方法
该方法用于处理 YAML 文件中定义的接口测试用例,包括请求参数构造、动态变量替换、接口调用、响应断言以及数据提取等核心功能。
点击查看代码
def specification_yaml(self, base_info, test_case):
"""
接口请求处理基本方法
:param base_info: yaml文件里面的baseInfo
:param test_case: yaml文件里面的testCase
:return:
"""
try:
params_type = ['data', 'json', 'params']
url_host = self.conf.get_section_for_data('api_envi', 'host')
api_name = base_info['api_name']
allure.attach(api_name, f'接口名称:{api_name}', allure.attachment_type.TEXT)
url = url_host + base_info['url']
allure.attach(api_name, f'接口地址:{url}', allure.attachment_type.TEXT)
method = base_info['method']
allure.attach(api_name, f'请求方法:{method}', allure.attachment_type.TEXT)
header = self.replace_load(base_info['header'])
allure.attach(api_name, f'请求头:{header}', allure.attachment_type.TEXT)
# 处理cookie
cookie = None
if base_info.get('cookies') is not None:
cookie = eval(self.replace_load(base_info['cookies']))
case_name = test_case.pop('case_name')
allure.attach(api_name, f'测试用例名称:{case_name}', allure.attachment_type.TEXT)
# 处理断言
val = self.replace_load(test_case.get('validation'))
test_case['validation'] = val
validation = eval(test_case.pop('validation'))
# 处理参数提取
extract = test_case.pop('extract', None)
extract_list = test_case.pop('extract_list', None)
# 处理接口的请求参数
for key, value in test_case.items():
if key in params_type:
test_case[key] = self.replace_load(value)
# 处理文件上传接口
file, files = test_case.pop('files', None), None
if file is not None:
for fk, fv in file.items():
allure.attach(json.dumps(file), '导入文件')
files = {fk: open(fv, mode='rb')}
res = self.run.run_main(name=api_name, url=url, case_name=case_name, header=header, method=method,
file=files, cookies=cookie, **test_case)
status_code = res.status_code
allure.attach(self.allure_attach_response(res.json()), '接口响应信息', allure.attachment_type.TEXT)
try:
res_json = json.loads(res.text) # 把json格式转换成字典字典
if extract is not None:
self.extract_data(extract, res.text)
if extract_list is not None:
self.extract_data_list(extract_list, res.text)
# 处理断言
self.asserts.assert_result(validation, res_json, status_code)
except JSONDecodeError as js:
logs.error('系统异常或接口未请求!')
raise js
except Exception as e:
logs.error(e)
raise e
except Exception as e:
raise e
四.自动化测试实践
测试用例

实现代码
点击查看代码
import allure
import pytest
from base.generateId import m_id, c_id
from base.apiutil import RequestBase
from common.readyaml import get_testcase_yaml
@allure.feature(next(m_id) + '商品管理(单接口)')
class TestLogin:
@allure.story(next(c_id) + "获取商品列表")
@pytest.mark.run(order=1)
@pytest.mark.parametrize('base_info,testcase', get_testcase_yaml('./testcase/ProductManager/getProductList.yaml'))
def test_get_product_list(self, base_info, testcase):
allure.dynamic.title(testcase['case_name'])
RequestBase().specification_yaml(base_info, testcase)
@allure.story(next(c_id) + "获取商品详情信息")
@pytest.mark.run(order=2)
@pytest.mark.parametrize('base_info,testcase', get_testcase_yaml('./testcase/ProductManager/productDetail.yaml'))
def test_get_product_detail(self, base_info, testcase):
allure.dynamic.title(testcase['case_name'])
RequestBase().specification_yaml(base_info, testcase)
# @allure.story('检查接口状态')
# @pytest.mark.parametrize('params', get_testcase_yaml('./testcase/productManager/apiType.yaml'))
# def test_get_api_type(self, params):
# RequestBase().specification_yaml(params)
#
# @allure.story('电网系统登录校验')
# @pytest.mark.parametrize('params', get_testcase_yaml('./testcase/productManager/login_dw.yaml'))
# def test_get_login_dw(self, params):
# RequestBase().specification_yaml(params)
@allure.story(next(c_id) + "提交订单")
@pytest.mark.run(order=3)
@pytest.mark.parametrize('base_info,testcase', get_testcase_yaml('./testcase/ProductManager/commitOrder.yaml'))
def test_commit_order(self, base_info, testcase):
allure.dynamic.title(testcase['case_name'])
RequestBase().specification_yaml(base_info, testcase)
@allure.story(next(c_id) + "订单支付")
@pytest.mark.run(order=4)
@pytest.mark.parametrize('base_info,testcase', get_testcase_yaml('./testcase/ProductManager/orderPay.yaml'))
def test_order_pay(self, base_info, testcase):
allure.dynamic.title(testcase['case_name'])
RequestBase().specification_yaml(base_info, testcase)
测试报告

五.结语
本项目基于 pytest + Allure 构建了一套完整、稳定、可扩展的接口自动化测试框架,适用于电商系统的业务流程测试。通过数据驱动、变量替换、断言机制、报告可视化等功能,有效提高了测试效率与质量。未来将持续优化,提升其通用性与智能化水平。

浙公网安备 33010602011771号