语研社・研管中心:从需求文档到完整测试体系的实践之路
大家好呀!之前结合AI完成了一个教育培训机构管理系统 ——语研社・研管中心,自己完成了相关的测试工作。区别于简单的“点点点”,我更希望从业务视角出发,构建一套能提前发现风险、保障核心链路稳定的测试体系。
这篇文章将复盘我是如何从两份核心文档(用户规格说明书、API接口文档)出发,通过“业务分析 -> 用例设计 -> 自动化落地(pytest+requests+YAML+Allure)”的路径, 最终为这个项目交付了一套可靠的质量保障方案的。
感兴趣的话一起来看看吧~
一、项目背景
语研社・研管中心是一款面向英语培训机构的后台管理系统,采用前后端分离架构(Vite + TypeScript + Express),包含以下核心模块:
①登录认证模块
②学员管理模块
③课程管理模块
④订单管理模块
⑤合同管理模块
UI 设计采用了弥散彩虹玻璃效果,视觉效果非常精美。
二、测试需求分析
2.1 研读用户规格说明书
拿到项目后,第一步是仔细阅读用户规格说明书,重点关注:
核心功能点提取:
①验证码获取与刷新
②用户登录 / 登出
③学员信息 CRUD(增删改查)
④课程信息管理与上下架
⑤订单创建、支付、取消
⑥合同激活、终止、课时扣减
⑦数据统计与概览
业务规则梳理:
①验证码必填(可选)验证
②金额计算逻辑:final_price = original_price - discount_amount
③金额不能为负数
④分页参数边界处理
⑤状态枚举值限制
2.2 分析 API 接口文档
API 接口文档定义了 29 个接口,我按照模块进行了如下分类:

