Files
user-system/docs/testing/TEST_PLAN_1_BUSINESS_LOGIC.md
long-agent 5b6bd93179 refactor: 整理项目根目录结构
整理内容:
- 删除 60+ 临时测试输出文件 (*.txt)
- 移动二进制文件到 bin/ 目录
- 移动 Shell 脚本到 scripts/ 目录
  - scripts/dev/: check_gitea.sh, check_sub2api.sh, run_tests.sh
  - scripts/deploy/: deploy_*.sh, simple_deploy.sh
  - scripts/ops/: fix_nginx.sh, fix_ssl.sh, install_docker.sh
  - scripts/test/: test_*.sh, test_*.bat
- 移动批处理文件到 scripts/
- 移动 Python 脚本到 tools/
- 清理临时日志文件

保留根目录必要文件:
- go.mod, go.sum, go.work
- Makefile, docker-compose.yml
- .env.example, .gitignore
- README.md, AGENTS.md, DEPLOY_GUIDE.md

验证: go build ./... && go test ./... 通过
2026-04-07 18:10:36 +08:00

199 lines
14 KiB
Markdown
Raw Permalink 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.
# 业务逻辑正确性测试方案
## 概述
本文档定义用户管理系统核心业务逻辑的正确性测试方案,涵盖用户生命周期管理、设备信任、登录日志、统计数据的端到端正确性验证。
---
## 1. 用户注册与审批流程测试
### 1.1 用户注册创建
**测试目标**:验证用户注册后状态流转与数据一致性的正确性
| 用例编号 | 用例描述 | 前置条件 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|---------|-----------|
| REG-001 | 管理员创建用户并设置初始状态为已激活 | 管理员已登录 | 1. 管理员创建用户status=1已激活<br>2. 提交表单 | 1. API 返回 200<br>2. 用户状态为已激活<br>3. 无需邮箱激活即可登录 | `SELECT status FROM users WHERE username='xxx'` 返回 `1` |
| REG-002 | 管理员创建用户并设置初始状态为未激活 | 管理员已登录 | 1. 管理员创建用户status=0未激活<br>2. 提交表单 | 1. API 返回 200<br>2. 用户状态为未激活<br>3. 用户无法登录 | `SELECT status FROM users WHERE username='xxx'` 返回 `0` |
| REG-003 | 用户自助注册流程状态正确 | 系统无管理员 | 1. 用户填写注册表单<br>2. 提交注册 | 1. 创建用户status=0未激活<br>2. 发送激活邮件 | `SELECT status FROM users WHERE email='xxx'` 返回 `0` |
| REG-004 | 重复用户名注册拒绝 | 无 | 1. 创建用户 "testuser"<br>2. 再次创建相同用户名 | 返回错误:用户名已存在 | 用户表仅有一条 username='testuser' 的记录 |
| REG-005 | 创建用户时分配角色 | 存在可用角色 | 1. 创建用户并分配 role_ids=[2,3]<br>2. 查询用户角色 | 1. API 返回成功<br>2. 用户拥有指定角色 | `SELECT role_id FROM user_roles WHERE user_id=xxx` 包含 2,3 |
### 1.2 用户状态变更
**测试目标**:验证用户状态(激活/锁定/禁用)变更的正确性及对登录的影响
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| STA-001 | 管理员禁用用户后用户无法登录 | 1. 禁用用户status=3<br>2. 用户尝试登录 | 登录失败,提示"账号已禁用" | `SELECT status FROM users WHERE id=xxx` 返回 `3` |
| STA-002 | 管理员锁定用户后用户无法登录 | 1. 锁定用户status=2<br>2. 用户尝试登录 | 登录失败,提示"账号已锁定" | `SELECT status FROM users WHERE id=xxx` 返回 `2` |
| STA-003 | 管理员解锁用户后用户恢复登录 | 1. 用户当前 status=2<br>2. 管理员更新为 status=1 | 1. 更新成功<br>2. 用户可正常登录 | `SELECT status FROM users WHERE id=xxx` 返回 `1` |
| STA-004 | 管理员激活未激活用户 | 1. 用户当前 status=0<br>2. 管理员激活用户 | 1. 更新成功<br>2. 用户可正常登录 | `SELECT status FROM users WHERE id=xxx` 返回 `1` |
| STA-005 | 批量更新用户状态 | 1. 选择 5 个用户<br>2. 批量禁用 | 1. 全部更新成功<br>2. 所有用户 status=3 | `SELECT COUNT(*) FROM users WHERE status=3 AND id IN (...)` 返回 `5` |
### 1.3 用户删除
**测试目标**:验证用户删除后的数据完整性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| DEL-001 | 删除用户后用户角色关联清除 | 1. 删除用户 ID=10<br>2. 查询 user_roles | 1. API 返回 200<br>2. 该用户无角色记录 | `SELECT COUNT(*) FROM user_roles WHERE user_id=10` 返回 `0` |
| DEL-002 | 删除用户后登录日志保留用户ID | 1. 删除用户前查询登录日志<br>2. 删除用户<br>3. 查询登录日志 | 1. 删除前有日志<br>2. 删除后日志仍存在user_id 字段保留 | 登录日志表 user_id 字段保留原值(非级联删除) |
| DEL-003 | 删除用户后设备关联保留 | 1. 删除用户<br>2. 查询 devices 表 | devices 表中该用户的设备保留user_id 不变 | `SELECT COUNT(*) FROM devices WHERE user_id=xxx` 结果不变 |
| DEL-004 | 恢复删除(软删除)的用户 | 1. 系统启用软删除<br>2. 删除用户<br>3. 恢复用户 | 1. 删除成功<br>2. 恢复后用户状态恢复 | 用户记录恢复status 恢复原值 |
---
## 2. 统计数据正确性测试
### 2.1 用户统计正确性
**测试目标**验证用户统计total_users, active_users, new_users 等)的计算正确性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| STAT-001 | 总用户数统计正确 | 1. 查询当前总用户数<br>2. 创建 3 个新用户<br>3. 再次查询 | 第二次查询比第一次多 3 | `SELECT COUNT(*) FROM users` 与 API 返回 total_users 一致 |
| STAT-002 | 新增用户今日统计正确 | 1. 查看今日新增<br>2. 创建一个用户<br>3. 再次查看 | 新增用户数 +1 | `SELECT COUNT(*) FROM users WHERE created_at >= today_start` 与 new_users_today 一致 |
| STAT-003 | 按状态统计正确 | 1. 创建 2 个用户后禁用其中一个<br>2. 查询统计数据 | disabled_users = 1 | `SELECT COUNT(*) FROM users WHERE status=3` 与 disabled_users 一致 |
| STAT-004 | 创建用户后 dashboard 统计数据更新 | 1. 获取 dashboard stats<br>2. 创建 1 个用户<br>3. 再次获取 | total_users +1, new_users_today +1 | 两次 stats 对比差异正确 |
| STAT-005 | 删除用户后统计更新 | 1. 获取 stats<br>2. 删除 1 个用户<br>3. 再次获取 | total_users -1 | 两次 stats 对比差异正确 |
| STAT-006 | 批量创建用户统计准确 | 1. 批量导入 100 个用户<br>2. 查询统计 | total_users 增加 100 | `SELECT COUNT(*) FROM users` 增加 100 |
### 2.2 登录统计正确性
**测试目标**:验证登录成功/失败次数统计的正确性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| LOGIN-001 | 登录成功日志记录正确 | 1. 用户成功登录<br>2. 查询登录日志 | 1. 日志存在<br>2. status=1成功<br>3. user_id 正确 | `SELECT status, user_id FROM login_logs ORDER BY id DESC LIMIT 1` |
| LOGIN-002 | 登录失败日志记录正确 | 1. 用户使用错误密码登录<br>2. 查询登录日志 | 1. 日志存在<br>2. status=0失败<br>3. fail_reason 包含原因 | `SELECT status, fail_reason FROM login_logs ORDER BY id DESC LIMIT 1` |
| LOGIN-003 | 登录统计今日成功次数正确 | 1. 查询 logins_today_success<br>2. 3 个用户成功登录<br>3. 再次查询 | 第二次比第一次多 3 | `SELECT COUNT(*) FROM login_logs WHERE status=1 AND created_at >= today_start` |
| LOGIN-004 | 登录统计今日失败次数正确 | 1. 查询 logins_today_failed<br>2. 2 个用户密码错误登录失败<br>3. 再次查询 | 第二次比第一次多 2 | `SELECT COUNT(*) FROM login_logs WHERE status=0 AND created_at >= today_start` |
---
## 3. 设备信任管理正确性测试
### 3.1 设备信任状态变更
**测试目标**:验证设备信任/取消信任操作的正确性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| DEV-001 | 用户信任当前设备 | 1. 用户登录新设备<br>2. 调用信任设备接口<br>3. 查询设备 | 1. API 返回 200<br>2. is_trusted=true<br>3. trust_expires_at 有值 | `SELECT is_trusted, trust_expires_at FROM devices WHERE id=xxx` |
| DEV-002 | 用户取消信任设备 | 1. 设备 is_trusted=true<br>2. 调用取消信任<br>3. 查询设备 | 1. API 返回 200<br>2. is_trusted=false<br>3. trust_expires_at=null | 同上is_trusted=false |
| DEV-003 | 管理员信任任意设备 | 1. 管理员调用 adminTrustDevice<br>2. 查询设备 | is_trusted=true, trust_expires_at 为 30 天后 | 同上 |
| DEV-004 | 管理员取消信任任意设备 | 1. 管理员调用 adminUntrustDevice<br>2. 查询设备 | is_trusted=false | 同上 |
| DEV-005 | 管理员删除设备 | 1. 管理员调用 adminDeleteDevice<br>2. 查询设备 | 设备不存在 | `SELECT COUNT(*) FROM devices WHERE id=xxx` 返回 0 |
| DEV-006 | 信任过期后状态正确 | 1. 设置 trust_expires_at 为过去时间<br>2. 查询设备状态 | is_trusted=false过期检查逻辑 | `SELECT is_trusted FROM devices WHERE trust_expires_at < now()` |
### 3.2 设备与用户关联正确性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| DEV-007 | 设备正确归属用户 | 1. 用户 A 登录设备<br>2. 用户 B 查看自己的设备 | 1. 设备属于用户 A<br>2. 用户 B 看不到 | devices 表 user_id 字段正确 |
| DEV-008 | 管理员查看所有设备 | 1. 管理员调用 listAllDevices<br>2. 查看返回列表 | 包含所有用户的设备 | `SELECT COUNT(*) FROM devices` 与返回 total 一致 |
| DEV-009 | 管理员按用户筛选设备 | 1. 设置 user_id_filter=5<br>2. 调用 listAllDevices | 仅返回 user_id=5 的设备 | SQL: `WHERE user_id=5` |
---
## 4. 权限与角色正确性测试
### 4.1 角色分配正确性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| ROLE-001 | 分配角色后用户拥有对应权限 | 1. 用户无角色<br>2. 分配 role_id=2<br>3. 验证用户权限 | 用户拥有 role_id=2 的所有权限 | `SELECT permission_id FROM role_permissions WHERE role_id=2` 与用户实际权限对比 |
| ROLE-002 | 分配多个角色权限合并 | 1. 分配 role_ids=[2,3]<br>2. 验证用户权限 | 用户拥有 role 2 和 role 3 的所有权限并集 | 权限数量 = role2 权限数 + role3 权限数(去重) |
| ROLE-003 | 移除用户角色 | 1. 用户有角色<br>2. 移除角色<br>3. 验证权限减少 | 用户失去被移除角色的权限 | 移除前后的权限数量对比 |
| ROLE-004 | 角色状态为禁用时用户无该角色权限 | 1. 角色 status=0禁用<br>2. 用户拥有该角色<br>3. 验证权限 | 用户不拥有该角色的任何权限 | 权限检查跳过 status=0 的角色 |
### 4.2 权限继承正确性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 | 数据库验证 |
|---------|---------|---------|---------|-----------|
| PERM-001 | 子权限继承父权限 | 1. 权限 A 是权限 B 的父级<br>2. 用户拥有 A<br>3. 检查 B 的访问 | 用户同时拥有 A 和 B | 权限树结构验证 |
| PERM-002 | 权限树深度遍历正确 | 1. 用户拥有叶节点权限<br>2. 检查所有祖先权限 | 用户拥有完整路径上的所有权限 | 递归查询权限树 |
---
## 5. 前端行为与后端数据一致性
### 5.1 表单提交与数据库
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 |
|---------|---------|---------|---------|
| FE-001 | 创建用户表单提交后数据库正确 | 1. 填写用户名、邮箱、密码<br>2. 提交<br>3. 页面刷新后数据存在 | 数据库用户表有一条对应记录 |
| FE-002 | 编辑用户信息后数据库同步 | 1. 修改用户昵称<br>2. 保存<br>3. 重新加载页面 | 数据库 nickname 字段已更新 |
| FE-003 | 删除用户后列表刷新 | 1. 删除用户<br>2. 页面自动刷新 | 列表中不再显示该用户,数据库中已删除 |
| FE-004 | 筛选条件变更后列表正确 | 1. 选择"仅活跃用户"<br>2. 查看列表 | 仅显示 status=1 的用户 |
### 5.2 批量操作一致性
| 用例编号 | 用例描述 | 测试步骤 | 预期结果 |
|---------|---------|---------|---------|
| FE-005 | 批量启用用户后数据库一致 | 1. 选中 10 个用户<br>2. 批量启用<br>3. 刷新页面 | 10 个用户 status=1 |
| FE-006 | 批量导入用户后统计正确 | 1. 导入 CSV50 个用户)<br>2. 查看统计 | total_users 增加 50 |
| FE-007 | 批量导出数据完整 | 1. 导出当前用户列表<br>2. 比对记录数 | 导出数量 = 数据库实际数量 |
---
## 6. 测试数据准备脚本
### 6.1 用户统计测试数据准备
```sql
-- 清理测试数据
DELETE FROM users WHERE username LIKE 'stat_test_%';
-- 插入不同状态的用户
INSERT INTO users (username, email, password, status, created_at) VALUES
('stat_test_active_1', 'active1@test.com', '$2a$10$...', 1, NOW()),
('stat_test_active_2', 'active2@test.com', '$2a$10$...', 1, NOW()),
('stat_test_locked', 'locked@test.com', '$2a$10$...', 2, NOW()),
('stat_test_disabled', 'disabled@test.com', '$2a$10$...', 3, NOW()),
('stat_test_inactive', 'inactive@test.com', '$2a$10$...', 0, NOW() - INTERVAL '2 days');
```
### 6.2 登录日志测试数据准备
```sql
-- 清理测试数据
DELETE FROM login_logs WHERE user_id IN (SELECT id FROM users WHERE username LIKE 'login_test_%');
-- 准备测试用户
INSERT INTO users (username, email, password, status) VALUES
('login_test_user', 'logintest@test.com', '$2a$10$...', 1);
-- 插入登录日志
INSERT INTO login_logs (user_id, login_type, status, ip, created_at) VALUES
(currval('users_id_seq'), 1, 1, '192.168.1.1', NOW()),
(currval('users_id_seq'), 1, 0, '192.168.1.2', NOW() - INTERVAL '1 hour'),
(currval('users_id_seq'), 1, 1, '192.168.1.3', NOW() - INTERVAL '2 hours');
```
---
## 7. 测试执行检查清单
### 7.1 测试前检查
- [ ] 测试数据库已初始化
- [ ] 测试用户已创建(有管理员权限)
- [ ] API 服务运行正常
- [ ] 前端开发服务器运行正常
### 7.2 测试后清理
- [ ] 测试数据已清理
- [ ] 无残留测试用户
- [ ] 统计数据已恢复
### 7.3 成功标准
- [ ] 所有测试用例通过
- [ ] 数据库验证全部符合预期
- [ ] 前端行为与数据库状态一致
- [ ] 统计数据计算误差为 0