# 盘古用户平台 - 应用管理模块测试用例

---

| 文档信息 | 内容 |
|---------|------|
| **文档版本** | V1.0 |
| **模块名称** | 应用管理模块 |
| **编写团队 | pangu |
| **创建日期** | 2026-01-31 |
| **审核状态** | 待评审 |

---

## 1. 测试范围

### 1.1 功能测试

| 测试模块 | 测试内容 |
|---------|---------|
| 应用列表 | 列表展示、分页、搜索、筛选 |
| 新增应用 | 表单验证、编码生成、密钥生成 |
| 编辑应用 | 数据回显、表单验证、接口授权 |
| 删除应用 | 确认提示、软删除 |
| 重置密钥 | 确认提示、新密钥生成、复制功能 |
| 接口授权 | 授权选择、权限校验 |

### 1.2 接口测试

| 测试模块 | 测试内容 |
|---------|---------|
| 管理端接口 | CRUD接口、权限控制 |
| 开放API | 签名验证、时间戳验证、权限校验 |

### 1.3 边界测试

| 测试模块 | 测试内容 |
|---------|---------|
| 输入边界 | 字段长度限制、特殊字符 |
| 业务边界 | 名称重复、空数据处理 |

---

## 2. 功能测试用例

### 2.1 应用列表

| 用例编号 | TC-APP-001 |
|---------|-----------|
| 用例名称 | 查看应用列表 |
| 前置条件 | 1. 已登录超级管理员账号 2. 数据库有应用数据 |
| 测试步骤 | 1. 点击左侧菜单"应用管理" |
| 预期结果 | 1. 页面正常加载 2. 表格显示应用列表 3. 显示分页信息 |
| 优先级 | P0 |

| 用例编号 | TC-APP-002 |
|---------|-----------|
| 用例名称 | 按应用名称搜索 |
| 前置条件 | 1. 已进入应用列表页 2. 数据库有"AI智慧平台"应用 |
| 测试步骤 | 1. 在应用名称输入框输入"AI" 2. 点击搜索按钮 |
| 预期结果 | 1. 列表只显示名称包含"AI"的应用 2. 分页信息正确 |
| 优先级 | P0 |

| 用例编号 | TC-APP-003 |
|---------|-----------|
| 用例名称 | 按应用编码搜索 |
| 前置条件 | 1. 已进入应用列表页 2. 数据库有"YY000001"应用 |
| 测试步骤 | 1. 在应用编码输入框输入"YY000001" 2. 点击搜索按钮 |
| 预期结果 | 1. 列表只显示编码匹配的应用 |
| 优先级 | P0 |

| 用例编号 | TC-APP-004 |
|---------|-----------|
| 用例名称 | 按状态筛选 |
| 前置条件 | 1. 已进入应用列表页 2. 数据库有正常和停用的应用 |
| 测试步骤 | 1. 状态下拉选择"正常" 2. 点击搜索按钮 |
| 预期结果 | 1. 列表只显示状态为"正常"的应用 |
| 优先级 | P0 |

| 用例编号 | TC-APP-005 |
|---------|-----------|
| 用例名称 | 重置查询条件 |
| 前置条件 | 1. 已进入应用列表页 2. 已输入查询条件 |
| 测试步骤 | 1. 点击重置按钮 |
| 预期结果 | 1. 所有查询条件清空 2. 列表显示全部数据 |
| 优先级 | P1 |

| 用例编号 | TC-APP-006 |
|---------|-----------|
| 用例名称 | 分页功能 |
| 前置条件 | 1. 已进入应用列表页 2. 数据库有超过10条应用 |
| 测试步骤 | 1. 点击第2页 2. 修改每页条数为20 |
| 预期结果 | 1. 显示第2页数据 2. 每页显示20条 3. 分页信息正确 |
| 优先级 | P1 |

