学校管理模块 - 测试方案
| 文档信息 |
内容 |
| 文档版本 |
V1.0 |
| 模块名称 |
学校管理模块 |
| 编写团队 |
pangu |
| 创建日期 |
2026-01-31 |
1. 测试概述
1.1 测试目标
- 验证学校管理模块所有功能按需求规格正确实现
- 验证业务规则正确执行
- 验证接口响应符合设计规范
- 验证数据权限控制有效
- 验证前端交互体验符合原型设计
1.2 测试范围
| 功能点 |
测试类型 |
优先级 |
| 学校树查询 |
接口测试、UI测试 |
P0 |
| 学校列表查询 |
接口测试、UI测试 |
P0 |
| 新增学校 |
接口测试、UI测试 |
P0 |
| 编辑学校 |
接口测试、UI测试 |
P0 |
| 删除学校 |
接口测试、UI测试 |
P0 |
| 挂载年级 |
接口测试、UI测试 |
P0 |
| 挂载班级 |
接口测试、UI测试 |
P0 |
| 删除年级 |
接口测试、UI测试 |
P1 |
| 删除班级 |
接口测试、UI测试 |
P1 |
| 数据权限 |
接口测试 |
P0 |
| 表单验证 |
UI测试 |
P0 |
1.3 测试环境
| 环境 |
说明 |
| 前端 |
Chrome 120+, Edge 120+ |
| 后端 |
Java 17, Spring Boot 3.3.x |
| 数据库 |
MySQL 8.0 |
| 测试工具 |
Postman, JUnit 5 |
2. 接口测试用例
2.1 获取学校树
接口地址: GET /api/school/tree
| 用例编号 |
用例名称 |
请求参数 |
预期结果 |
| API-SCH-001 |
查询全部学校树 |
无 |
返回所有学校树形结构 |
| API-SCH-002 |
按区域查询学校树 |
regionId=111 |
返回武昌区下学校树 |
| API-SCH-003 |
查询无学校的区域 |
regionId=999 |
返回空数组 |
API-SCH-001 详细用例
请求:GET /api/school/tree
Header: Authorization: Bearer {token}
预期响应:
{
"code": 200,
"msg": "查询成功",
"data": [
{
"id": 1,
"type": "school",
"name": "武汉市第一中学",
"code": "SCH20260001",
"status": "0",
"regionPath": "湖北省-武汉市-武昌区",
"children": [
{
"id": 1,
"type": "grade",
"name": "七年级",
"schoolGradeId": 1,
"gradeId": 7,
"children": [
{
"id": 1,
"type": "class",
"name": "1班",
"schoolClassId": 1,
"classId": 1
}
]
}
]
}
]
}
验证点:
1. 返回code为200
2. data为数组格式
3. 学校节点包含type="school"
4. 年级节点包含type="grade"
5. 班级节点包含type="class"
6. 层级关系正确
2.2 新增学校
接口地址: POST /api/school
| 用例编号 |
用例名称 |
请求参数 |
预期结果 |
| API-SCH-010 |
正常新增学校 |
必填项完整 |
成功,学校编码自动生成 |
| API-SCH-011 |
缺少学校名称 |
schoolName为空 |
失败,返回验证错误 |
| API-SCH-012 |
缺少所属区域 |
regionId为空 |
失败,返回验证错误 |
| API-SCH-013 |
缺少学校类型 |
schoolType为空 |
失败,返回验证错误 |
| API-SCH-014 |
学校名称超长 |
101个字符 |
失败,返回验证错误 |
API-SCH-010 详细用例
请求:POST /api/school
Header:
Authorization: Bearer {token}
Content-Type: application/json
Body:
{
"schoolName": "武汉市测试中学",
"schoolType": "02",
"regionId": 111,
"address": "武昌区测试路1号",
"contactPerson": "张老师",
"contactPhone": "13812345678",
"status": "0"
}
预期响应:
{
"code": 200,
"msg": "操作成功"
}
验证点:
1. 返回code为200
2. 数据库中新增一条学校记录
3. school_code格式为SCH2026xxxx
4. region_path自动填充为"湖北省-武汉市-武昌区"
5. del_flag为'0'
6. create_time和create_by已填充
API-SCH-011 详细用例
请求:POST /api/school
Body:
{
"schoolName": "",
"schoolType": "02",
"regionId": 111
}
预期响应:
{
"code": 400,
"msg": "学校名称不能为空"
}
验证点:
1. 返回code为400
2. msg包含错误提示
3. 数据库未新增记录
2.3 修改学校
接口地址: PUT /api/school
| 用例编号 |
用例名称 |
请求参数 |
预期结果 |
| API-SCH-020 |
正常修改学校 |
合法参数 |
成功 |
| API-SCH-021 |
修改不存在的学校 |
schoolId=999 |
失败 |
| API-SCH-022 |
修改区域后更新路径 |
regionId变更 |
成功,region_path更新 |
API-SCH-020 详细用例
请求:PUT /api/school
Body:
{
"schoolId": 1,
"schoolName": "武汉市第一中学(新)",
"schoolType": "02",
"regionId": 111,
"status": "0"
}
预期响应:
{
"code": 200,
"msg": "操作成功"
}
验证点:
1. 返回code为200
2. 数据库school_name已更新
3. update_time和update_by已更新
2.4 删除学校
接口地址: DELETE /api/school/{schoolId}
| 用例编号 |
用例名称 |
前置条件 |
预期结果 |
| API-SCH-030 |
删除无子级的学校 |
学校无年级/班级 |
成功 |
| API-SCH-031 |
删除有年级的学校 |
学校下有年级 |
失败,提示有年级 |
| API-SCH-032 |
删除有学生的学校 |
学校被学生引用 |
失败,提示被引用 |
| API-SCH-033 |
删除不存在的学校 |
schoolId=999 |
失败 |
API-SCH-031 详细用例
前置条件:
- 学校ID=1下有年级数据
请求:DELETE /api/school/1
预期响应:
{
"code": 500,
"msg": "该学校下存在年级数据,请先删除年级"
}
验证点:
1. 返回code非200
2. msg包含错误提示
3. 数据库记录未删除
API-SCH-032 详细用例
前置条件:
- 学校ID=2无年级数据
- 学校ID=2被学生信息引用
请求:DELETE /api/school/2
预期响应:
{
"code": 500,
"msg": "该学校已被学生信息引用,无法删除"
}
验证点:
1. 返回code非200
2. 数据库记录未删除
2.5 挂载年级
接口地址: POST /api/school/bindGrades
| 用例编号 |
用例名称 |
请求参数 |
预期结果 |
| API-SCH-040 |
正常挂载年级 |
schoolId + gradeIds |
成功 |
| API-SCH-041 |
重复挂载年级 |
已存在的gradeId |
成功,忽略重复 |
| API-SCH-042 |
空年级列表 |
gradeIds为空数组 |
失败,验证错误 |
| API-SCH-043 |
挂载到不存在的学校 |
schoolId=999 |
失败 |
API-SCH-040 详细用例
请求:POST /api/school/bindGrades
Body:
{
"schoolId": 1,
"gradeIds": [1, 2, 3]
}
预期响应:
{
"code": 200,
"msg": "操作成功"
}
验证点:
1. 返回code为200
2. pg_school_grade表新增3条记录
3. school_id和grade_id关联正确
API-SCH-041 详细用例
前置条件:
- 学校ID=1已挂载年级ID=1
请求:POST /api/school/bindGrades
Body:
{
"schoolId": 1,
"gradeIds": [1, 4, 5]
}
预期响应:
{
"code": 200,
"msg": "操作成功"
}
验证点:
1. 返回成功
2. 新增2条记录(年级4、5)
3. 年级1不重复插入
2.6 挂载班级
接口地址: POST /api/school/bindClasses
| 用例编号 |
用例名称 |
请求参数 |
预期结果 |
| API-SCH-050 |
正常挂载班级 |
schoolGradeId + classIds |
成功 |
| API-SCH-051 |
重复挂载班级 |
已存在的classId |
成功,忽略重复 |
| API-SCH-052 |
挂载到不存在的年级 |
schoolGradeId=999 |
失败 |
2.7 删除学校年级
接口地址: DELETE /api/school/grade/{schoolGradeId}
| 用例编号 |
用例名称 |
前置条件 |
预期结果 |
| API-SCH-060 |
删除无班级的年级 |
年级下无班级 |
成功 |
| API-SCH-061 |
删除有班级的年级 |
年级下有班级 |
失败,提示有班级 |
| API-SCH-062 |
删除被学生引用的年级 |
年级被学生引用 |
失败,提示被引用 |
2.8 删除学校班级
接口地址: DELETE /api/school/class/{schoolClassId}
| 用例编号 |
用例名称 |
前置条件 |
预期结果 |
| API-SCH-070 |
删除未被引用的班级 |
班级未被学生引用 |
成功 |
| API-SCH-071 |
删除被学生引用的班级 |
班级被学生引用 |
失败,提示被引用 |
2.9 数据权限测试
| 用例编号 |
用例名称 |
测试账号 |
预期结果 |
| API-SCH-080 |
超级管理员查看全部 |
admin |
返回所有学校 |
| API-SCH-081 |
分公司用户查看所属区域 |
武汉分公司用户 |
只返回武汉区域学校 |
| API-SCH-082 |
分公司用户新增学校 |
武汉分公司用户 |
只能选择所属区域 |
| API-SCH-083 |
学校用户无权限 |
学校用户 |
菜单不显示或403 |
3. 功能测试用例
3.1 页面加载
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-001 |
页面正常加载 |
访问学校管理页面 |
页面正常显示 |
| UI-SCH-002 |
区域树加载 |
进入页面 |
左侧显示区域树 |
| UI-SCH-003 |
学校树加载 |
进入页面 |
右侧显示学校树 |
| UI-SCH-004 |
加载状态显示 |
刷新页面 |
显示加载中状态 |
3.2 区域树操作
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-010 |
区域树展开收起 |
点击父节点图标 |
子节点展开/收起 |
| UI-SCH-011 |
区域节点选中 |
点击区域节点 |
节点高亮,学校列表刷新 |
| UI-SCH-012 |
多次点击相同节点 |
重复点击同一节点 |
不重复请求 |
3.3 学校树操作
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-020 |
学校树展开 |
点击学校行展开图标 |
显示年级和班级 |
| UI-SCH-021 |
学校树收起 |
点击已展开学校的图标 |
年级班级收起 |
| UI-SCH-022 |
显示学校编码 |
查看学校行 |
学校行显示编码 |
| UI-SCH-023 |
年级班级无编码 |
查看年级/班级行 |
编码列显示"-" |
3.4 新增学校
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-030 |
打开新增弹窗 |
点击"新增学校"按钮 |
弹窗显示 |
| UI-SCH-031 |
区域默认值 |
先选择区域树节点,再点击新增 |
所属区域默认带入 |
| UI-SCH-032 |
表单验证-必填 |
留空必填项,点击确定 |
显示验证提示 |
| UI-SCH-033 |
表单验证-手机号 |
输入错误格式手机号 |
显示格式错误提示 |
| UI-SCH-034 |
正常新增 |
填写完整信息,点击确定 |
成功提示,列表刷新 |
| UI-SCH-035 |
取消新增 |
点击取消按钮 |
弹窗关闭,无数据变化 |
3.5 编辑学校
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-040 |
打开编辑弹窗 |
点击学校行"编辑"按钮 |
弹窗显示,数据回填 |
| UI-SCH-041 |
学校编码只读 |
查看编辑弹窗 |
学校编码不可修改 |
| UI-SCH-042 |
修改学校名称 |
修改名称,点击确定 |
成功,列表数据更新 |
| UI-SCH-043 |
修改所属区域 |
修改区域,点击确定 |
成功,区域路径更新 |
3.6 删除学校
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-050 |
删除确认弹窗 |
点击"删除"按钮 |
显示确认对话框 |
| UI-SCH-051 |
取消删除 |
确认框点击取消 |
对话框关闭,数据不变 |
| UI-SCH-052 |
确认删除成功 |
确认删除无关联学校 |
成功提示,列表刷新 |
| UI-SCH-053 |
删除失败提示 |
确认删除有关联学校 |
显示错误提示 |
3.7 挂载年级
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-060 |
打开年级选择弹窗 |
点击学校行"新增年级" |
弹窗显示年级列表 |
| UI-SCH-061 |
已挂载年级禁用 |
查看弹窗 |
已挂载的年级显示禁用 |
| UI-SCH-062 |
多选年级 |
勾选多个年级 |
支持多选 |
| UI-SCH-063 |
确认挂载 |
选择年级,点击确定 |
成功,学校树刷新 |
| UI-SCH-064 |
未选择年级确认 |
不选择年级,点击确定 |
提示请选择年级 |
3.8 挂载班级
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-070 |
打开班级选择弹窗 |
点击年级行"新增班级" |
弹窗显示班级列表 |
| UI-SCH-071 |
已挂载班级禁用 |
查看弹窗 |
已挂载的班级显示禁用 |
| UI-SCH-072 |
确认挂载班级 |
选择班级,点击确定 |
成功,学校树刷新 |
3.9 删除年级/班级
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-080 |
删除年级确认 |
点击年级行"删除" |
显示确认对话框 |
| UI-SCH-081 |
删除年级失败 |
确认删除有班级的年级 |
显示错误提示 |
| UI-SCH-082 |
删除年级成功 |
确认删除无班级的年级 |
成功,学校树刷新 |
| UI-SCH-083 |
删除班级 |
点击班级行"删除"并确认 |
成功,学校树刷新 |
3.10 搜索功能
| 用例编号 |
用例名称 |
测试步骤 |
预期结果 |
| UI-SCH-090 |
按名称搜索 |
输入学校名称,点击搜索 |
列表过滤 |
| UI-SCH-091 |
按状态搜索 |
选择状态,点击搜索 |
列表过滤 |
| UI-SCH-092 |
组合搜索 |
输入名称+选择状态 |
列表过滤 |
| UI-SCH-093 |
重置搜索 |
点击重置按钮 |
清空条件,显示全部 |
| UI-SCH-094 |
无结果提示 |
搜索不存在的学校 |
显示"暂无数据" |
4. 边界测试
4.1 数据边界
| 用例编号 |
用例名称 |
测试数据 |
预期结果 |
| BD-SCH-001 |
学校名称最大长度 |
100个中文字符 |
成功 |
| BD-SCH-002 |
学校名称超长 |
101个中文字符 |
验证失败 |
| BD-SCH-003 |
空学校列表 |
新区域无学校 |
显示空状态 |
| BD-SCH-004 |
大量学校 |
100所学校 |
正常显示,无卡顿 |
| BD-SCH-005 |
深层级结构 |
学校-12年级-10班级 |
正常展开显示 |
4.2 并发测试
| 用例编号 |
用例名称 |
测试场景 |
预期结果 |
| CC-SCH-001 |
同时新增学校 |
2个用户同时新增 |
编码不冲突 |
| CC-SCH-002 |
同时挂载年级 |
2个用户同时挂载相同年级 |
不重复插入 |
5. 测试数据准备
5.1 测试账号
| 角色 |
账号 |
密码 |
权限 |
| 超级管理员 |
admin |
admin123 |
全部权限 |
| 武汉分公司用户 |
wuhan_user |
123456 |
武汉区域数据 |
| 学校用户 |
school_user |
123456 |
本校数据 |
5.2 测试数据
-- 测试区域
INSERT INTO pg_region VALUES (1, 0, '湖北', 1, '0', 1, '0');
INSERT INTO pg_region VALUES (11, 1, '武汉', 2, '0,1', 1, '0');
INSERT INTO pg_region VALUES (111, 11, '武昌区', 3, '0,1,11', 1, '0');
-- 测试学校
INSERT INTO pg_school VALUES (1, 'SCH20260001', '测试学校A', '02', 111, '湖北省-武汉市-武昌区', '0', '0');
INSERT INTO pg_school VALUES (2, 'SCH20260002', '测试学校B', '02', 111, '湖北省-武汉市-武昌区', '0', '0');
-- 测试年级
INSERT INTO pg_grade VALUES (1, 'GRD001', '一年级', 1, '0', '0');
INSERT INTO pg_grade VALUES (7, 'GRD007', '七年级', 7, '0', '0');
-- 测试班级
INSERT INTO pg_class VALUES (1, 'CLS001', '1班', 1, '0', '0');
INSERT INTO pg_class VALUES (2, 'CLS002', '2班', 2, '0', '0');
-- 测试关联
INSERT INTO pg_school_grade VALUES (1, 1, 7, 1, '0', '0');
INSERT INTO pg_school_class VALUES (1, 1, 1, 1, '0', '0');
6. 缺陷管理
6.1 缺陷等级定义
| 等级 |
说明 |
处理时限 |
| P0 |
阻塞性缺陷,功能完全不可用 |
立即修复 |
| P1 |
严重缺陷,核心功能受影响 |
1个工作日 |
| P2 |
一般缺陷,功能可用但有问题 |
3个工作日 |
| P3 |
轻微缺陷,体验问题 |
下个版本 |
6.2 缺陷跟踪
| 缺陷编号 |
标题 |
等级 |
发现人 |
发现日期 |
状态 |
修复人 |
验证人 |
|
|
|
|
|
|
|
|
7. 测试报告模板
7.1 测试概要
| 项目 |
内容 |
| 测试模块 |
学校管理 |
| 测试版本 |
|
| 测试周期 |
|
| 测试人员 |
|
7.2 测试结果
| 测试类型 |
用例数 |
通过 |
失败 |
阻塞 |
通过率 |
| 接口测试 |
|
|
|
|
|
| 功能测试 |
|
|
|
|
|
| 边界测试 |
|
|
|
|
|
| 合计 |
|
|
|
|
|
7.3 缺陷统计
| 等级 |
发现数 |
已修复 |
待修复 |
验证通过 |
| P0 |
|
|
|
|
| P1 |
|
|
|
|
| P2 |
|
|
|
|
| P3 |
|
|
|
|
7.4 测试结论
文档结束