Files
Jog/doc/jog-system-cursor-automated-test-spec.md
T
2026-05-18 21:54:13 +08:00

585 lines
26 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.
# Jog System · Cursor 自动化测试输入规范(全量需求展开)
**文档版本** · **V1.0Cursor** · **生成日期** · **2026-05-18**
| 属性 | 内容 |
| :--- | :--- |
| **定位** | **AI(含 Cursor Agent)生成自动化测试代码时的唯一输入**;不依赖其他 doc 文件即可推导 JUnit / MockMvc / Testcontainers / Vitest / Playwright / k6 等用例 |
| **需求溯源** | 全文展开自 `doc/jog-system-requirements.md`V1.02026-05-17)中的 **FR**、**AC**、**§3 非功能**、**§4 权限矩阵**、**§5 界面**、**§6 测试验收** |
| **实现校准** | HTTP 路径与 Controller 以 **附录 A** 为准(当前 `jog-*` 仓库);与需求文字中的示例路径不一致时,**以代码为准**,并在用例 `notes` 中标注「需求差异」 |
| **并存说明** | 若与 `jog-system-automated-test-plan.md` 同时存在,**以本 `cursor` 文档为 AI 唯一输入** |
---
## 0. 使用方式(写给 AI / Cursor
1. **仅依据本文档**生成测试:从「第 6 章」起按 `TC-*` 编号实现;接口路径查附录 A。
2. 每条用例必须使用 **第 5 章 JSON 模板** 输出设计(可先批量生成 YAML/JSON fixture,再写代码)。
3. `trace` 字段必须含 **FR-* / AC-* / NF-* / PM-* / UI-* / API-*` 之一,便于覆盖率报告。
4. 标注 `implementation_gap` 的用例:实现未达需求时,实现 **`@Disabled` + 原因** 或 **`xfail`**,不得静默改预期。
5. **优先级**`P0` 阻塞发布;`P1` 阻塞合并;`P2` 迭代补齐。
---
## 1. 仓库与已有验证事实(非需求,仅供上下文)
| 代号 | 说明 |
| :--- | :--- |
| T-01 | `mvn -B test` 可通过,但各模块 **`No tests to run`**,无自有 Java 测试 |
| T-02 | 前端 `npm run build`**Node ≥ 20**v16 下 Vite 可能失败 |
| T-03 | `jog-frontend/package.json` **无** `test:unit` / `test:e2e` |
| N-01 | 契约、Flyway、权限等曾依赖**人工静态对比**(见 `jog-system-bug-list.md` |
---
## 2. 测试环境与数据
| 项 | 约定 |
| :--- | :--- |
| JDK | 21 |
| Node | ≥ 20(推荐与 CI 锁定一致) |
| 集成测试 DB/Redis | Testcontainers 或隔离实例;**禁止**默认连开发者 `application.yml` 中公网地址 |
| Profile | `application-test.yml`Flyway 开启,JWT 密钥固定 |
| 数据前缀 | `auto_test_*`,用例结束清理或回滚 |
| 角色 | `anonymous` · `user``ROLE_USER`)· `admin``ROLE_ADMIN` |
**已知实现注记(编写断言时参考)**
- 验证码接口可能为**占位**(见历史 BUG-010):只断言结构存在,不按生产级验证码验收。
- 限流 Key 可能缺 IP/用户维度(BUG-014):限流类用例标注 `weak_isolation`
- 需求称访客可读评论;当前评论列表若在 `/api/app/comment/**`,访客可能 **401**:用例中保留 **需求差异** 断言分支。
---
## 3. 推荐工具与落地目录
| 分层 | 工具 | 目录建议 |
| :--- | :--- | :--- |
| 后端单元 | JUnit 5、Mockito、AssertJ | 各模块 `src/test/java` |
| 后端 API/集成 | Spring Boot Test、MockMvc、`@SpringBootTest`、Testcontainers | `jog-admin/src/test/java` 为主 |
| 契约 | SpringDoc OpenAPI + 脚本对比 `jog-frontend/src/api` | `scripts/contract/` |
| 前端单元 | Vitest、Vue Test Utils、MSW | `jog-frontend` |
| E2E | Playwright | `e2e/``jog-frontend/e2e/` |
| 性能/并发 | k6、JMeter | `perf/k6/` |
| 可访问性 | axe-core + Playwright | 挂接 E2E |
---
## 4. AI 生成单条用例的强制模板
每条逻辑用例输出为一个对象(可存 `test-fixtures/*.json`):
```json
{
"id": "TC-AC-USER-REG-01",
"title": "中文短标题",
"priority": "P0|P1|P2",
"trace": ["AC-USER-REG-01", "FR-USER-REG-01", "API-AUTH-003"],
"layers": ["integration", "e2e"],
"roles": ["anonymous"],
"preconditions": ["干净库或已种子用户", "SMTP mock 或关闭发信断言"],
"steps": [
{ "action": "HTTP POST ...", "detail": "body 字段..." },
{ "action": "查库/查 Redis", "detail": "..." }
],
"expected": {
"http": 200,
"bodyJsonPath": { "code": 200, "data.id": "exists" },
"db": ["sys_user 新增一行 email=..."],
"ui": "可选:E2E 断言"
},
"negative_cases": [],
"implementation_gap": null,
"notes": null
}
```
---
## 5. 功能需求全量展开(对应需求 §2)
以下每节结构:**FR 覆盖表**(规则级必测点)+ **AC 详规**(验收级可执行展开)。
**API 映射列**指向附录 A 中最可能用到的路径(若尚无对应能力则写 `N/A` 并标 `implementation_gap`)。
---
### 5.1 管理员登录(需求 §2.1)
#### 5.1.1 FR → 测试要点
| FR ID | 测试要点 | 建议分层 | 优先级 | API / 备注 |
| :--- | :--- | :--- | :--- | :--- |
| FR-ADM-LOGIN-01 | 支持手机号+密码、用户名+密码登录 | API / E2E | P0 | `POST /api/public/admin/login` |
| FR-ADM-LOGIN-02 | 仅 1 个内置超管,禁止第二管理员 | API / 集成 | P1 | 管理端用户创建接口若不存在则 `implementation_gap` |
| FR-ADM-LOGIN-03 | 连续 3 次错密后需验证码;5 次错密锁定 30 分钟 | API | P0 | 结合 `GET /api/public/captcha`(占位时注明) |
| FR-ADM-LOGIN-04 | 同 IP 5 分钟内失败 >10 次 → IP 封禁 15 分钟 | API / 集成 | P1 | 限流隔离弱时标 `weak_isolation` |
| FR-ADM-LOGIN-05 | 每次成功/失败写登录日志:时间、IP、设备指纹、结果 | 集成 | P0 | 查 `sys_login_log` 或等价表 |
| FR-ADM-LOGIN-06 | 会话 8h;记住我 7d | API / 集成 | P1 | JWT `exp`、refresh 配置 |
#### 5.1.2 AC → 详规
**TC-AC-ADM-LOGIN-01**`P0``trace`: AC-ADM-LOGIN-01, FR-ADM-LOGIN-01, FR-ADM-LOGIN-05
- **目的**:正确用户名或手机号 + 密码登录后台。
- **前置**:Flyway 种子管理员存在;已知凭据。
- **步骤**
1. `POST /api/public/admin/login`,body:账号字段(与实现一致)、密码、可选 `deviceFingerprint`
2. 断言 200`data` 含访问令牌与管理员信息。
3. 数据库/日志:`result=成功`、IP/时间非空。
- **E2E**:登录表单提交后 URL 进入 `/admin` 或仪表盘路由。
- **api_ref**:附录 A `AuthController`
**TC-AC-ADM-LOGIN-02**`P0``trace`: AC-ADM-LOGIN-02, FR-ADM-LOGIN-03
- **目的**:连续 3 次错误密码后第 4 次需验证码。
- **步骤**
1. 同一账号连续 3 次错误密码。
2. 第 4 次请求:不带验证码 → 期望 400/422 或业务码提示需验证码(与实现一致)。
3. `GET /api/public/captcha``captchaKey`;带正确/错误验证码各测一轮。
- **implementation_gap**:若验证码为占位,则断言「接口返回结构」+ 业务仍返回需验证码 **或** 记录产品与实现对齐缺口。
**TC-AC-ADM-LOGIN-03**`P0``trace`: AC-ADM-LOGIN-03, FR-ADM-LOGIN-03
- **目的**:连续 5 次错误锁定 30 分钟。
- **步骤**:连续失败至阈值;第 6 次正确密码仍不可登录;期望文案含锁定与约 30 分钟。
- **集成**:查用户 `locked_until` 或等价字段。
**TC-AC-ADM-LOGIN-04**`P1``trace`: AC-ADM-LOGIN-04, FR-ADM-LOGIN-02
- **目的**:禁止第二超级管理员。
- **步骤**:若存在「创建管理员」API 则调用并期望拒绝;若无 API 则静态断言 `user_type` 枚举与注册路径不通。
**TC-AC-ADM-LOGIN-05**`P0``trace`: AC-ADM-LOGIN-05, FR-ADM-LOGIN-05
- **目的**:登录日志字段完整。
- **步骤**:成功一次、失败一次;查日志表:`ip``device`/`ua``result``time`
---
### 5.2 用户注册(需求 §2.2
#### 5.2.1 FR → 测试要点
| FR ID | 测试要点 | 建议分层 | 优先级 |
| :--- | :--- | :--- | :--- |
| FR-USER-REG-01 | 邮箱+密码必填 | API / FE 单元 | P0 |
| FR-USER-REG-02 | 密码 8~32 且至少三类字符 | FE + API | P0 |
| FR-USER-REG-03 | 邮箱唯一;发验证邮件 | API / 集成 | P0 |
| FR-USER-REG-04 | 验证链接 24h | API | P1 |
| FR-USER-REG-05 | 同 IP 1h 最多 3 次注册 | API | P0 |
| FR-USER-REG-06 | 无自助找回;仅管理员重置 | API | P1 |
#### 5.2.2 AC → 详规
**TC-AC-USER-REG-01**`P0``trace`: AC-USER-REG-01, FR-USER-REG-01~03
- **步骤**:合法邮箱+合规密码 `POST /api/public/user/register` → 200;DB 用户存在;邮件发送可 mock 断言「调用次数」。
**TC-AC-USER-REG-02**`P0``trace`: AC-USER-REG-02, FR-USER-REG-03
- **步骤**:重复邮箱第二次注册 → 业务错误「该邮箱已被注册」或等价码。
**TC-AC-USER-REG-03**`P0``trace`: AC-USER-REG-03, FR-USER-REG-02
- **步骤**:纯数字或少于 8 位 → 前端校验拦截;绕过前端直调 API → 400/业务错误。
**TC-AC-USER-REG-04**`P0``trace`: AC-USER-REG-04, FR-USER-REG-05
- **步骤**:同 IP(或同测试标识)第 4 次注册 → 限流或「注册过于频繁」。
**TC-AC-USER-REG-05**`P0``trace`: AC-USER-REG-05, FR-USER-REG-06
- **步骤**:管理员 `PUT /api/admin/user/{id}/reset-password`;旧密码失效、新密码可登录。
#### 5.2.3 FR 补充用例(无独立 AC
**TC-FR-USER-REG-04**`P1``trace`: FR-USER-REG-04
- **目的**:邮箱验证 token 超过 24h 失效。
- **步骤**:插入过期 token 或时钟模拟;请求验证接口期望失败。
---
### 5.3 用户登录(需求 §2.3
#### 5.3.1 FR → 测试要点
| FR ID | 测试要点 | 优先级 |
| :--- | :--- | :--- |
| FR-USER-LOGIN-01 | 邮箱+密码 | P0 |
| FR-USER-LOGIN-02 | 最多 3 活跃会话,驱逐最早 | P0 |
| FR-USER-LOGIN-03 | OAuth 扩展点可配置开关 | P2 |
| FR-USER-LOGIN-04 | 5 次错密锁定 15 分钟 | P0 |
| FR-USER-LOGIN-05 | 忘记密码引导联系管理员 | P1 |
| FR-USER-LOGIN-06 | 默认 24h;记住我 14d | P0 |
#### 5.3.2 AC → 详规
**TC-AC-USER-LOGIN-01**`P0``trace`: AC-USER-LOGIN-01
- `POST /api/public/user/login` 成功;返回 Token 与用户信息。
**TC-AC-USER-LOGIN-02**`P0``trace`: AC-USER-LOGIN-02, FR-USER-LOGIN-02
- 模拟 4 个客户端(不同 `deviceFingerprint` 或 User-Agent):第 4 次登录后,最早 Token 调受保护接口 **401/失效**
**TC-AC-USER-LOGIN-03**`P0``trace`: AC-USER-LOGIN-03, FR-USER-LOGIN-04
- 连续 5 次错误密码 → 锁定 15 分钟;比对管理员锁定时长差异(需求管理员 30min / 用户 15min)。
**TC-AC-USER-LOGIN-04**`P1``trace`: AC-USER-LOGIN-04, FR-USER-LOGIN-05
- E2E:点击忘记密码 → 文案含联系管理员。
**TC-AC-USER-LOGIN-05**`P2``trace`: AC-USER-LOGIN-05, FR-USER-LOGIN-03
- 配置项 OAuth 开关存在;`/api/oauth/**` 或配置表中开关读取断言。
**TC-AC-USER-LOGIN-06**`P0``trace`: AC-USER-LOGIN-06, FR-USER-LOGIN-06
- 记住我勾选:`refresh`/Cookie 过期时间接近 14d;未勾选接近 24h(按实现字段断言)。
---
### 5.4 博客发布(需求 §2.4
#### 5.4.1 FR → 测试要点
| FR ID | 测试要点 | 优先级 |
| :--- | :--- | :--- |
| FR-BLOG-PUB-01 | 未登录不可编辑 | P0 |
| FR-BLOG-PUB-02 | 富文本、图片格式与大小、视频嵌入 | P0/P1 |
| FR-BLOG-PUB-03 | 手动存草稿 + 30s 自动保存 | P1 |
| FR-BLOG-PUB-04 | 可见性:公开/私密/仅粉丝 | P0 |
| FR-BLOG-PUB-05 | 已发布可改可见性即时生效 | P0 |
| FR-BLOG-PUB-06 | 必选 1 分类、≤5 标签 | P0 |
| FR-BLOG-PUB-07 | XSS 过滤;禁止非图上传 | P0 |
#### 5.4.2 AC → 详规
**TC-AC-BLOG-PUB-01**`P0``trace`: AC-BLOG-PUB-01, FR-BLOG-PUB-01
- E2E:直接打开编辑路由 → 重定向登录;`redirect` 回跳。
**TC-AC-BLOG-PUB-02**`P1``trace`: AC-BLOG-PUB-02, FR-BLOG-PUB-02
- E2E/API:插入图片 URL 或上传接口;超限文件失败。
**TC-AC-BLOG-PUB-03**`P1``trace`: AC-BLOG-PUB-03, FR-BLOG-PUB-03
- 保存草稿后再进入编辑;内容一致;若有自动保存接口则 mock 时钟测 30s(或文档说明降常为 P2)。
**TC-AC-BLOG-PUB-04**`P0``trace`: AC-BLOG-PUB-04, FR-BLOG-PUB-04
- 作者可见私密文;访客 `GET /api/public/article/{id}` → 404 或无权。
**TC-AC-BLOG-PUB-05**`P0``trace`: AC-BLOG-PUB-05, FR-BLOG-PUB-05
- `PUT /api/app/article/{id}` 改可见性后,访客再看详情变化。
**TC-AC-BLOG-PUB-06**`P0``trace`: AC-BLOG-PUB-06, FR-BLOG-PUB-06
- 创建携带 6 个 tagId → 拒绝。
**TC-AC-BLOG-PUB-07**`P0``trace`: AC-BLOG-PUB-07, FR-BLOG-PUB-07
- 上传 `.exe` 或使用文章正文带可执行链接策略;期望拒绝或清洗。
---
### 5.5 博客列表查看(需求 §2.5)
#### 5.5.1 FR → 测试要点
| FR ID | 测试要点 | 优先级 |
| :--- | :--- | :--- |
| FR-BLOG-LIST-01 | 按发布时间升降序、浏览量降序 | P0 |
| FR-BLOG-LIST-02 | 分类 + 标签组合筛选 | P0 |
| FR-BLOG-LIST-03 | 标题+正文全文检索与高亮(UI) | P0 |
| FR-BLOG-LIST-04 | 每页 15 条 | P0 |
| FR-BLOG-LIST-05 | 私密只对作者列表可见 | P0 |
| FR-BLOG-LIST-06 | 仅粉丝可见:作者+粉丝 | P0 |
| FR-BLOG-LIST-07 | 浏览量:访客/用户去重;作者本人不看加 | P0 |
| FR-BLOG-LIST-08 | 卡片展示阅读量 | P1 |
#### 5.5.2 AC → 详规
**TC-AC-BLOG-LIST-01**`P0``trace`: AC-BLOG-LIST-01, FR-BLOG-LIST-01
- `GET /api/public/article/list``sortBy`/`order`(以代码参数名为准);断言顺序。
**TC-AC-BLOG-LIST-02**`P0``trace`: AC-BLOG-LIST-02, FR-BLOG-LIST-02
- 同时 `categoryId` + `tagId`;结果集同时满足。
**TC-AC-BLOG-LIST-03**`P0``trace`: AC-BLOG-LIST-03, FR-BLOG-LIST-03
- 关键字搜索;E2E 断言高亮 DOM 或 API 返回摘要含关键词。
**TC-AC-BLOG-LIST-04**`P0``trace`: AC-BLOG-LIST-04, FR-BLOG-LIST-04
- **说明**:需求原文写「第 3 页」,按 **第 2 页** 语义理解为分页;请求 `page=2``pageSize=15`,本页最多 15 条,`total` 与页码一致。
**TC-AC-BLOG-LIST-05**`P0``trace`: AC-BLOG-LIST-05, FR-BLOG-LIST-05
- 作者列表可见私密文;其他用户列表不可见。
**TC-AC-BLOG-LIST-06**`P0``trace`: AC-BLOG-LIST-06, FR-BLOG-LIST-07
- 作者访问本人详情:`view_count` 两次请求不变(或增量为 0)。
**TC-AC-BLOG-LIST-07**`P1``trace`: AC-BLOG-LIST-07, FR-BLOG-LIST-08
- E2E:列表卡片渲染 `viewCount` 字段非空且与接口一致。
#### 5.5.3 FR 补充
**TC-FR-BLOG-LIST-06**`P0``trace`: FR-BLOG-LIST-06
- 用户 B 关注作者 A 后可见「仅粉丝可见」文;未关注则不可见。
---
### 5.6 评论功能(需求 §2.6
#### 5.6.1 FR → 测试要点
| FR ID | 测试要点 | 优先级 |
| :--- | :--- | :--- |
| FR-COMMENT-01 | 登录才能评;访客可读 | P0 |
| FR-COMMENT-02 | 最多 3 级;更深变平级 | P0 |
| FR-COMMENT-03 | 审核开关 | P0 |
| FR-COMMENT-04 | 作者标识 | P1 |
| FR-COMMENT-05 | 管理员删/屏蔽 | P0 |
| FR-COMMENT-06 | 回复站内通知 | P1 |
| FR-COMMENT-07 | XSS + 敏感词 | P0 |
#### 5.6.2 AC → 详规
**TC-AC-COMMENT-01**`P0``trace`: AC-COMMENT-01, FR-COMMENT-01
- E2E:未登录点发表 → 登录引导。
- **API 差异**:访客调评论列表若需登录,记 `implementation_gap` 相对 FR-COMMENT-01「访客可读」。
**TC-AC-COMMENT-02**`P0``trace`: AC-COMMENT-02, FR-COMMENT-02
- 构造 A→B→C→D 四级;断言 D 与 C 平级 `level`/结构。
**TC-AC-COMMENT-03**`P0``trace`: AC-COMMENT-03, FR-COMMENT-03
- 开关开启:`POST` 评论后前台列表无;管理员 `PUT /api/admin/comment/{id}/audit` 后可见。
**TC-AC-COMMENT-04**`P1``trace`: AC-COMMENT-04, FR-COMMENT-04
- 作者账号评论:`isAuthor` 或 UI 徽章。
**TC-AC-COMMENT-05**`P0``trace`: AC-COMMENT-05, FR-COMMENT-05
- 屏蔽后:其它用户不可见;发表者可见(按实现 status)。
**TC-AC-COMMENT-06**`P1``trace`: AC-COMMENT-06, FR-COMMENT-06
- A 回复 B 后 B 的通知列表/未读数+1(若未实现则 `implementation_gap`)。
**TC-AC-COMMENT-07**`P0``trace`: AC-COMMENT-07, FR-COMMENT-07
- 评论含 `<script>`:持久化字段无执行;详情接口返回转义/清洗后串。
---
## 6. 非功能性需求展开(对应需求 §3)
### 6.1 性能与体验(§3.1
| TC ID | 指标来源 | 测试方法 | 通过条件 | 优先级 |
| :--- | :--- | :--- | :--- | :--- |
| TC-NF-PERF-01 | §3.1.1 首屏 ≤2s | Lighthouse 4G 节流 | LCP/Performance 预算 | P1 |
| TC-NF-PERF-02 | §3.1.1 交互 ≤500ms | Playwright `performance.now()` 采样 | 关键点击-反馈延迟 | P2 |
| TC-NF-PERF-03 | §3.1.2 列表 P95 ≤500ms | k6 | `p(95)<500ms` | P1 |
| TC-NF-PERF-04 | §3.1.2 详情 P95 ≤300ms | k6 | `p(95)<300ms` | P1 |
| TC-NF-PERF-05 | §3.1.2 登录注册 P95 ≤800ms | k6 | `p(95)<800ms` | P1 |
| TC-NF-PERF-06 | §3.1.3 ≥500 并发在线 | k6 scenario | 错误率 <1%,无 OOM | P2 |
| TC-NF-PERF-07 | §3.1.3 列表/详情 TPS ≥100 | k6 | 达标或出报告 | P2 |
### 6.2 安全性(§3.2
| TC ID | 要求 | 测试方法 | 通过条件 | 优先级 |
| :--- | :--- | :--- | :--- | :--- |
| TC-NF-SEC-01 | bcrypt 存储 | JDBC 读 `password` | 以 `$2a$` 等开头 | P0 |
| TC-NF-SEC-02 | 生产 HTTPS | 部署/config 检查 | 301 到 HTTPS | P1 |
| TC-NF-SEC-03 | SQL 注入 | 参数化模糊测试 / OWASP | 无异常泄露 | P0 |
| TC-NF-SEC-04 | XSS | API 注入脚本 | 无执行,已转义 | P0 |
| TC-NF-SEC-05 | CSRF | 需求要求校验 Token | **若项目为纯 JWT 无 Cookie** 则记差异并测 CORS | P1 |
| TC-NF-SEC-06 | 敏感接口限流 | 突增登录/注册 | 429 或业务限流 | P0 |
| TC-NF-SEC-07 | 日志无密码 Token | 扫日志输出 | 无明文 | P1 |
### 6.3 兼容性(§3.3
| TC ID | 范围 | 测试方法 | 优先级 |
| :--- | :--- | :--- | :--- |
| TC-NF-COMP-01 | Chrome/Edge/Safari 近三版本 | Playwright projects | P1 |
| TC-NF-COMP-02 | 视口 320~1920 | Playwright viewport 矩阵 | P1 |
| TC-NF-COMP-03 | 触控可点区域 | E2E `boundingBox` ≥44px | P2 |
### 6.4 可用性与运维(§3.4
| TC ID | 要求 | 测试方法 | 优先级 |
| :--- | :--- | :--- | :--- |
| TC-NF-AVAIL-01 | 月 99.5% | 监控外置,本项标 **manual/ops** | P3 |
| TC-NF-AVAIL-02 | 日备份 7 天 | 检查备份任务 | P3 |
| TC-NF-AVAIL-03 | RTO/RPO | 灾备演练 | P3 |
---
## 7. 权限矩阵用例(对应需求 §4.2)
**通则**:对每个「管理员 / 注册用户 / 访客」×「操作」组合生成 **允许成功****401/403** 断言。使用附录 A 中真实路径。
| TC ID | 矩阵坐标(模块·操作) | 角色 | 预期 |
| :--- | :--- | :--- | :--- |
| TC-PM-001 | 管理员登录·登录后台 | Admin | 成功 |
| TC-PM-002 | 管理员登录·登录后台 | User/Guest | 拒绝(无此入口或 403 |
| TC-PM-003 | 用户注册·提交申请 | Guest | 成功 |
| TC-PM-004 | 博客发布·创建 | Guest | 401 |
| TC-PM-005 | 博客发布·创建 | User | 成功 |
| TC-PM-006 | 博客浏览·公开列表 | Guest | 200 |
| TC-PM-007 | 博客浏览·私密文详情 | Guest | 404/403 |
| TC-PM-008 | 博客浏览·私密文详情 | Author | 200 |
| TC-PM-009 | 评论·发表评论 | Guest | 401 |
| TC-PM-010 | 评论·发表评论 | User | 200 |
| TC-PM-011 | 评论·删除/屏蔽 | User | 403 |
| TC-PM-012 | 评论·删除/屏蔽 | Admin | 200 |
| TC-PM-013 | 后台·用户列表 | User | 403 |
| TC-PM-014 | 后台·用户列表 | Admin | 200 |
| TC-PM-015 | 后台·分类标签 CRUD | Admin | 200 |
(实现完整矩阵时可脚本化:读取 §4.2 表生成组合。)
---
## 8. 界面与交互(对应需求 §5)
| TC ID | 来源 | 场景 | 建议工具 |
| :--- | :--- | :--- | :--- |
| TC-UI-001 | §5.1 对比度 WCAG AA | 首页/文章页 axe | Playwright+axe |
| TC-UI-002 | §5.1 深色模式 | 切换 theme DOM | E2E |
| TC-UI-003 | §5.2.1 列表卡片字段 | 标题摘要封面时间阅读量分类 | E2E 快照或字段断言 |
| TC-UI-004 | §5.2.1 悬停 scale | hover `transform` | E2E 可选 |
| TC-UI-005 | §5.2.1 骨架屏 | loading 状态 | E2E |
| TC-UI-006 | §5.2.2 详情排版/灯箱/分享 | 视项目是否存在按钮 | E2E |
| TC-UI-007 | §5.2.3 编辑页分栏/自动保存指示/二次确认 | E2E |
| TC-UI-008 | §5.2.4 移动端汉堡/单列/工具栏 | viewport 矩阵 |
| TC-UI-009 | §5.3 空/加载/错误/超时 UI | 网络 mock |
---
## 9. 测试验收与流程(对应需求 §6)
| 需求原文 | 转化为自动化门禁 |
| :--- | :--- |
| §6.1 功能全覆盖 | Jacoco/覆盖率报告 + TC 追溯矩阵 100% 可映射 |
| §6.2.1 性能 | k6 JOB 接 CI nightly |
| §6.2.2 安全 | OWASP ZAP 或依赖 `sqlmap` 仅 stag、密码 bcrypt 单测 |
| §6.2.3 兼容 | Playwright 多浏览器 project |
| §6.3 P0/P1 清零 | Issue 与 `@Tag("p0")` 对应 |
---
## 10. API 回归清单(与需求交叉的快捷索引)
> 详细路径与 HTTP 方法见附录 A;实现测试时 `{id}` 用例内替换。
**认证**`POST /api/public/user/login``POST /api/public/admin/login``POST /api/public/user/register``POST /api/public/refresh-token``GET /api/public/captcha`
**用户**`GET /api/app/user/me``POST/DELETE /api/app/user/{id}/follow``GET /api/admin/user/list``PUT /api/admin/user/{id}/reset-password``PUT /api/admin/user/{id}/status`
**文章**`GET /api/public/article/list``GET /api/public/article/{id}``POST /api/app/article``PUT /api/app/article/{id}``GET /api/app/article/mine``PUT /api/app/article/{id}/recycle``PUT /api/app/article/{id}/restore``DELETE /api/app/article/{id}``POST /api/app/article/{id}/like``GET/DELETE /api/admin/article/*`
**分类/标签**`GET /api/public/category/list``GET /api/public/tag/list``POST/PUT/DELETE /api/admin/category/*``POST /api/admin/tag`
**评论**`POST /api/app/comment``DELETE /api/app/comment/{id}``GET /api/app/comment/article/{articleId}``POST /api/app/comment/{id}/like``GET /api/admin/comment/list``PUT /api/admin/comment/{id}/audit``DELETE /api/admin/comment/{id}`
---
## 附录 A:后端路由(当前代码,`jog-*`)
| Controller / 前缀 | 方法摘要 |
| :--- | :--- |
| `/api/public`Auth | `POST /user/login``POST /admin/login``POST /user/register``GET /captcha``POST /refresh-token` |
| `/api/app/user` | `GET /me``GET /{id}``POST/DELETE /{id}/follow``POST /logout` |
| `/api/admin/user` | `GET /list``PUT /{id}/reset-password``PUT /{id}/status` |
| `/api/public/article` | `GET /list``GET /{id}` |
| `/api/app/article` | `POST /``PUT /{id}``GET /mine``PUT /{id}/recycle``PUT /{id}/restore``DELETE /{id}``POST /{id}/like` |
| `/api/admin/article` | `GET /list``DELETE /{id}` |
| `/api/public/category` | `GET /list` |
| `/api/admin/category` | `POST /``PUT /{id}``DELETE /{id}` |
| `/api/public/tag` | `GET /list` |
| `/api/admin/tag` | `POST /``name` 参数) |
| `/api/app/comment` | `POST /``DELETE /{id}``GET /article/{articleId}``POST /{id}/like` |
| `/api/admin/comment` | `GET /list``PUT /{id}/audit``DELETE /{id}` |
**契约**:实现后须将上表与 `jog-frontend/src/api/**/*.js``url`+`method` 对齐。
---
## 附录 B:追溯索引(验收 ID → 用例 ID 前缀)
| 需求 AC | 本文 TC |
| :--- | :--- |
| AC-ADM-LOGIN-* | TC-AC-ADM-LOGIN-0* |
| AC-USER-REG-* | TC-AC-USER-REG-0* |
| AC-USER-LOGIN-* | TC-AC-USER-LOGIN-0* |
| AC-BLOG-PUB-* | TC-AC-BLOG-PUB-0* |
| AC-BLOG-LIST-* | TC-AC-BLOG-LIST-0* |
| AC-COMMENT-* | TC-AC-COMMENT-0* |
---
## 附录 C`jog-system-requirements.md` 全部 AC 一行一用例(共 37 条)
| # | 需求 AC | 本文主用例 ID | 所在章节 |
|:-:| :--- | :--- | :--- |
| 1 | AC-ADM-LOGIN-01 | TC-AC-ADM-LOGIN-01 | §5.1.2 |
| 2 | AC-ADM-LOGIN-02 | TC-AC-ADM-LOGIN-02 | §5.1.2 |
| 3 | AC-ADM-LOGIN-03 | TC-AC-ADM-LOGIN-03 | §5.1.2 |
| 4 | AC-ADM-LOGIN-04 | TC-AC-ADM-LOGIN-04 | §5.1.2 |
| 5 | AC-ADM-LOGIN-05 | TC-AC-ADM-LOGIN-05 | §5.1.2 |
| 6 | AC-USER-REG-01 | TC-AC-USER-REG-01 | §5.2.2 |
| 7 | AC-USER-REG-02 | TC-AC-USER-REG-02 | §5.2.2 |
| 8 | AC-USER-REG-03 | TC-AC-USER-REG-03 | §5.2.2 |
| 9 | AC-USER-REG-04 | TC-AC-USER-REG-04 | §5.2.2 |
| 10 | AC-USER-REG-05 | TC-AC-USER-REG-05 | §5.2.2 |
| 11 | AC-USER-LOGIN-01 | TC-AC-USER-LOGIN-01 | §5.3.2 |
| 12 | AC-USER-LOGIN-02 | TC-AC-USER-LOGIN-02 | §5.3.2 |
| 13 | AC-USER-LOGIN-03 | TC-AC-USER-LOGIN-03 | §5.3.2 |
| 14 | AC-USER-LOGIN-04 | TC-AC-USER-LOGIN-04 | §5.3.2 |
| 15 | AC-USER-LOGIN-05 | TC-AC-USER-LOGIN-05 | §5.3.2 |
| 16 | AC-USER-LOGIN-06 | TC-AC-USER-LOGIN-06 | §5.3.2 |
| 17 | AC-BLOG-PUB-01 | TC-AC-BLOG-PUB-01 | §5.4.2 |
| 18 | AC-BLOG-PUB-02 | TC-AC-BLOG-PUB-02 | §5.4.2 |
| 19 | AC-BLOG-PUB-03 | TC-AC-BLOG-PUB-03 | §5.4.2 |
| 20 | AC-BLOG-PUB-04 | TC-AC-BLOG-PUB-04 | §5.4.2 |
| 21 | AC-BLOG-PUB-05 | TC-AC-BLOG-PUB-05 | §5.4.2 |
| 22 | AC-BLOG-PUB-06 | TC-AC-BLOG-PUB-06 | §5.4.2 |
| 23 | AC-BLOG-PUB-07 | TC-AC-BLOG-PUB-07 | §5.4.2 |
| 24 | AC-BLOG-LIST-01 | TC-AC-BLOG-LIST-01 | §5.5.2 |
| 25 | AC-BLOG-LIST-02 | TC-AC-BLOG-LIST-02 | §5.5.2 |
| 26 | AC-BLOG-LIST-03 | TC-AC-BLOG-LIST-03 | §5.5.2 |
| 27 | AC-BLOG-LIST-04 | TC-AC-BLOG-LIST-04 | §5.5.2 |
| 28 | AC-BLOG-LIST-05 | TC-AC-BLOG-LIST-05 | §5.5.2 |
| 29 | AC-BLOG-LIST-06 | TC-AC-BLOG-LIST-06 | §5.5.2 |
| 30 | AC-BLOG-LIST-07 | TC-AC-BLOG-LIST-07 | §5.5.2 |
| 31 | AC-COMMENT-01 | TC-AC-COMMENT-01 | §5.6.2 |
| 32 | AC-COMMENT-02 | TC-AC-COMMENT-02 | §5.6.2 |
| 33 | AC-COMMENT-03 | TC-AC-COMMENT-03 | §5.6.2 |
| 34 | AC-COMMENT-04 | TC-AC-COMMENT-04 | §5.6.2 |
| 35 | AC-COMMENT-05 | TC-AC-COMMENT-05 | §5.6.2 |
| 36 | AC-COMMENT-06 | TC-AC-COMMENT-06 | §5.6.2 |
| 37 | AC-COMMENT-07 | TC-AC-COMMENT-07 | §5.6.2 |
**FR 补充用例**(无单独 AC):`TC-FR-USER-REG-04`(§5.2.3)、`TC-FR-BLOG-LIST-06`(§5.5.3)。
---
**文档结束** — 本文档为 **Cursor / AI 生成自动化测试** 的单一输入源;新增需求时只改本文档并升版本号。