| 用例编号 | TC-APP-007 |
|---------|-----------|
| 用例名称 | 授权接口标签展示 |
| 前置条件 | 1. 已进入应用列表页 2. 应用有4个以上授权接口 |
| 测试步骤 | 1. 查看授权接口列 |
| 预期结果 | 1. 显示前3个接口标签 2. 显示"+N"表示剩余数量 |
| 优先级 | P1 |

---

### 2.2 新增应用

| 用例编号 | TC-APP-010 |
|---------|-----------|
| 用例名称 | 新增应用成功 |
| 前置条件 | 1. 已登录超级管理员账号 2. 已进入应用列表页 |
| 测试步骤 | 1. 点击"新增"按钮 2. 输入应用名称"测试应用" 3. 输入应用描述 4. 输入联系人和电话 5. 选择状态"正常" 6. 勾选2个接口授权 7. 点击"确定" |
| 预期结果 | 1. 提示"新增成功" 2. 弹窗关闭 3. 列表刷新显示新应用 4. 应用编码格式正确（YY+6位序号） |
| 优先级 | P0 |

| 用例编号 | TC-APP-011 |
|---------|-----------|
| 用例名称 | 应用名称必填验证 |
| 前置条件 | 1. 已打开新增弹窗 |
| 测试步骤 | 1. 不输入应用名称 2. 点击"确定" |
| 预期结果 | 1. 提示"请输入应用名称" 2. 表单不提交 |
| 优先级 | P0 |

| 用例编号 | TC-APP-012 |
|---------|-----------|
| 用例名称 | 应用名称长度验证 |
| 前置条件 | 1. 已打开新增弹窗 |
| 测试步骤 | 1. 输入超过100个字符的应用名称 2. 点击"确定" |
| 预期结果 | 1. 提示"应用名称不能超过100个字符" |
| 优先级 | P1 |

| 用例编号 | TC-APP-013 |
|---------|-----------|
| 用例名称 | 应用名称重复验证 |
| 前置条件 | 1. 数据库已有"AI智慧平台"应用 |
| 测试步骤 | 1. 打开新增弹窗 2. 输入应用名称"AI智慧平台" 3. 点击"确定" |
| 预期结果 | 1. 提示"应用名称已存在" |
| 优先级 | P0 |

| 用例编号 | TC-APP-014 |
|---------|-----------|
| 用例名称 | 联系电话格式验证 |
| 前置条件 | 1. 已打开新增弹窗 |
| 测试步骤 | 1. 输入应用名称 2. 联系电话输入"12345" 3. 点击"确定" |
| 预期结果 | 1. 提示"请输入正确的手机号" |
| 优先级 | P1 |

| 用例编号 | TC-APP-015 |
|---------|-----------|
| 用例名称 | 应用编码自动生成 |
| 前置条件 | 1. 数据库最大编码为YY000005 |
| 测试步骤 | 1. 新增一个应用 |
| 预期结果 | 1. 新应用编码为YY000006 |
| 优先级 | P0 |

| 用例编号 | TC-APP-016 |
|---------|-----------|
| 用例名称 | 取消新增 |
| 前置条件 | 1. 已打开新增弹窗 2. 已填写部分信息 |
| 测试步骤 | 1. 点击"取消"按钮 |
| 预期结果 | 1. 弹窗关闭 2. 不保存数据 |
| 优先级 | P1 |

---

### 2.3 编辑应用

| 用例编号 | TC-APP-020 |
|---------|-----------|
| 用例名称 | 编辑应用成功 |
| 前置条件 | 1. 数据库有应用数据 |
| 测试步骤 | 1. 点击某应用的"编辑"按钮 2. 修改应用名称 3. 修改接口授权 4. 点击"确定" |
| 预期结果 | 1. 提示"修改成功" 2. 列表刷新显示修改后的数据 |
| 优先级 | P0 |

| 用例编号 | TC-APP-021 |
|---------|-----------|
| 用例名称 | 编辑数据回显 |
| 前置条件 | 1. 数据库有完整信息的应用 |
| 测试步骤 | 1. 点击某应用的"编辑"按钮 |
| 预期结果 | 1. 弹窗显示 2. 所有字段正确回显 3. 应用编码只读 4. 接口授权正确勾选 |
| 优先级 | P0 |

