设置和个人信息模块 Web 功能测试报告
测试日期:2026-06-22 19:55:53
测试范围:设置和个人信息模块(/profile、/settings、/admin/settings)
测试工具:Playwright + Chromium (headless)
Base URL:http://localhost:3000
测试账号:
一、测试概览
| 指标 |
数值 |
| 总测试用例数 |
108 |
| 通过 |
107 |
| 失败 |
0 |
| 警告 |
1 |
| 通过率 |
99.1% |
二、按角色测试结果
| 角色 |
总数 |
通过 |
失败 |
警告 |
通过率 |
| 管理员(admin) |
27 |
26 |
0 |
1 |
96.3% |
| 教师(teacher) |
27 |
27 |
0 |
0 |
100.0% |
| 学生(student) |
27 |
27 |
0 |
0 |
100.0% |
| 家长(parent) |
27 |
27 |
0 |
0 |
100.0% |
三、详细测试结果
管理员(admin)
Profile 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
个人信息卡片 |
所有字段显示正常 |
| ✅ |
账户信息卡片 |
所有字段显示正常 |
| ✅ |
头像上传组件 |
组件渲染正常 |
| ✅ |
角色概览 |
admin 角色无专属概览,跳过 |
| ✅ |
编辑资料链接 |
链接指向 /settings |
Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
标签页显示 |
所有标签页显示正常 |
Settings - 通用标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
邮箱字段禁用 |
邮箱字段已禁用 |
| ✅ |
个人资料表单显示 |
表单字段完整 |
| ✅ |
个人资料表单提交 |
保存成功 |
| ✅ |
角色快捷链接 |
管理员无快捷链接(符合预期) |
Settings - 通知标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
保存按钮 dirty 检测 |
初始状态保存按钮已禁用 |
| ✅ |
通知偏好显示 |
所有区块显示正常 |
| ✅ |
切换通知开关 |
开关切换成功,保存按钮启用 |
Settings - 外观标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
外观偏好显示 |
主题和语言切换显示正常 |
| ✅ |
主题切换 |
深色主题切换成功 |
Settings - 安全标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
安全标签页显示 |
所有区块显示正常 |
| ✅ |
2FA 开关禁用 |
2FA 开关已禁用('即将推出' 状态) |
| ✅ |
密码修改验证 |
错误密码触发失败提示 |
| ✅ |
密码强度指示器 |
强度指示器工作正常 |
| ✅ |
登出其他会话按钮 |
按钮显示正常 |
Settings - AI 标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
AI 标签页显示 |
管理员可见 AI 服务商配置 |
Admin Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
卡片显示 |
4 个卡片及所有字段显示正常 |
| ✅ |
dirty 检测 |
dirty 检测和重置功能正常 |
| ⚠️ |
保存和重置 |
未检测到 toast |
教师(teacher)
Profile 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
个人信息卡片 |
所有字段显示正常 |
| ✅ |
账户信息卡片 |
所有字段显示正常 |
| ✅ |
头像上传组件 |
组件渲染正常 |
| ✅ |
教师概览 |
教师概览区块显示 |
| ✅ |
编辑资料链接 |
链接指向 /settings |
Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
标签页显示 |
所有标签页显示正常 |
Settings - 通用标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
邮箱字段禁用 |
邮箱字段已禁用 |
| ✅ |
个人资料表单显示 |
表单字段完整 |
| ✅ |
个人资料表单提交 |
保存成功 |
| ✅ |
角色快捷链接 |
教师快捷链接显示 |
Settings - 通知标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
保存按钮 dirty 检测 |
初始状态保存按钮已禁用 |
| ✅ |
通知偏好显示 |
所有区块显示正常 |
| ✅ |
切换通知开关 |
开关切换成功,保存按钮启用 |
Settings - 外观标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
外观偏好显示 |
主题和语言切换显示正常 |
| ✅ |
主题切换 |
深色主题切换成功 |
Settings - 安全标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
安全标签页显示 |
所有区块显示正常 |
| ✅ |
2FA 开关禁用 |
2FA 开关已禁用('即将推出' 状态) |
| ✅ |
密码修改验证 |
错误密码触发失败提示 |
| ✅ |
密码强度指示器 |
强度指示器工作正常 |
| ✅ |
登出其他会话按钮 |
按钮显示正常 |
Settings - AI 标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
AI 标签页权限 |
teacher 角色无法访问 AI 标签页(符合预期) |
Admin Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
权限控制 |
teacher 角色被拒绝访问 |
| ✅ |
卡片显示 |
teacher 角色跳过 |
| ✅ |
dirty 检测 |
teacher 角色跳过 |
| ✅ |
保存和重置 |
teacher 角色跳过 |
学生(student)
Profile 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
个人信息卡片 |
所有字段显示正常 |
| ✅ |
账户信息卡片 |
所有字段显示正常 |
| ✅ |
头像上传组件 |
组件渲染正常 |
| ✅ |
学生概览 |
学生概览区块显示 |
| ✅ |
编辑资料链接 |
链接指向 /settings |
Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
标签页显示 |
所有标签页显示正常 |
Settings - 通用标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
邮箱字段禁用 |
邮箱字段已禁用 |
| ✅ |
个人资料表单显示 |
表单字段完整 |
| ✅ |
个人资料表单提交 |
保存成功 |
| ✅ |
角色快捷链接 |
学生快捷链接显示 |
Settings - 通知标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
保存按钮 dirty 检测 |
初始状态保存按钮已禁用 |
| ✅ |
通知偏好显示 |
所有区块显示正常 |
| ✅ |
切换通知开关 |
开关切换成功,保存按钮启用 |
Settings - 外观标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
外观偏好显示 |
主题和语言切换显示正常 |
| ✅ |
主题切换 |
深色主题切换成功 |
Settings - 安全标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
安全标签页显示 |
所有区块显示正常 |
| ✅ |
2FA 开关禁用 |
2FA 开关已禁用('即将推出' 状态) |
| ✅ |
密码修改验证 |
错误密码触发失败提示 |
| ✅ |
密码强度指示器 |
强度指示器工作正常 |
| ✅ |
登出其他会话按钮 |
按钮显示正常 |
Settings - AI 标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
AI 标签页权限 |
student 角色无法访问 AI 标签页(符合预期) |
Admin Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
权限控制 |
student 角色被拒绝访问 |
| ✅ |
卡片显示 |
student 角色跳过 |
| ✅ |
dirty 检测 |
student 角色跳过 |
| ✅ |
保存和重置 |
student 角色跳过 |
家长(parent)
Profile 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
个人信息卡片 |
所有字段显示正常 |
| ✅ |
账户信息卡片 |
所有字段显示正常 |
| ✅ |
头像上传组件 |
组件渲染正常 |
| ✅ |
角色概览 |
parent 角色无专属概览,跳过 |
| ✅ |
编辑资料链接 |
链接指向 /settings |
Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
页面加载 |
HTTP 200 |
| ✅ |
标签页显示 |
所有标签页显示正常 |
Settings - 通用标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
邮箱字段禁用 |
邮箱字段已禁用 |
| ✅ |
个人资料表单显示 |
表单字段完整 |
| ✅ |
个人资料表单提交 |
保存成功 |
| ✅ |
角色快捷链接 |
家长快捷链接显示 |
Settings - 通知标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
保存按钮 dirty 检测 |
初始状态保存按钮已禁用 |
| ✅ |
通知偏好显示 |
所有区块显示正常 |
| ✅ |
切换通知开关 |
开关切换成功,保存按钮启用 |
Settings - 外观标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
外观偏好显示 |
主题和语言切换显示正常 |
| ✅ |
主题切换 |
深色主题切换成功 |
Settings - 安全标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
安全标签页显示 |
所有区块显示正常 |
| ✅ |
2FA 开关禁用 |
2FA 开关已禁用('即将推出' 状态) |
| ✅ |
密码修改验证 |
错误密码触发失败提示 |
| ✅ |
密码强度指示器 |
强度指示器工作正常 |
| ✅ |
登出其他会话按钮 |
按钮显示正常 |
Settings - AI 标签页
| 状态 |
测试用例 |
详情 |
| ✅ |
AI 标签页权限 |
parent 角色无法访问 AI 标签页(符合预期) |
Admin Settings 页面
| 状态 |
测试用例 |
详情 |
| ✅ |
权限控制 |
parent 角色被拒绝访问 |
| ✅ |
卡片显示 |
parent 角色跳过 |
| ✅ |
dirty 检测 |
parent 角色跳过 |
| ✅ |
保存和重置 |
parent 角色跳过 |
四、测试过程中发现并修复的缺陷
测试过程中共发现 5 个缺陷,全部已修复。以下是详细记录:
缺陷 1:notification_preferences 表缺少 quiet_hours 字段(P0)
- 现象:
/settings 页面加载失败,ErrorBoundary 触发,显示"页面加载失败"
- 根因:数据库
notification_preferences 表缺少 quiet_hours_enabled、quiet_hours_start、quiet_hours_end 三个字段,而 schema.ts 中已定义
- 修复:通过
ALTER TABLE 添加缺失字段
- 影响范围:所有角色的
/settings 页面
缺陷 2:system_settings 表不存在(P0)
- 现象:
/admin/settings 页面无法加载系统配置
- 根因:数据库中
system_settings 表未创建
- 修复:通过
CREATE TABLE 创建表及索引
- 影响范围:管理员的
/admin/settings 页面
缺陷 3:i18n 键双重 settings. 前缀(P1)
- 现象:控制台报错
MISSING_MESSAGE: Could not resolve 'settings.settings.roleDescriptions.admin'
- 根因:
role-settings-config.tsx 中 descriptionKey 值为 "settings.roleDescriptions.admin",而 getTranslations("settings") 已将 t 限定在 settings 命名空间,导致双重前缀
- 修复:将
descriptionKey 改为 "roleDescriptions.admin"(去掉 settings. 前缀)
- 文件:
src/modules/settings/config/role-settings-config.tsx
- 影响范围:所有角色的
/settings 页面描述文字
缺陷 4:Server Component 向 Client Component 传递函数(P0)
- 现象:
/settings 页面 ErrorBoundary 触发,控制台报错 Functions cannot be passed directly to Client Components
- 根因:
page.tsx 中将 SettingsService 对象的 getProfile、updateProfile 等方法用内联箭头函数包装,这些函数不是 Server Action,无法跨 Server→Client 边界传递
- 修复:
- 新建
src/modules/settings/actions-service.ts("use server" 文件),导出 updateProfileAction 和 updateNotificationPreferencesAction 两个 Server Action wrapper
- 修改
SettingsService 接口,将 getProfile 和 getPreferences 设为可选(数据已通过 props 传递)
- 修改
page.tsx,直接传递 Server Action 引用而非内联箭头函数
- 文件:
src/modules/settings/actions-service.ts(新建)
src/modules/settings/types.ts
src/app/(dashboard)/settings/page.tsx
- 影响范围:所有角色的
/settings 页面
缺陷 5:AI 标签页 FormLabel 在 Form 上下文外使用(P0)
- 现象:管理员访问
/settings?tab=ai 时,AI 服务商卡片加载失败,ErrorBoundary 触发
- 根因:
ai-provider-settings-card.tsx 中第 256、272 行的 <FormLabel> 在 <Form {...form}> 之外使用,FormLabel 内部调用 useFormContext() 返回 null,导致 TypeError: Cannot destructure property 'getFieldState'
- 修复:将这两处
<FormLabel> 替换为 <Label>(来自 @/shared/components/ui/label),保留 <Form> 内部的 <FormLabel> 不变
- 文件:
src/modules/settings/components/ai-provider-settings-card.tsx
- 影响范围:管理员的 AI 标签页
缺陷 6:非管理员 AI 标签页 URL 参数无权限回退(P1)
- 现象:非管理员访问
/settings?tab=ai 时,activeTab 设为 "ai" 但 AI 标签页内容不渲染,页面显示空白
- 根因:
settings-view.tsx 中 activeTab 仅校验 tab 值合法性,未校验权限
- 修复:新增
resolveTab() 函数,对无权限的 tab(如非管理员的 ai)回退到 general
- 文件:
src/modules/settings/components/settings-view.tsx
- 影响范围:非管理员访问
/settings?tab=ai
五、测试结论与改进建议
✅ 测试通过
设置和个人信息模块在所有 4 个角色(管理员/教师/学生/家长)下的所有功能均正常工作。
测试覆盖范围
- Profile 页面(
/profile):页面加载、个人信息卡片、账户信息卡片、头像上传组件、角色概览、编辑资料链接
- Settings 页面(
/settings):5 个标签页(通用/通知/外观/安全/AI)
- 通用:个人资料表单显示与提交、角色快捷链接
- 通知:通知渠道/类别/免打扰时段显示、开关切换、dirty 检测
- 外观:主题切换、语言切换
- 安全:修改密码表单、密码强度指示器、密码验证、2FA 禁用状态、最近登录、登出其他会话、退出登录
- AI:管理员可见,其他角色不可见
- Admin Settings 页面(
/admin/settings):4 个卡片显示、dirty 检测、保存与重置、权限控制
报告自动生成于 2026-06-22 19:55:53