三、测试用例设计
3.1 功能测试用例设计
基于用户规格说明书,我设计了11 大模块,100 + 条功能测试用例:
测试覆盖维度:
- 正常功能流程
- 边界条件测试(空值、超长、负数、零值)
- 异常输入测试(格式错误、类型错误)
- 数据验证(字段类型、长度、枚举值)
- UI/UX 测试(玻璃拟态效果、交互反馈)
- 响应式测试(不同屏幕尺寸)
- 性能测试(页面加载、查询响应)
关键测试用例示例:
| 模块 | 测试场景 | 预期结果 |
|---|---|---|
| 登录 | 验证码错误 | 返回 "验证码错误",不能登录 |
| 学员管理 | 姓名为空 | 参数验证失败,提示 "姓名不能为空" |
| 学员管理 | 手机号格式错误 | 验证失败,提示 "手机号格式不正确" |
| 课程管理 | 价格为负数 | 验证失败,提示 "价格必须大于 0" |
| 订单管理 | 折扣大于原价 | 实付金额为 0,不能为负数 |
| 订单管理 | 金额精度 | 保留 2 位小数,不能有精度丢失 |
3.2 接口测试用例设计
基于 API 接口文档,我设计了11 大测试模块,300 + 条接口测试用例:
接口测试覆盖维度:
- 功能测试(正常业务流程)
- 参数验证(必填项、类型、格式、长度、枚举)
- 边界测试(分页参数、金额范围、数量限制)
- 异常测试(400/401/404/500 错误)
- 业务逻辑测试(金额计算、状态变更、数据一致性)
- 安全测试(认证、授权、SQL 注入、XSS)
- 性能测试(响应时间、并发、大数据量)
核心接口测试用例示例:
登录接口测试:
正常登录 - 用户名+密码+正确验证码
密码错误 - 返回"用户名或密码错误"
验证码错误 - 返回"验证码错误"
用户名为空 - 参数验证失败
不带token访问需要认证的接口 - 返回401
订单创建接口测试:
正常创建订单 - 成功返回订单ID
金额计算验证 - final_price = original_price - discount_amount
折扣大于原价 - final_price = 0(不能为负)
原价为负数 - 参数验证失败
学员不存在 - 返回404或业务错误
浮点数精度 - 0.1+0.2正确计算为0.3
学员列表接口测试:
正常分页查询 - page=1, page_size=10
page=0 - 自动调整为page=1
page_size=1000 - 限制为最大100条
page=-1 - 参数验证失败
筛选功能 - 按name/phone/status筛选
数据验证 - 字段类型正确、枚举值合法
四、接口自动化测试框架搭建
4.1 技术选型
基于项目需求和团队技术栈,我选择了以下技术组合:
| 组件 | 选型 | 说明 |
|---|---|---|
| 测试框架 | pytest | Python 生态最流行的测试框架 |
| HTTP 客户端 | requests | 简单易用的 HTTP 请求库 |
| 测试数据 | YAML | 人类可读的数据格式 |
| 测试报告 | Allure | 可视化测试报告,支持 Feature/Story 分层 |
4.2 项目结构设计
tests/
├── README.md # 使用说明
├── requirements.txt # Python依赖
├── pytest.ini # pytest配置
├── conftest.py # pytest fixtures配置
├── data/
│ └── test_data.yaml # YAML测试数据
├── test_auth.py # 认证模块测试
├── test_students.py # 学员管理测试
├── test_courses.py # 课程管理测试
└── test_orders.py # 订单管理测试
4.3 核心代码实现
4.3.1 pytest 配置 (pytest.ini)
[pytest]
testpaths = tests
python_files = test_*.py
addopts =
-v
--alluredir=./allure-results
--clean-alluredir
markers =
smoke: 冒烟测试用例
regression: 回归测试用例
auth: 认证模块测试
students: 学员管理测试
4.3.2 Fixtures 配置 (conftest.py)
@pytest.fixture(scope="session")
def base_url(env):
urls = {
"test": "http://localhost:5000",
"staging": "https://staging.your-domain.com"
}
return urls.get(env, urls["test"])
@pytest.fixture(scope="module")
def auth_token(base_url, test_data):
login_data = test_data["auth"]["login_success"]
response = requests.post(f"{base_url}/api/auth/login", json=login_data)
return response.json().get("data", {}).get("access_token")
@pytest.fixture(scope="function")
def auth_headers(auth_token):
return {
"Authorization": f"Bearer {auth_token}",
"Content-Type": "application/json"
}
4.3.3 YAML 测试数据管理
auth:
login_success:
username: "admin"
password: "admin123"
captcha: "ABCD"
login_wrong_password:
username: "admin"
password: "wrongpassword"
students:
create_valid:
name: "测试学员"
gender: "male"
phone: "13800138001"
create_empty_name:
name: ""
gender: "male"
phone: "13800138002"
orders:
create_valid:
student_id: 1
course_id: 1
original_price: 1000
discount_amount: 100
create_discount_exceeds:
student_id: 1
course_id: 1
original_price: 1000
discount_amount: 2000
4.3.4 测试用例编写 (Allure 装饰器)
@allure.feature("学员管理")
@allure.story("学员CRUD操作")
class TestStudents:
@title("新增学员-正常流程")
@severity(severity_level.CRITICAL)
@pytest.mark.smoke
@pytest.mark.students
def test_create_student_success(self, base_url, auth_headers, test_data):
with step("准备学员数据"):
student_data = test_data["students"]["create_valid"]
with step("发送新增请求"):
response = requests.post(
f"{base_url}/api/students",
headers=auth_headers,
json=student_data
)
with step("验证响应"):
assert response.status_code == 200
result = response.json()
assert result.get("success") is True
4.4 测试执行与报告
运行测试:
# 运行所有测试
pytest
# 运行冒烟测试
pytest -m smoke
# 运行特定模块
pytest -m students
# 生成Allure报告
pytest
allure serve allure-results
Allure 报告特性:
- Feature/Story 分层展示
- 测试步骤详细记录
- 测试结果统计图表
- 测试执行时间统计
- 精美的可视化界面
五、Bug 发现与深度分析
在测试过程中,我累计发现了13 个高质量 Bug,并进行了深度分析:
5.1 Bug 分类统计
| Bug 类型 | 数量 | 严重程度 |
|---|---|---|
| 功能测试 Bug | 5 个 | 严重 2 个,中等 2 个,轻微 1 个 |
| 接口测试 Bug | 5 个 | 严重 2 个,中等 2 个,轻微 1 个 |
| 自动化测试 Bug | 3 个 | 中等 2 个,轻微 1 个 |
| 总计 | 13 个 | 严重 4 个,中等 6 个,轻微 3 个 |
5.2 典型 Bug 深度分析
Bug #1: 登录接口验证码验证逻辑缺陷(严重)
问题描述:
登录接口的验证码验证逻辑存在缺陷,即使传入错误的验证码,接口仍然返回登录成功。
根因分析:
// 错误的实现
if (captcha) {
// 这里没有实际验证逻辑!
}
return success;
// 应该的实现
if (captcha) {
const sessionCaptcha = req.session.captcha;
if (captcha !== sessionCaptcha) {
return { code: 400, message: '验证码错误' };
}
}
安全风险:
- 验证码形同虚设
- 恶意用户可以暴力破解密码
- 账户安全受到严重威胁
Bug #2: 订单创建接口金额计算错误(严重)
问题描述:
- final_price 计算逻辑写反了:
final_price = original_price + discount_amount - 当 discount_amount > original_price 时,final_price 变成负数
- 浮点数精度丢失:0.1+0.2=0.30000000000000004
根因分析:
// 错误的实现
const final_price = original_price + discount_amount; // 写反了!
// 正确的实现 - 使用整数计算避免精度问题
const originalPriceCent = Math.round(original_price * 100);
const discountAmountCent = Math.round(discount_amount * 100);
let finalPriceCent = originalPriceCent - discountAmountCent;
if (finalPriceCent < 0) finalPriceCent = 0; // 保护不为负
const final_price = finalPriceCent / 100;
业务影响:
- 财务风险极高,直接影响营收
- 可能出现负金额订单,引起客户投诉
Bug #3: 自动化测试脚本登录流程不稳定(中等)
问题描述:
自动化测试的登录流程成功率只有 70%,失败原因包括:
- OCR 识别验证码准确率只有 80%
- 验证码过期问题
- 缺少重试机制
解决方案:
// 测试环境提供专用接口
async function login() {
if (process.env.NODE_ENV === 'test') {
const res = await axios.post('/api/auth/test-token', {
username: 'admin'
});
return res.data.data.access_token;
}
}
六、测试成果总结
6.1 测试交付物
| 交付物 | 说明 |
|---|---|
| 功能测试用例思维导图 | 11 大模块,100 + 测试用例 |
| 接口测试用例思维导图 | 11 大模块,300 + 测试用例 |
| 接口自动化测试框架 | pytest+requests+YAML+Allure |
| Bug 报告 | 13 个高质量 Bug,含根因分析和修复建议 |
6.2 测试覆盖
- 功能测试覆盖:100% 核心业务流程
- 接口测试覆盖:100%(29/29)API 接口
- 自动化测试覆盖:核心接口 33 个自动化用例
- 边界测试覆盖:空值、超长、负数、零值等场景
- 异常测试覆盖:400/401/404/500 错误处理
6.3 改进建议
在测试过程中,我向团队提出了以下建议并被采纳:
- 统一接口响应格式:制定响应格式规范,确保文档与实际一致
- 建立标准测试音频样本库:(虽然是教育系统,但同理)建立标准测试数据集
- 使用事务回滚清理测试数据:自动化测试使用数据库事务,避免脏数据
- 添加完整的参数验证层:使用 Zod 或 Joi 进行输入验证
- 金额使用整数计算:分为单位计算,避免浮点数精度问题
七、个人收获
通过这个项目,我在以下几个方面有了很大收获:
7.1 测试思维提升
1.从需求文档到测试用例的转化能力
2.边界条件和异常场景的敏感度
3.业务逻辑的深度理解能力
7.2 技术能力提升
1.pytest+requests+Allure 自动化框架实战经验
2.YAML 数据驱动测试实践
3.接口测试深度设计能力
4.Bug 根因分析方法论
7.3 软技能提升
1.测试文档的编写与组织
2.Bug 报告的深度分析与清晰描述
3.与开发团队的有效沟通
4.改进建议的推动与落地
结语
测试工作不仅仅是 "找 Bug",更重要的是:
- 预防 Bug:通过测试左移,在需求和设计阶段就发现问题
- 保障质量:建立完整的测试体系,确保产品质量
- 推动改进:发现问题的同时,提供改进建议和最佳实践
- 赋能团队:通过自动化测试提升团队效率
希望这篇文章对你有所帮助!如果你也在做类似的测试项目,欢迎交流讨论。我们下次再见,拜拜~
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)