| 用例编号 | TC-APP-022 |
|---------|-----------|
| 用例名称 | 编辑时应用编码不可修改 |
| 前置条件 | 1. 已打开编辑弹窗 |
| 测试步骤 | 1. 尝试修改应用编码 |
| 预期结果 | 1. 应用编码输入框为禁用状态 2. 无法输入 |
| 优先级 | P0 |

| 用例编号 | TC-APP-023 |
|---------|-----------|
| 用例名称 | 编辑时修改接口授权 |
| 前置条件 | 1. 应用已授权"学校接口"和"年级接口" |
| 测试步骤 | 1. 打开编辑弹窗 2. 取消"年级接口"勾选 3. 勾选"学生接口" 4. 点击"确定" |
| 预期结果 | 1. 修改成功 2. 应用只有"学校接口"和"学生接口"权限 |
| 优先级 | P0 |

---

### 2.4 删除应用

| 用例编号 | TC-APP-030 |
|---------|-----------|
| 用例名称 | 删除应用成功 |
| 前置条件 | 1. 数据库有应用数据 |
| 测试步骤 | 1. 点击某应用的"删除"按钮 2. 在确认弹窗点击"确定" |
| 预期结果 | 1. 提示"删除成功" 2. 列表刷新，该应用不再显示 |
| 优先级 | P0 |

| 用例编号 | TC-APP-031 |
|---------|-----------|
| 用例名称 | 删除确认取消 |
| 前置条件 | 1. 数据库有应用数据 |
| 测试步骤 | 1. 点击某应用的"删除"按钮 2. 在确认弹窗点击"取消" |
| 预期结果 | 1. 弹窗关闭 2. 应用数据保留 |
| 优先级 | P1 |

| 用例编号 | TC-APP-032 |
|---------|-----------|
| 用例名称 | 删除为软删除 |
| 前置条件 | 1. 数据库有应用数据 |
| 测试步骤 | 1. 删除某应用 2. 查询数据库pg_application表 |
| 预期结果 | 1. 数据库记录仍存在 2. del_flag字段值为"1" |
| 优先级 | P1 |

---

### 2.5 重置密钥

| 用例编号 | TC-APP-040 |
|---------|-----------|
| 用例名称 | 重置密钥成功 |
| 前置条件 | 1. 数据库有应用数据 |
| 测试步骤 | 1. 点击某应用的"重置密钥"按钮 2. 在确认弹窗点击"确定" |
| 预期结果 | 1. 提示"密钥重置成功" 2. 弹出密钥展示弹窗 3. 显示新密钥（32位） |
| 优先级 | P0 |

| 用例编号 | TC-APP-041 |
|---------|-----------|
| 用例名称 | 重置密钥确认取消 |
| 前置条件 | 1. 数据库有应用数据 |
| 测试步骤 | 1. 点击某应用的"重置密钥"按钮 2. 在确认弹窗点击"取消" |
| 预期结果 | 1. 弹窗关闭 2. 密钥未变更 |
| 优先级 | P1 |

| 用例编号 | TC-APP-042 |
|---------|-----------|
| 用例名称 | 复制密钥功能 |
| 前置条件 | 1. 已重置密钥 2. 密钥展示弹窗已打开 |
| 测试步骤 | 1. 点击"复制"按钮 |
| 预期结果 | 1. 提示"复制成功" 2. 剪贴板包含密钥内容 |
| 优先级 | P0 |

| 用例编号 | TC-APP-043 |
|---------|-----------|
| 用例名称 | 旧密钥失效验证 |
| 前置条件 | 1. 记录应用旧密钥 2. 已重置密钥 |
| 测试步骤 | 1. 使用旧密钥调用开放API |
| 预期结果 | 1. 返回"签名验证失败" |
| 优先级 | P0 |

---

### 2.6 接口授权

