pangu-user-platform/docs/03-测试文档/H5接口测试报告.md

706 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# H5 接口测试报告
> 测试时间2026-02-02
> 测试人员pangu
> 测试手机号15889762069
---
## 一、测试环境
| 项目 | 值 |
|------|-----|
| 后端地址 | http://localhost:8080 |
| 短信模式 | enabled: true |
| 测试手机号 | 15889762069 |
---
## 二、测试用例执行
### B1: 获取区域树
**请求:**
```
GET /h5/base/regions
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": [
{
"regionCode": null,
"regionId": "2018256469153099778",
"level": 1,
"regionName": "\u5317\u4eac\u5e02"
},
{
"regionCode": "420000",
"regionId": 420000,
"level": 1,
"children": [
{
"regionCode": "420100",
"regionId": 420100,
"level": 2,
"children": [
{
"regionCode": "420102",
"regionId": 420102,
"level": 3,
"regionName": "\u6c5f\u5cb8\u533a"
},
{
"regionCode": "420103",
"regionId": 420103,
"level": 3,
"regionName": "\u6c5f\u6c49\u533a"
},
{
"regionCode": "420104",
"regionId": 420104,
"level": 3,
"regionName": "\u785a\u53e3\u533a"
}
],
"regionName": "\u6b66\u6c49\u5e02"
}
],
"regionName": "\u6e56\u5317\u7701"
}
]
}
```
**结果:** ✅ 通过
---
### B2: 获取学校列表
**请求:**
```
GET /h5/base/schools?regionId=2018256469153099778
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": []
}
```
**结果:** ✅ 通过
---
### B3: 获取年级列表
**请求:**
```
GET /h5/base/grades?schoolId=
```
**响应:**
```json
{
"code": 500,
"msg": "Required request parameter 'schoolId' for method parameter type Long is present but converted to null",
"data": null
}
```
**结果:** ❌ 失败
---
### B2: 获取学校列表(修正)
**请求:**
```
GET /h5/base/schools?regionId=420100
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": [
{
"schoolId": 5,
"schoolName": "\u534e\u4e2d\u79d1\u6280\u5927\u5b66\u9644\u5c5e\u4e2d\u5b66",
"schoolCode": "WHDX001"
}
]
}
```
**结果:** ✅ 通过
---
### B3: 获取年级列表
**请求:**
```
GET /h5/base/grades?schoolId=5
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": [
{
"gradeName": "\u9ad8\u4e00",
"gradeId": 10,
"schoolGradeId": 19
},
{
"gradeName": "\u9ad8\u4e8c",
"gradeId": 11,
"schoolGradeId": 20
},
{
"gradeName": "\u9ad8\u4e09",
"gradeId": 12,
"schoolGradeId": 21
}
]
}
```
**结果:** ✅ 通过
---
### B4: 获取班级列表
**请求:**
```
GET /h5/base/classes?schoolGradeId=19
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": []
}
```
**结果:** ✅ 通过
---
### B5: 获取学科列表
**请求:**
```
GET /h5/base/subjects
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": [
{
"subjectCode": "SUB001",
"subjectId": 1,
"subjectName": "\u8bed\u6587"
},
{
"subjectCode": "SUB002",
"subjectId": 2,
"subjectName": "\u6570\u5b66"
},
{
"subjectCode": "SUB003",
"subjectId": 3,
"subjectName": "\u82f1\u8bed"
},
{
"subjectCode": "SUB004",
"subjectId": 4,
"subjectName": "\u7269\u7406"
},
{
"subjectCode": "SUB005",
"subjectId": 5,
"subjectName": "\u5316\u5b66"
},
{
"subjectCode": "SUB007",
"subjectId": 7,
"subjectName": "\u5386\u53f2"
},
{
"subjectCode": "SUB008",
"subjectId": 8,
"subjectName": "\u5730\u7406"
},
{
"subjectCode": "SUB009",
"subjectId": 9,
"subjectName": "\u653f\u6cbb"
}
]
}
```
**结果:** ✅ 通过
---
### A1: 获取图形验证码
**请求:**
```
GET /h5/auth/captcha
```
**响应:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"uuid": "9c9447e9ffd445d2b039b05ef9fee639",
"captchaImg": "iVBORw0KGgoAAAANSUhEUgAAAKAAAAA8CAYAAADha7EVAAAL+U...(Base64图片已截断)"
}
}
```
**结果:** ✅ 通过
---
### A2: 发送注册短信验证码
**请求:**
```
POST /h5/auth/sms/send
Content-Type: application/json
{
"phone": "15889762069",
"captchaCode": "5",
"uuid": "e091ad4af7f349edaaf1cdcad8764176",
"type": "register"
}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": null
}
```
**结果:** ✅ 通过(短信已发送)
---
### A3: 用户注册
**步骤:**
1. 从Redis获取短信验证码: 395910
2. 获取新的图形验证码
3. 执行注册
**请求:**
```
POST /h5/auth/register
Content-Type: application/json
{
"phone": "15889762069",
"smsCode": "395910",
"captchaCode": "0",
"uuid": "a7a535e63ac6487594a0d19fd56990d4",
"password": "Test123456"
}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjIwMTgzMjQ5ODQ3MTUzMTMxNTMsInJuU3RyIjoiaW9BUEJWdXpzOFVoZnMxcU9WSm9lNUlCcDY2Wm41T0wifQ.nE-NCSIgQV_4dDk3AT9BVJj2aMLzjkx3o7hoQjtRSBI",
"refreshToken": "58d9711f8b8c4d7faba360a583e7e8be",
"expiresIn": 7200,
"memberId": "2018324984715313153",
"memberCode": "M17700411496756880",
"phone": "158****2069",
"nickname": "user_2069",
"identityType": null
}
}
```
**结果:** ✅ 通过(注册成功)
---
### A4: 发送登录短信验证码
**请求:**
```
POST /h5/auth/sms/send
Content-Type: application/json
{
"phone": "15889762069",
"captchaCode": "5",
"uuid": "532fe00e25cd44bfaeeb9879f1ece68b",
"type": "login"
}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": null
}
```
**结果:** ✅ 通过
---
### A5: 短信验证码登录
**请求:**
```
POST /h5/auth/login/sms
Content-Type: application/json
{
"phone": "15889762069",
"smsCode": "836517",
"captchaCode": "4",
"uuid": "d9859b1f4df5429e971e6cd90bb72409"
}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjIwMTgzMjQ5ODQ3MTUzMTMxNTMsInJuU3RyIjoiUWJpWFZDNkNxbFJRV2JRT2lqY1hXd0VlMmJHRXZUWlYifQ.RTwB9OdnUwpieg4wqtzGRvE0Sd1bAcVu3DbbXwqmm-A",
"refreshToken": "11523f0716bc4fbf8e173ea7ce461d86",
"expiresIn": 7200,
"memberId": "2018324984715313153",
"memberCode": "M17700411496756880",
"phone": "158****2069",
"nickname": "user_2069",
"identityType": "1"
}
}
```
**结果:** ✅ 通过
---
### A6: 密码登录
**请求:**
```
POST /h5/auth/login/password
Content-Type: application/json
{
"phone": "15889762069",
"password": "Test123456",
"captchaCode": "2",
"uuid": "63dfd908814d496e88bbe6cd3ca24b52",
"rememberMe": false
}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjIwMTgzMjQ5ODQ3MTUzMTMxNTMsInJuU3RyIjoicVZTWE51Y1BZbnV2TDZzMVREc2kwSnBRWGQ5OFd2RHYifQ.pmAmEH_Z-eJSA8edo5q0vbBS64ix4wx1f8p--Ph23i4",
"refreshToken": "bce1eed54c73426f8bb7519bd10f8e35",
"expiresIn": 7200,
"memberId": "2018324984715313153",
"memberCode": "M17700411496756880",
"phone": "158****2069",
"nickname": "user_2069",
"identityType": "1"
}
}
```
**结果:** ✅ 通过
---
### M1: 获取会员信息
**请求:**
```
GET /h5/member/info
Authorization: Bearer {accessToken}
```
**响应:**
```json
{
"code": 500,
"msg": "Cannot invoke \"Object.toString()\" because the return value of \"cn.dev33.satoken.stp.StpUtil.getExtra(String)\" is null",
"data": null
}
```
**结果:** ⚠️ 请求完成
---
### M1: 获取会员信息(修复后)
**请求:**
```
GET /h5/member/info
Authorization: Bearer {accessToken}
```
**响应:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"memberId": "2018324984715313153",
"memberCode": "M17700411496756880",
"phone": "158****2069",
"nickname": "user_2069",
"avatar": null,
"gender": "0",
"birthday": null,
"registerTime": "2026-02-02 22:05:50",
"identityType": "1",
"education": null,
"students": []
}
}
```
**结果:** ✅ 通过
---
### M2: 修改会员信息
**请求:**
```
PUT /h5/member/info
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"nickname": "测试用户",
"gender": "1"
}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": null
}
```
**结果:** ✅ 通过
---
### M6: 绑定学生
**请求:**
```
POST /h5/member/student
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"studentName": "测试学生",
"studentNo": "TEST001",
"birthday": "2015-06-15",
"gender": "1",
"regionId": 420100,
"schoolId": 5,
"schoolGradeId": 19,
"schoolClassId": 55
}
```
**响应:**
```json
{
"code": 500,
"msg": "\u73ed\u7ea7\u4e0d\u5b58\u5728\u6216\u4e0d\u5c5e\u4e8e\u8be5\u5e74\u7ea7",
"data": null
}
```
**结果:** ⚠️ 请求完成
---
> **注意**: 当前测试学校(华中科技大学附属中学)下的年级没有配置班级数据,绑定学生功能无法完整测试。
---
### M7: 获取绑定的学生列表
**请求:**
```
GET /h5/member/students
Authorization: Bearer {accessToken}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": []
}
```
**结果:** ✅ 通过(当前无绑定学生)
---
### A7: 刷新Token
**请求:**
```
POST /h5/auth/refresh?refreshToken={refreshToken}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjIwMTgzMjQ5ODQ3MTUzMTMxNTMsInJuU3RyIjoiYUZ0MEFTelFiSzZGMFZMbmhDY2dBMFJ2TENwZERLM24iLCJ0ZW5hbnRJZCI6IjAwMDAwMCIsInVzZXJJZCI6MjAxODMyNDk4NDcxNTMxMzE1MywidXNlck5hbWUiOiLmtYvor5XnlKjmiLciLCJjbGllbnRpZCI6Img1XzIwMTgzMjQ5ODQ3MTUzMTMxNTMifQ.OmeWh0BaYKi2YFVHp3I0akq50zgaCCIS_a376ciI-00",
"refreshToken": "88f94e5f264e4f2f8f9bf9f4a3ba0b58",
"expiresIn": 7200,
"memberId": "2018324984715313153",
"memberCode": "M17700411496756880",
"phone": "158****2069",
"nickname": "\u6d4b\u8bd5\u7528\u6237",
"identityType": "1"
}
}
```
**结果:** ✅ 通过
---
### A8: 退出登录
**请求:**
```
POST /h5/auth/logout
Authorization: Bearer {accessToken}
```
**响应:**
```json
{
"code": 200,
"msg": "\u64cd\u4f5c\u6210\u529f",
"data": null
}
```
**结果:** ✅ 通过
---
## 三、测试总结
### 测试结果统计
| 模块 | 通过 | 失败 | 备注 |
|------|------|------|------|
| 基础数据B1-B5 | 5 | 0 | 全部通过 |
| 认证模块A1-A8 | 8 | 0 | 全部通过 |
| 会员模块M1-M7 | 3 | 1 | M6绑定学生因数据缺失未完整测试 |
### 测试覆盖
- ✅ 图形验证码获取
- ✅ 短信验证码发送(阿里云)
- ✅ 用户注册
- ✅ 密码登录
- ✅ 短信验证码登录
- ✅ Token刷新
- ✅ 退出登录
- ✅ 获取会员信息
- ✅ 修改会员信息
- ✅ 获取绑定学生列表
- ⚠️ 绑定学生(需要完整的学校-年级-班级数据)
### 问题修复
在测试过程中发现并修复了以下问题:
1. **H5登录Token校验问题**
- 问题H5登录后访问需认证接口报500错误
- 原因SecurityConfig拦截器检查clientId时H5登录未设置extra信息导致NPE
- 修复在H5AuthServiceImpl中设置extra信息并在SecurityConfig中跳过H5设备的clientId校验
---
## 四、Redis验证码获取方式
```bash
# 连接Redis数据库2
redis-cli -h 8.148.25.55 -a aly2024A -n 2
# 获取图形验证码
GET global:captcha_codes:{uuid}
# 获取注册短信验证码
GET h5:sms:code:register:15889762069
# 获取登录短信验证码
GET h5:sms:code:login:15889762069
```
---
*测试完成时间: 2026-02-02*