| 用例编号 | TC-APP-050 |
|---------|-----------|
| 用例名称 | 接口授权列表显示 |
| 前置条件 | 1. 已打开新增/编辑弹窗 |
| 测试步骤 | 1. 查看接口授权区域 |
| 预期结果 | 1. 显示所有可授权的接口 2. 每个接口有复选框 |
| 优先级 | P0 |

| 用例编号 | TC-APP-051 |
|---------|-----------|
| 用例名称 | 授权接口可调用 |
| 前置条件 | 1. 应用已授权"学校接口" |
| 测试步骤 | 1. 使用该应用密钥调用/open/school/list接口 |
| 预期结果 | 1. 接口调用成功 2. 返回学校数据 |
| 优先级 | P0 |

| 用例编号 | TC-APP-052 |
|---------|-----------|
| 用例名称 | 未授权接口不可调用 |
| 前置条件 | 1. 应用未授权"学生接口" |
| 测试步骤 | 1. 使用该应用密钥调用/open/student/list接口 |
| 预期结果 | 1. 返回"无权访问该接口" |
| 优先级 | P0 |

---

## 3. 接口测试用例

### 3.1 管理端接口

| 用例编号 | TC-API-001 |
|---------|-----------|
| 用例名称 | 获取应用列表接口 |
| 接口地址 | GET /api/application/list |
| 请求参数 | pageNum=1&pageSize=10 |
| 预期响应 | code=200, rows数组, total>=0 |
| 优先级 | P0 |

| 用例编号 | TC-API-002 |
|---------|-----------|
| 用例名称 | 获取应用详情接口 |
| 接口地址 | GET /api/application/{appId} |
| 请求参数 | appId=1 |
| 预期响应 | code=200, data包含应用完整信息 |
| 优先级 | P0 |

| 用例编号 | TC-API-003 |
|---------|-----------|
| 用例名称 | 新增应用接口 |
| 接口地址 | POST /api/application |
| 请求参数 | {"appName":"测试应用","status":"0","apiCodes":["SCHOOL_LIST"]} |
| 预期响应 | code=200, data包含appCode和appSecret |
| 优先级 | P0 |

| 用例编号 | TC-API-004 |
|---------|-----------|
| 用例名称 | 修改应用接口 |
| 接口地址 | PUT /api/application |
| 请求参数 | {"appId":1,"appName":"修改后名称","apiCodes":["SCHOOL_LIST","GRADE_LIST"]} |
| 预期响应 | code=200 |
| 优先级 | P0 |

| 用例编号 | TC-API-005 |
|---------|-----------|
| 用例名称 | 删除应用接口 |
| 接口地址 | DELETE /api/application/{appId} |
| 请求参数 | appId=1 |
| 预期响应 | code=200 |
| 优先级 | P0 |

| 用例编号 | TC-API-006 |
|---------|-----------|
| 用例名称 | 重置密钥接口 |
| 接口地址 | PUT /api/application/resetSecret/{appId} |
| 请求参数 | appId=1 |
| 预期响应 | code=200, data包含appSecret |
| 优先级 | P0 |

| 用例编号 | TC-API-007 |
|---------|-----------|
| 用例名称 | 未登录访问管理接口 |
| 接口地址 | GET /api/application/list |
| 请求头 | 无Authorization |
| 预期响应 | code=401 |
| 优先级 | P0 |

---

### 3.2 开放API接口

| 用例编号 | TC-OPEN-001 |
|---------|-----------|
| 用例名称 | 签名验证成功 |
| 接口地址 | GET /open/school/list |
| 请求头 | X-App-Id, X-Timestamp, X-Sign(正确签名) |
| 预期响应 | code=200, 返回数据 |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-002 |
|---------|-----------|
| 用例名称 | 缺少X-App-Id |
| 接口地址 | GET /open/school/list |
| 请求头 | 无X-App-Id |
| 预期响应 | code=500, msg="缺少认证参数" |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-003 |
|---------|-----------|
| 用例名称 | 缺少X-Timestamp |
| 接口地址 | GET /open/school/list |
| 请求头 | 无X-Timestamp |
| 预期响应 | code=500, msg="缺少认证参数" |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-004 |
|---------|-----------|
| 用例名称 | 缺少X-Sign |
| 接口地址 | GET /open/school/list |
| 请求头 | 无X-Sign |
| 预期响应 | code=500, msg="缺少认证参数" |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-005 |
|---------|-----------|
| 用例名称 | 签名错误 |
| 接口地址 | GET /open/school/list |
| 请求头 | X-Sign=错误的签名 |
| 预期响应 | code=500, msg="签名验证失败" |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-006 |
|---------|-----------|
| 用例名称 | 时间戳过期 |
| 接口地址 | GET /open/school/list |
| 请求头 | X-Timestamp=10分钟前的时间戳 |
| 预期响应 | code=500, msg="请求已过期" |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-007 |
|---------|-----------|
| 用例名称 | 应用不存在 |
| 接口地址 | GET /open/school/list |
| 请求头 | X-App-Id=不存在的编码 |
| 预期响应 | code=500, msg="应用不存在" |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-008 |
|---------|-----------|
| 用例名称 | 应用已停用 |
| 前置条件 | 应用状态为停用 |
| 接口地址 | GET /open/school/list |
| 预期响应 | code=500, msg="应用已停用" |
| 优先级 | P0 |

| 用例编号 | TC-OPEN-009 |
|---------|-----------|
| 用例名称 | 无接口权限 |
| 前置条件 | 应用未授权学生接口 |
| 接口地址 | GET /open/student/list |
| 预期响应 | code=500, msg="无权访问该接口" |
| 优先级 | P0 |

---

## 4. 边界测试用例

### 4.1 输入边界

| 用例编号 | TC-BOUND-001 |
|---------|-----------|
| 用例名称 | 应用名称最大长度 |
| 测试数据 | 100个字符的应用名称 |
| 预期结果 | 保存成功 |
| 优先级 | P1 |

| 用例编号 | TC-BOUND-002 |
|---------|-----------|
| 用例名称 | 应用名称超过最大长度 |
| 测试数据 | 101个字符的应用名称 |
| 预期结果 | 提示长度超限 |
| 优先级 | P1 |

| 用例编号 | TC-BOUND-003 |
|---------|-----------|
| 用例名称 | 应用描述最大长度 |
| 测试数据 | 500个字符的描述 |
| 预期结果 | 保存成功 |
| 优先级 | P1 |

| 用例编号 | TC-BOUND-004 |
|---------|-----------|
| 用例名称 | 特殊字符处理 |
| 测试数据 | 应用名称包含<script>alert(1)</script> |
| 预期结果 | 保存成功，内容被转义 |
| 优先级 | P1 |

| 用例编号 | TC-BOUND-005 |
|---------|-----------|
| 用例名称 | 空格处理 |
| 测试数据 | 应用名称"  测试应用  "（前后有空格） |
| 预期结果 | 空格被trim处理 |
| 优先级 | P2 |

---

### 4.2 业务边界

| 用例编号 | TC-BOUND-010 |
|---------|-----------|
| 用例名称 | 无授权接口的应用 |
| 测试数据 | 不勾选任何接口授权 |
| 预期结果 | 保存成功，应用无法调用任何开放API |
| 优先级 | P1 |

| 用例编号 | TC-BOUND-011 |
|---------|-----------|
| 用例名称 | 全部授权的应用 |
| 测试数据 | 勾选所有接口授权 |
| 预期结果 | 保存成功，应用可调用所有开放API |
| 优先级 | P1 |

| 用例编号 | TC-BOUND-012 |
|---------|-----------|
| 用例名称 | 空列表显示 |
| 前置条件 | 数据库无应用数据 |
| 预期结果 | 表格显示空状态，分页显示0条 |
| 优先级 | P2 |

---

## 5. 性能测试用例

| 用例编号 | TC-PERF-001 |
|---------|-----------|
| 用例名称 | 列表查询响应时间 |
| 测试场景 | 数据库有1000条应用记录 |
| 性能指标 | 响应时间 ≤ 500ms |
| 优先级 | P1 |

| 用例编号 | TC-PERF-002 |
|---------|-----------|
| 用例名称 | 签名验证响应时间 |
| 测试场景 | 连续100次开放API调用 |
| 性能指标 | 单次验证 ≤ 50ms |
| 优先级 | P1 |

| 用例编号 | TC-PERF-003 |
|---------|-----------|
| 用例名称 | 并发访问 |
| 测试场景 | 50个并发请求应用列表 |
| 性能指标 | 无错误，响应时间 ≤ 1s |
| 优先级 | P2 |

---

## 6. 权限测试用例

| 用例编号 | TC-PERM-001 |
|---------|-----------|
| 用例名称 | 超级管理员访问 |
| 前置条件 | 使用超级管理员账号登录 |
| 测试步骤 | 访问应用管理页面 |
| 预期结果 | 正常访问，可执行所有操作 |
| 优先级 | P0 |

| 用例编号 | TC-PERM-002 |
|---------|-----------|
| 用例名称 | 分公司用户访问 |
| 前置条件 | 使用分公司用户账号登录 |
| 测试步骤 | 访问应用管理页面 |
| 预期结果 | 无权限访问，显示无权限提示或菜单不可见 |
| 优先级 | P0 |

| 用例编号 | TC-PERM-003 |
|---------|-----------|
| 用例名称 | 学校用户访问 |
| 前置条件 | 使用学校用户账号登录 |
| 测试步骤 | 访问应用管理页面 |
| 预期结果 | 无权限访问 |
| 优先级 | P0 |

---

## 7. 测试数据

### 7.1 基础测试数据

```sql
-- 测试应用数据
INSERT INTO pg_application (app_id, app_code, app_name, app_secret, status, create_time) VALUES
(1, 'YY000001', 'AI智慧平台', 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6', '0', NOW()),
(2, 'YY000002', '在线课堂系统', 'b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7', '0', NOW()),
(3, 'YY000003', '停用测试应用', 'c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8', '1', NOW());

-- 测试接口授权数据
INSERT INTO pg_app_api (app_id, api_code, api_name, api_path) VALUES
(1, 'SCHOOL_LIST', '查询学校信息', '/open/school/list'),
(1, 'GRADE_LIST', '查询年级信息', '/open/grade/list'),
(1, 'CLASS_LIST', '查询班级信息', '/open/class/list'),
(2, 'STUDENT_LIST', '查询学生信息', '/open/student/list'),
(2, 'MEMBER_LIST', '查询会员信息', '/open/member/list');
```

### 7.2 签名测试数据

```
应用编码：YY000001
应用密钥：a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
时间戳：1706716800000 (2026-01-31 12:00:00)
请求参数：pageNum=1&pageSize=10

签名字符串：pageNum=1&pageSize=10&appSecret=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
MD5签名：E5D7C6B5A4F3E2D1C0B9A8F7E6D5C4B3（示例）
```

---

## 8. 测试环境要求

| 项目 | 要求 |
|------|------|
| 浏览器 | Chrome 最新版 |
| 后端服务 | 已部署并正常运行 |
| 数据库 | MySQL 8.0，已初始化测试数据 |
| Redis | 已启动 |
| 测试账号 | 超级管理员、分公司用户、学校用户各一个 |

---

## 9. 缺陷等级定义

| 等级 | 定义 | 处理要求 |
|------|------|---------|
| **致命** | 系统崩溃、数据丢失、核心功能无法使用 | 立即修复 |
| **严重** | 主要功能异常、数据错误 | 当天修复 |
| **一般** | 次要功能异常、UI问题 | 3天内修复 |
| **建议** | 优化建议、体验问题 | 下版本修复 |

---

*文档结束*
