844 lines
32 KiB
Markdown
844 lines
32 KiB
Markdown
|
|
# 测试用例 - H5 智能推荐重构
|
|||
|
|
|
|||
|
|
> **REQ 编号**: REQ-用户-006
|
|||
|
|
> **版本**: v1.0
|
|||
|
|
> **日期**: 2026-07-28
|
|||
|
|
> **作者**: 宋献 (Simon) + Duckula
|
|||
|
|
> **状态**: 🟡 待评审(基于 PRD v1.0-Frozen + 技术方案 v1.0)
|
|||
|
|
> **关联文档**:
|
|||
|
|
> - **PRD(冻结)**:`docs/01-产品文档/05-用户端H5/PRD-REQ-用户-006-智能推荐重构-v1.0-Frozen.md`
|
|||
|
|
> - **技术方案**:`docs/02-技术文档/技术架构/技术方案-REQ-用户-006-智能推荐重构-v1.0.md`
|
|||
|
|
> - **任务说明书**:`docs/07-项目管理/任务说明书/任务说明书-REQ-用户-006-智能推荐重构.md`
|
|||
|
|
> - **原型图**:`docs/01-产品文档/05-用户端H5/原型-REQ-用户-006-智能推荐重构-v1.0.html`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、基本信息
|
|||
|
|
|
|||
|
|
| 项目 | 内容 |
|
|||
|
|
|------|------|
|
|||
|
|
| **用例集名称** | TC-用户-006 H5 智能推荐重构 |
|
|||
|
|
| **关联 PRD** | REQ-用户-006 v1.0-Frozen(§4.7 已冻结) |
|
|||
|
|
| **用例总数** | 76 条(10 大类) |
|
|||
|
|
| **优先级分布** | P0 28 条 / P1 32 条 / P2 16 条 |
|
|||
|
|
| **关联决策** | 必须 100% 覆盖 PRD §4.7 5 个核心决策(① A / ② B / ③ B / ④ B / ⑤ B) |
|
|||
|
|
| **自动化目标** | 单元测试 100% 自动化 / E2E 关键路径自动化 / 灰度指标由数据埋点验证 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、测试范围
|
|||
|
|
|
|||
|
|
### 2.1 In-scope
|
|||
|
|
|
|||
|
|
- 后端 `asset_recommend_service.py` 重构(L1/L2/L3 + 中文匹配)
|
|||
|
|
- 后端新增 `recommend_progress_service.py`(T2 webhook + 轮询)
|
|||
|
|
- 后端新增 `topic_detector.py`(Jaccard 相似度)
|
|||
|
|
- 后端 `_step_assets` 改造(3s 超时 + 降级链路)
|
|||
|
|
- 前端 `recommendStore.ts` 状态机
|
|||
|
|
- 前端 `DynamicRecommend.vue` 重构(无标题 + FIFO + 4 类卡片)
|
|||
|
|
- 前端 `RightPanel.vue` 适配
|
|||
|
|
- WS 协议扩展(dynamic_recommend / asset_recommend / recommend_update)
|
|||
|
|
- localStorage 持久化
|
|||
|
|
- 数据模型(recommend_progress + recommend_event)
|
|||
|
|
|
|||
|
|
### 2.2 Out-of-scope
|
|||
|
|
|
|||
|
|
- 智能推荐算法升级(语义匹配/向量召回)→ v1.4+ 单独测
|
|||
|
|
- 坐席端 AI 辅助 → 不在本次范围
|
|||
|
|
- 多模态推荐 → PRD-REQ-AI-003 单独测
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、测试环境
|
|||
|
|
|
|||
|
|
| 项 | 配置 |
|
|||
|
|
|----|------|
|
|||
|
|
| **后端** | Python 3.13 / FastAPI / pytest |
|
|||
|
|
| **前端** | Vue 3 / TypeScript / Vitest |
|
|||
|
|
| **E2E** | agent-browser(Playwright) |
|
|||
|
|
| **数据库** | PostgreSQL 16 + Redis 7 |
|
|||
|
|
| **外部 mock** | Dify 推理 / 企微审批 webhook / 火绒 API |
|
|||
|
|
| **环境** | dev → staging → 生产灰度 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、用例分类规则
|
|||
|
|
|
|||
|
|
| 前缀 | 模块 | 用例数 |
|
|||
|
|
|------|------|--------|
|
|||
|
|
| TC-001 | 来源 A:Dify action(T0 同步) | 8 |
|
|||
|
|
| TC-002 | 来源 B:L1 关键词(T1 异步) | 10 |
|
|||
|
|
| TC-003 | 来源 C:L2 画像(T1 异步) | 10 |
|
|||
|
|
| TC-004 | 来源 D:L3 角色(T1 异步) | 8 |
|
|||
|
|
| TC-005 | 多源合并规则(决策 ② B) | 8 |
|
|||
|
|
| TC-006 | 冷启动策略(决策 ① A) | 6 |
|
|||
|
|
| TC-007 | 触发失败降级(决策 ③ B) | 8 |
|
|||
|
|
| TC-008 | 话题切换检测(决策 ④ B) | 8 |
|
|||
|
|
| TC-009 | 跨会话持久化(决策 ⑤ B) | 6 |
|
|||
|
|
| TC-010 | E2E 集成 + UI 行为 | 4 |
|
|||
|
|
| **合计** | | **76** |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、详细用例
|
|||
|
|
|
|||
|
|
### TC-001:来源 A - Dify action(T0 同步)
|
|||
|
|
|
|||
|
|
#### TC-001-1 [P0] 来源 A:AI 返回 action 后立即同步推送到左侧气泡
|
|||
|
|
- **前置条件**:用户进入新会话,员工端 WS 已连接
|
|||
|
|
- **测试步骤**:
|
|||
|
|
1. 用户发送"我要申请 VPN"
|
|||
|
|
2. Dify 返回 `{text: "好的", action: {approval_type: "vpn_access", title: "VPN 申请"}}`
|
|||
|
|
- **预期结果**:
|
|||
|
|
- WS `ai_reply` 立即到达(含文字 + action)
|
|||
|
|
- 左侧气泡显示"VPN 申请"操作卡(v2.3 后审批类只放左边)
|
|||
|
|
- 右侧栏 **不出现** 该审批卡(v2.3 决策)
|
|||
|
|
- **关联**:PRD §4.7.1 来源 A / 技术方案 §5.1 T0
|
|||
|
|
|
|||
|
|
#### TC-001-2 [P0] 来源 A:非审批类 action 同步推送到右侧栏
|
|||
|
|
- **前置条件**:同上
|
|||
|
|
- **测试步骤**:
|
|||
|
|
1. 用户发送"VPN 连不上怎么办"
|
|||
|
|
2. Dify 返回 `{text: "请重连", action: {type: "step_card", steps: [...]}}`
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 左侧气泡显示文字 + 来源图标
|
|||
|
|
- 右侧栏顶部插入操作步骤卡(蓝色边框,可展开)
|
|||
|
|
- **关联**:PRD §4.5 / §4.7.1 A
|
|||
|
|
|
|||
|
|
#### TC-001-3 [P1] 来源 A:action 为空时不推送右侧栏
|
|||
|
|
- **前置条件**:Dify 返回 `{text: "你好", action: null}`
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 左侧气泡显示文字
|
|||
|
|
- 右侧栏 **不增加** 任何卡片
|
|||
|
|
- 不出现"暂无推荐"提示
|
|||
|
|
- **关联**:技术方案 §4.1
|
|||
|
|
|
|||
|
|
#### TC-001-4 [P1] 来源 A:recommend_data 包含 source/trigger_timing/layer 字段
|
|||
|
|
- **前置条件**:触发 AI 回复(Dify 返回非空 action)
|
|||
|
|
- **测试步骤**:检查 WS 数据包
|
|||
|
|
- **预期结果**:
|
|||
|
|
- `recommend_data.source = "dify_action"`
|
|||
|
|
- `recommend_data.trigger_timing = "T0"`
|
|||
|
|
- `recommend_data.layer = "A"`
|
|||
|
|
- **关联**:技术方案 §5.1
|
|||
|
|
|
|||
|
|
#### TC-001-5 [P1] 来源 A:审批发起后立即在右侧栏顶部插入占位卡
|
|||
|
|
- **前置条件**:用户发起 VPN 审批(action.approval_type = "vpn_access")
|
|||
|
|
- **测试步骤**:
|
|||
|
|
1. 用户点击气泡中的"申请"
|
|||
|
|
2. 跳转企微审批表单
|
|||
|
|
3. 用户提交审批
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 提交瞬间右侧栏顶部插入审批进度占位卡(紫色边框,状态"pending")
|
|||
|
|
- 显示"VPN 申请 已发起,等待审批"
|
|||
|
|
- **关联**:技术方案 §5.3 T2 / PRD §4.7.2
|
|||
|
|
|
|||
|
|
#### TC-001-6 [P2] 来源 A:action.type 包含 contact_window 时只推左侧
|
|||
|
|
- **前置条件**:Dify 返回 `action.type = "contact_window"`
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 左侧气泡显示联系窗口按钮
|
|||
|
|
- 右侧栏 **不出现** 该卡(PRD §4.7.1 A 限制)
|
|||
|
|
- **关联**:PRD §4.7.1 来源 A 补充决策
|
|||
|
|
|
|||
|
|
#### TC-001-7 [P2] 来源 A:action.type 包含 contact_card 时只推左侧
|
|||
|
|
- **前置条件**:Dify 返回 `action.type = "contact_card"`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 左侧气泡显示联系人名片
|
|||
|
|
- 右侧栏不出现
|
|||
|
|
- **关联**:PRD §4.7.1 来源 A 补充决策
|
|||
|
|
|
|||
|
|
#### TC-001-8 [P2] 来源 A:action.type 包含 download 时只推左侧
|
|||
|
|
- **前置条件**:Dify 返回 `action.type = "download"`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 左侧气泡显示下载链接
|
|||
|
|
- 右侧栏不出现
|
|||
|
|
- **关联**:PRD §4.7.1 来源 A 补充决策
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-002:来源 B - L1 关键词匹配(T1 异步)
|
|||
|
|
|
|||
|
|
#### TC-002-1 [P0] 来源 B:用户消息包含精确关键词时命中
|
|||
|
|
- **前置条件**:assets.yaml 配置 `vpn` 关键词
|
|||
|
|
- **测试步骤**:用户发送"VPN 连不上"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏插入 L1 卡片(绿色边框)
|
|||
|
|
- 标题为"VPN 相关信息"
|
|||
|
|
- 置信度反映词频权重(≥ 0.5)
|
|||
|
|
- **关联**:PRD §4.7.1 来源 B / 技术方案 §4.2
|
|||
|
|
|
|||
|
|
#### TC-002-2 [P0] 来源 B:用户消息包含别名时也命中
|
|||
|
|
- **前置条件**:配置 alias "虚拟专用网络" → "vpn"
|
|||
|
|
- **测试步骤**:用户发送"虚拟专用网络怎么用"
|
|||
|
|
- **预期结果**:右侧栏插入 L1 VPN 卡片
|
|||
|
|
- **关联**:技术方案 §4.2 同义词表
|
|||
|
|
|
|||
|
|
#### TC-002-3 [P1] 来源 B:词频权重(短消息 + 高频词)
|
|||
|
|
- **前置条件**:用户发送"VPN"(仅 3 字)
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 VPN 卡插入
|
|||
|
|
- 置信度 = min(1.0, 1 × (3/3) × 10) = 1.0(短消息高权重)
|
|||
|
|
- **关联**:技术方案 §4.2 词频权重公式
|
|||
|
|
|
|||
|
|
#### TC-002-4 [P1] 来源 B:长消息中关键词被稀释
|
|||
|
|
- **前置条件**:用户发送长消息(> 50 字),仅 1 次包含 "VPN"
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 VPN 卡插入
|
|||
|
|
- 置信度较低(< 0.5),优先级低于其他高权重推荐
|
|||
|
|
- **关联**:技术方案 §4.2 长度归一化
|
|||
|
|
|
|||
|
|
#### TC-002-5 [P1] 来源 B:exclude_keywords 排除规则生效
|
|||
|
|
- **前置条件**:配置 `exclude_keywords: ["邮箱"]`
|
|||
|
|
- **测试步骤**:用户发送"我的收件箱打不开,邮箱登不上"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 邮箱卡 **不出现**(被排除)
|
|||
|
|
- 仅出现其他来源推荐
|
|||
|
|
- **关联**:技术方案 §4.2 排除关键词
|
|||
|
|
|
|||
|
|
#### TC-002-6 [P1] 来源 B:30 分钟同源抑制
|
|||
|
|
- **前置条件**:5 分钟前已推送过 L1 VPN 卡
|
|||
|
|
- **测试步骤**:用户再次发送"VPN 又连不上了"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 VPN 卡 **不重复推送**(30 分钟内同关键词抑制)
|
|||
|
|
- Redis 中存在 `suppress:{employee_id}:vpn` 键(TTL ≤ 30 分钟)
|
|||
|
|
- **关联**:PRD §4.7.3 同源抑制 / 技术方案 §6.4
|
|||
|
|
|
|||
|
|
#### TC-002-7 [P2] 来源 B:30 分钟后可再次推送
|
|||
|
|
- **前置条件**:30 分钟前推送过 L1 VPN 卡,Redis 键已过期
|
|||
|
|
- **测试步骤**:用户再次发送"VPN 连不上"
|
|||
|
|
- **预期结果**:L1 VPN 卡正常推送
|
|||
|
|
- **关联**:技术方案 §6.4
|
|||
|
|
|
|||
|
|
#### TC-002-8 [P1] 来源 B:用户消息包含多个关键词时多卡
|
|||
|
|
- **前置条件**:用户发送"VPN 连不上,邮箱也登不上"
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏插入 L1 VPN 卡 + L1 邮箱卡(2 张)
|
|||
|
|
- 按 layer 优先级 + confidence 排序
|
|||
|
|
- 总数 ≤ 3 张
|
|||
|
|
- **关联**:PRD §4.7.3 / 技术方案 §6.1
|
|||
|
|
|
|||
|
|
#### TC-002-9 [P2] 来源 B:消息完全不包含任何关键词时无 L1
|
|||
|
|
- **前置条件**:用户发送"今天天气真好"
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 来源 B 返回空列表
|
|||
|
|
- 继续走来源 C/D 降级链路
|
|||
|
|
- **关联**:技术方案 §4.2 / §6.1
|
|||
|
|
|
|||
|
|
#### TC-002-10 [P2] 来源 B:Dify 同步识别意图时,来源 B 可与 A 互补
|
|||
|
|
- **前置条件**:Dify 返回 action(来源 A),同时用户消息包含关键词
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 左侧气泡显示 A 来源卡片
|
|||
|
|
- 右侧栏同时显示 A 步骤卡 + B 关键词卡(不重复)
|
|||
|
|
- **关联**:技术方案 §6.1 去重
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-003:来源 C - L2 画像触发(T1 异步)
|
|||
|
|
|
|||
|
|
#### TC-003-1 [P0] 来源 C:火绒病毒库过期触发提醒
|
|||
|
|
- **前置条件**:员工画像 `huorong_virusdb_date` 距今 10 天
|
|||
|
|
- **测试步骤**:用户发送任意消息
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏插入 L2 提醒卡(橙色边框)
|
|||
|
|
- 标题"火绒病毒库过期"
|
|||
|
|
- 描述包含"已 N 天未更新"
|
|||
|
|
- **关联**:PRD §4.7.1 来源 C / 技术方案 §4.3
|
|||
|
|
|
|||
|
|
#### TC-003-2 [P0] 来源 C:火绒终端版本过旧触发提醒
|
|||
|
|
- **前置条件**:画像 `huorong_version = "5.0.50"`(< 5.0.73)
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L2 提醒卡插入
|
|||
|
|
- 描述"您的版本为 5.0.50,最新版本为 5.0.73"
|
|||
|
|
- **关联**:技术方案 §4.3
|
|||
|
|
|
|||
|
|
#### TC-003-3 [P0] 来源 C:终端防护离线触发最高优先级提醒
|
|||
|
|
- **前置条件**:画像 `huorong_offline_days = 5`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L2 提醒卡插入
|
|||
|
|
- priority = 100(最高)
|
|||
|
|
- **关联**:技术方案 §4.3
|
|||
|
|
|
|||
|
|
#### TC-003-4 [P1] 来源 C:联软违规项触发
|
|||
|
|
- **前置条件**:画像 `unionsoft_violations = ["禁用软件", "未安装补丁"]`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L2 提醒卡插入
|
|||
|
|
- extra.violations 包含违规项列表
|
|||
|
|
- **关联**:技术方案 §4.3
|
|||
|
|
|
|||
|
|
#### TC-003-5 [P1] 来源 C:系统补丁缺失触发
|
|||
|
|
- **前置条件**:画像 `unionsoft_patches_missing = 12`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:L2 提醒卡"系统补丁缺失"
|
|||
|
|
- **关联**:技术方案 §4.3
|
|||
|
|
|
|||
|
|
#### TC-003-6 [P0] 来源 C:画像 API 不可用时降级到 DB 缓存
|
|||
|
|
- **前置条件**:`employee_profile_service.get_profile()` 超时/异常
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 调用 `_get_cached_profile_from_db(employee_id)` 兜底
|
|||
|
|
- 如 DB 有缓存画像,按缓存触发 L2
|
|||
|
|
- 如 DB 也无,走来源 D 降级
|
|||
|
|
- **关联**:技术方案 §4.3 缓存画像 / PRD §4.7.5 决策 ③ B
|
|||
|
|
|
|||
|
|
#### TC-003-7 [P1] 来源 C:画像完全为空时(API + DB 都无)
|
|||
|
|
- **前置条件**:新员工,无任何画像数据
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 来源 C 返回空
|
|||
|
|
- 走来源 D 降级(C → D)
|
|||
|
|
- **关联**:PRD §4.7.5 / 技术方案 §4.3
|
|||
|
|
|
|||
|
|
#### TC-003-8 [P2] 来源 C:多个画像字段同时满足触发多张卡
|
|||
|
|
- **前置条件**:病毒库过期 + 版本过旧 + 离线 5 天
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 3 张 L2 提醒卡(按 priority 排序:离线 > 版本 > 病毒库)
|
|||
|
|
- 总数 + 其他来源 ≤ 3 张
|
|||
|
|
- **关联**:技术方案 §4.3 / §6.1
|
|||
|
|
|
|||
|
|
#### TC-003-9 [P2] 来源 C:画像字段格式异常时优雅跳过
|
|||
|
|
- **前置条件**:`huorong_version = ""`(空字符串)
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- try-except 捕获 AttributeError/ValueError
|
|||
|
|
- 该字段跳过,其他字段继续判定
|
|||
|
|
- **关联**:技术方案 §4.3 try-except
|
|||
|
|
|
|||
|
|
#### TC-003-10 [P1] 来源 C:T1 异步触发 3s 超时保护
|
|||
|
|
- **前置条件**:画像 API 响应缓慢(> 3s)
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- `asyncio.timeout(3.0)` 触发超时
|
|||
|
|
- 跳过来源 C,走来源 D
|
|||
|
|
- 不阻塞主对话流程
|
|||
|
|
- **关联**:技术方案 §5.2 / PRD §4.7.5
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-004:来源 D - L3 角色匹配(T1 异步)
|
|||
|
|
|
|||
|
|
#### TC-004-1 [P0] 来源 D:中文岗位名命中英文 role_assets key(精确)
|
|||
|
|
- **前置条件**:`profile.position = "开发工程师"` + 配置 `开发工程师: alias_of: developer`
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 来源 D 命中 developer 资源
|
|||
|
|
- L3 卡插入右侧栏(实际:按 v1.0 用户决策移到左侧)
|
|||
|
|
- **关联**:PRD §4.7.1 来源 D / 技术方案 §4.4 / §11 卡片归属
|
|||
|
|
|
|||
|
|
#### TC-004-2 [P0] 来源 D:中文岗位子串匹配
|
|||
|
|
- **前置条件**:`profile.position = "前端开发工程师"`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 子串匹配命中 "developer"
|
|||
|
|
- confidence = 0.7(子串匹配置信度低)
|
|||
|
|
- **关联**:技术方案 §4.4 子串匹配
|
|||
|
|
|
|||
|
|
#### TC-004-3 [P1] 来源 D:别名匹配(如 "研发" → "developer")
|
|||
|
|
- **前置条件**:`profile.position = "研发"` + 配置 `role_aliases.developer: ["研发", ...]`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 命中 developer 资源
|
|||
|
|
- confidence = 0.85
|
|||
|
|
- **关联**:技术方案 §4.4 role_aliases
|
|||
|
|
|
|||
|
|
#### TC-004-4 [P1] 来源 D:profile.position 为 None 时跳过
|
|||
|
|
- **前置条件**:新员工未填写岗位
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 来源 D 返回空
|
|||
|
|
- 走来源 B + C 降级(D 失败 → B + C)
|
|||
|
|
- **关联**:技术方案 §4.4
|
|||
|
|
|
|||
|
|
#### TC-004-5 [P1] 来源 D:英文 position 也能命中英文 key(兼容)
|
|||
|
|
- **前置条件**:`profile.position = "developer"`
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:精确匹配 developer,confidence = 1.0
|
|||
|
|
- **关联**:技术方案 §4.4
|
|||
|
|
|
|||
|
|
#### TC-004-6 [P2] 来源 D:双向子串匹配(key 包含 position)
|
|||
|
|
- **前置条件**:`profile.position = "开发"` + key = "developer"
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- "开发" 在 "developer" 里?否(中文不在英文里)
|
|||
|
|
- "developer" 在 "开发" 里?否
|
|||
|
|
- 来源 D 返回空(无命中)
|
|||
|
|
- **关联**:技术方案 §4.4 双向子串
|
|||
|
|
|
|||
|
|
#### TC-004-7 [P2] 来源 D:多个角色同时命中
|
|||
|
|
- **前置条件**:position = "开发"(命中 developer),但配置也有 "财务开发"
|
|||
|
|
- **测试步骤**:同上
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 多张 L3 卡
|
|||
|
|
- 按 confidence 排序
|
|||
|
|
- **关联**:技术方案 §4.4 / §6.1
|
|||
|
|
|
|||
|
|
#### TC-004-8 [P2] 来源 D:role_assets 配置变更热重载
|
|||
|
|
- **前置条件**:调用 `asset_service.reload()`
|
|||
|
|
- **测试步骤**:修改 assets.yaml 后调用 reload
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 配置生效,无需重启服务
|
|||
|
|
- 日志输出"配置热重载完成"
|
|||
|
|
- **关联**:技术方案 §4.4 reload()
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-005:多源合并规则(决策 ② B)
|
|||
|
|
|
|||
|
|
#### TC-005-1 [P0] 合并:同 recommend_id 去重,保留高 confidence
|
|||
|
|
- **前置条件**:A 来源产生 rec_001(confidence=0.85)+ B 来源也产生 rec_001(confidence=0.7)
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏仅 1 张 rec_001(保留 A 的 0.85)
|
|||
|
|
- **关联**:PRD §4.7.3 / 技术方案 §6.1
|
|||
|
|
|
|||
|
|
#### TC-005-2 [P0] 合并:layer 优先级排序 L1 > L2 > L3
|
|||
|
|
- **前置条件**:A 步骤卡(layer A)+ L1 关键词卡 + L2 画像卡 + L3 角色卡
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 排序:A > L1 > L2 > L3
|
|||
|
|
- 右侧栏显示:A 在最上
|
|||
|
|
- **关联**:技术方案 §6.2
|
|||
|
|
|
|||
|
|
#### TC-005-3 [P0] 合并:上限 3 张
|
|||
|
|
- **前置条件**:同时有 5 张推荐卡(A + 2 × L1 + L2 + L3)
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏仅 3 张
|
|||
|
|
- 超出 2 张按排序丢弃
|
|||
|
|
- **关联**:PRD §4.7.3 上限规则
|
|||
|
|
|
|||
|
|
#### TC-005-4 [P1] 合并:同 layer 内按 confidence DESC
|
|||
|
|
- **前置条件**:L1 VPN(0.85)+ L1 邮箱(0.7)
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 VPN 在 L1 邮箱上方
|
|||
|
|
- **关联**:技术方案 §6.1
|
|||
|
|
|
|||
|
|
#### TC-005-5 [P1] 合并:A 来源步骤卡优先级最高(layer A)
|
|||
|
|
- **前置条件**:A 步骤卡(layer A)+ L1 关键词卡
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:A 步骤卡在最上方(即使 confidence 较低)
|
|||
|
|
- **关联**:技术方案 §6.2 layer_priority
|
|||
|
|
|
|||
|
|
#### TC-005-6 [P1] 合并:进度回流卡插入最上方
|
|||
|
|
- **前置条件**:已有 2 张卡,审批状态变化触发 T2
|
|||
|
|
- **测试步骤**:企微审批 webhook 推送 status="approved"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 进度卡插入最上方(FIFO)
|
|||
|
|
- 已有的 2 张卡往下排
|
|||
|
|
- 超出上限时最旧的被丢弃
|
|||
|
|
- **关联**:PRD §4.7.7 / 技术方案 §5.3
|
|||
|
|
|
|||
|
|
#### TC-005-7 [P2] 合并:merge_recommends 算法纯函数测试
|
|||
|
|
- **前置条件**:单元测试
|
|||
|
|
- **测试步骤**:mock 4 个来源各返回 N 张卡
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 总数 ≤ 3
|
|||
|
|
- 排序符合 layer 优先级 + confidence
|
|||
|
|
- 同 ID 不重复
|
|||
|
|
- **关联**:技术方案 §6.1
|
|||
|
|
|
|||
|
|
#### TC-005-8 [P2] 合并:空输入返回空列表
|
|||
|
|
- **前置条件**:所有来源都返回空
|
|||
|
|
- **测试步骤**:调用 `merge_recommends([], [], [], [])`
|
|||
|
|
- **预期结果**:返回 `[]`
|
|||
|
|
- **关联**:技术方案 §6.1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-006:冷启动策略(决策 ① A)
|
|||
|
|
|
|||
|
|
#### TC-006-1 [P0] 冷启动:进会话 5s 内无消息 → 右侧栏完全空白
|
|||
|
|
- **前置条件**:用户进入新会话
|
|||
|
|
- **测试步骤**:观察右侧栏 5 秒
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏 **完全空白**
|
|||
|
|
- 不显示"暂无推荐"提示
|
|||
|
|
- 不显示"试试问 XXX"引导
|
|||
|
|
- **关联**:PRD §4.7.4 决策 ① A
|
|||
|
|
|
|||
|
|
#### TC-006-2 [P0] 冷启动:首条消息发出但 AI 未回复 → 右侧栏空白
|
|||
|
|
- **前置条件**:用户已发消息,AI 推理中
|
|||
|
|
- **测试步骤**:观察右侧栏
|
|||
|
|
- **预期结果**:右侧栏空白(与决策 ① A 一致)
|
|||
|
|
- **关联**:PRD §4.7.4
|
|||
|
|
|
|||
|
|
#### TC-006-3 [P0] 冷启动:AI 回复到达瞬间 → 真实推荐填充
|
|||
|
|
- **前置条件**:AI 推理完成
|
|||
|
|
- **测试步骤**:观察右侧栏变化
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 按 §4.7.3 合并规则填充
|
|||
|
|
- 顶部插入新卡
|
|||
|
|
- **关联**:PRD §4.7.4 场景 3
|
|||
|
|
|
|||
|
|
#### TC-006-4 [P0] 冷启动:完全不显示任何兜底
|
|||
|
|
- **前置条件**:所有来源都失败(L3 失败 + 无画像 + 无历史)
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏 **完全空白**
|
|||
|
|
- 不显示"暂无推荐,试试问 'VPN 怎么连'"提示
|
|||
|
|
- **关联**:PRD §4.7.4 决策 ① A + §4.7.5 全部失败
|
|||
|
|
|
|||
|
|
#### TC-006-5 [P1] 冷启动:store 状态机从 empty → populated
|
|||
|
|
- **前置条件**:前端 recommendStore 初始化
|
|||
|
|
- **测试步骤**:触发 AI 回复(A/B/C/D 任一产生卡)
|
|||
|
|
- **预期结果**:
|
|||
|
|
- state 从 `empty` → `populated`
|
|||
|
|
- visibleCards 非空
|
|||
|
|
- **关联**:技术方案 §7.1
|
|||
|
|
|
|||
|
|
#### TC-006-6 [P2] 冷启动:清空后 state 回到 empty
|
|||
|
|
- **前置条件**:已有卡,用户清空
|
|||
|
|
- **测试步骤**:调用 `store.clearAll()`
|
|||
|
|
- **预期结果**:state 回到 `empty`,visibleCards = []
|
|||
|
|
- **关联**:技术方案 §7.1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-007:触发失败降级(决策 ③ B)
|
|||
|
|
|
|||
|
|
#### TC-007-1 [P0] 降级:A 失败 → B + C + D
|
|||
|
|
- **前置条件**:Dify 返回非 JSON 或 action 为空
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 来源 A 跳过
|
|||
|
|
- 来源 B/C/D 正常执行
|
|||
|
|
- **关联**:PRD §4.7.5
|
|||
|
|
|
|||
|
|
#### TC-007-2 [P0] 降级:B 失败 → C + D
|
|||
|
|
- **前置条件**:用户消息不包含任何关键词(来源 B 返回空)
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 来源 B 跳过
|
|||
|
|
- 来源 C/D 正常执行
|
|||
|
|
- **关联**:PRD §4.7.5
|
|||
|
|
|
|||
|
|
#### TC-007-3 [P0] 降级:C 失败 → D(关键降级)
|
|||
|
|
- **前置条件**:画像 API 不可用 + DB 无缓存
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 来源 C 跳过
|
|||
|
|
- 来源 D 命中(如果有中文岗位)
|
|||
|
|
- 至少能展示 1 张卡(保证有内容)
|
|||
|
|
- **关联**:PRD §4.7.5 / 技术方案 §4.3
|
|||
|
|
|
|||
|
|
#### TC-007-4 [P0] 降级:D 失败 → 空
|
|||
|
|
- **前置条件**:profile.position 为 None + 用户消息无关键词 + 无画像
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 所有来源失败
|
|||
|
|
- 右侧栏空(按决策 ① A 走空状态)
|
|||
|
|
- **关联**:PRD §4.7.5
|
|||
|
|
|
|||
|
|
#### TC-007-5 [P0] 降级:全部失败 → 右侧栏空(与决策 ① 一致)
|
|||
|
|
- **前置条件**:所有来源都失败
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 右侧栏 **完全空白**
|
|||
|
|
- 不显示"暂无推荐"提示
|
|||
|
|
- **关联**:PRD §4.7.4 + §4.7.5
|
|||
|
|
|
|||
|
|
#### TC-007-6 [P1] 降级:T1 异步触发 3s 超时
|
|||
|
|
- **前置条件**:来源 B/C/D 全部响应缓慢
|
|||
|
|
- **测试步骤**:模拟慢响应
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 3s 超时触发
|
|||
|
|
- 不阻塞主对话
|
|||
|
|
- 右侧栏空
|
|||
|
|
- **关联**:技术方案 §5.2
|
|||
|
|
|
|||
|
|
#### TC-007-7 [P2] 降级:降级路径日志完整
|
|||
|
|
- **前置条件**:触发降级(C → D)
|
|||
|
|
- **测试步骤**:检查后端日志
|
|||
|
|
- **预期结果**:日志包含 `[AssetRecommend] 画像获取失败/超时(C → D 降级)`
|
|||
|
|
- **关联**:技术方案 §5.2 日志
|
|||
|
|
|
|||
|
|
#### TC-007-8 [P2] 降级:recommend_event 埋点记录降级触发次数
|
|||
|
|
- **前置条件**:降级发生时
|
|||
|
|
- **测试步骤**:检查 recommend_event 表
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 存在 `event_type='degraded'` 记录
|
|||
|
|
- 包含降级链路信息(C→D / 全部失败)
|
|||
|
|
- **关联**:技术方案 §11.2 埋点
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-008:话题切换检测(决策 ④ B)
|
|||
|
|
|
|||
|
|
#### TC-008-1 [P0] 话题切换:Jaccard 相似度 < 0.3 触发清空
|
|||
|
|
- **前置条件**:最近 3 条消息关键词集合 = {VPN, 重连, aTrust},新消息 = {会议室, 预定, 时间}
|
|||
|
|
- **测试步骤**:用户发送"帮我预定会议室"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- Jaccard = 0/6 = 0 < 0.3
|
|||
|
|
- 触发话题切换
|
|||
|
|
- L1 推荐清空(按 layer 清除)
|
|||
|
|
- **关联**:PRD §4.7.6 / 技术方案 §9.1
|
|||
|
|
|
|||
|
|
#### TC-008-2 [P0] 话题切换:Jaccard 相似度 ≥ 0.3 不触发清空
|
|||
|
|
- **前置条件**:最近 3 条 = {VPN, 重连, aTrust},新消息 = {VPN, 又连不上}
|
|||
|
|
- **测试步骤**:用户发送"VPN 又连不上了"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- Jaccard = 1/5 = 0.2 < 0.3(边界)
|
|||
|
|
- L1 保留(VPN 关键词继续命中)
|
|||
|
|
- **关联**:技术方案 §9.1
|
|||
|
|
|
|||
|
|
#### TC-008-3 [P1] 话题切换:意图突变触发清空
|
|||
|
|
- **前置条件**:Dify 上次返回 intent_type="vpn_query",本次 "meeting_book"
|
|||
|
|
- **测试步骤**:触发 AI 回复
|
|||
|
|
- **预期结果**:清空对应 layer 的推荐
|
|||
|
|
- **关联**:PRD §4.7.6 / 技术方案 §9.2
|
|||
|
|
|
|||
|
|
#### TC-008-4 [P1] 话题切换:会话分隔清空所有跨会话推荐
|
|||
|
|
- **前置条件**:用户点"结束会话"或新建会话
|
|||
|
|
- **测试步骤**:用户新建会话
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 所有跨会话推荐清空
|
|||
|
|
- L2/L3/progress 也清(按"会话分隔"规则)
|
|||
|
|
- **关联**:PRD §4.7.6
|
|||
|
|
|
|||
|
|
#### TC-008-5 [P1] 话题切换:L2/L3/progress 不被 L1 清空影响
|
|||
|
|
- **前置条件**:已有 L1 VPN + L2 病毒库 + progress VPN 申请
|
|||
|
|
- **测试步骤**:用户切换话题到"会议室"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 VPN 清空
|
|||
|
|
- L2 病毒库保留(与话题无关)
|
|||
|
|
- progress VPN 申请保留(跨会话持久)
|
|||
|
|
- **关联**:PRD §4.7.6
|
|||
|
|
|
|||
|
|
#### TC-008-6 [P2] 话题切换:算法纯函数测试
|
|||
|
|
- **前置条件**:单元测试
|
|||
|
|
- **测试步骤**:构造边界用例
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 空集合相似度 = 1.0
|
|||
|
|
- 完全相同相似度 = 1.0
|
|||
|
|
- 完全不同相似度 = 0
|
|||
|
|
- **关联**:技术方案 §9.1
|
|||
|
|
|
|||
|
|
#### TC-008-7 [P2] 话题切换:阈值为 0.3 边界测试
|
|||
|
|
- **前置条件**:Jaccard = 0.29 和 0.31
|
|||
|
|
- **测试步骤**:分别测试
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 0.29 < 0.3 → 触发
|
|||
|
|
- 0.31 ≥ 0.3 → 不触发
|
|||
|
|
- **关联**:技术方案 §9.1
|
|||
|
|
|
|||
|
|
#### TC-008-8 [P2] 话题切换:检测失败时静默跳过(不阻塞主流程)
|
|||
|
|
- **前置条件**:`extract_keywords` 抛异常
|
|||
|
|
- **测试步骤**:mock 异常
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 异常被捕获
|
|||
|
|
- 主对话正常进行
|
|||
|
|
- 不触发清空(保守处理)
|
|||
|
|
- **关联**:技术方案 §9.1 try-except
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-009:跨会话持久化(决策 ⑤ B)
|
|||
|
|
|
|||
|
|
#### TC-009-1 [P0] 持久化:L1 关键词推荐不持久化
|
|||
|
|
- **前置条件**:用户会话 1 产生 L1 VPN 卡
|
|||
|
|
- **测试步骤**:关闭浏览器,重新打开
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 VPN 卡 **不出现**(localStorage 无记录)
|
|||
|
|
- **关联**:PRD §4.7.7 / 技术方案 §10.2
|
|||
|
|
|
|||
|
|
#### TC-009-2 [P0] 持久化:L2 画像提醒持久化 30 天
|
|||
|
|
- **前置条件**:用户会话 1 产生 L2 火绒过期提醒
|
|||
|
|
- **测试步骤**:关闭浏览器,重新打开
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L2 提醒卡 **仍在**(localStorage 有记录)
|
|||
|
|
- 数据包含 `ttl_days: 30`
|
|||
|
|
- **关联**:PRD §4.7.7 / 技术方案 §10.2
|
|||
|
|
|
|||
|
|
#### TC-009-3 [P0] 持久化:L3 角色资源持久化
|
|||
|
|
- **前置条件**:用户会话 1 产生 L3 开发者资源
|
|||
|
|
- **测试步骤**:关闭浏览器,重新打开
|
|||
|
|
- **预期结果**:L3 卡仍在
|
|||
|
|
- **关联**:PRD §4.7.7
|
|||
|
|
|
|||
|
|
#### TC-009-4 [P0] 持久化:审批进度持久化直到完结
|
|||
|
|
- **前置条件**:用户发起 VPN 审批,progress 卡插入
|
|||
|
|
- **测试步骤**:
|
|||
|
|
1. 关闭浏览器,重新打开
|
|||
|
|
2. 企微审批 webhook 推送 status="completed"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 关闭前 progress 卡仍在
|
|||
|
|
- webhook 后 progress 卡标记"已完成"
|
|||
|
|
- 后续不再显示(已完结)
|
|||
|
|
- **关联**:PRD §4.7.7 / 技术方案 §5.3
|
|||
|
|
|
|||
|
|
#### TC-009-5 [P1] 持久化:localStorage 配额超限降级
|
|||
|
|
- **前置条件**:localStorage 写入失败(QuotaExceededError)
|
|||
|
|
- **测试步骤**:mock QuotaExceededError
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 捕获异常
|
|||
|
|
- LRU 淘汰最旧数据
|
|||
|
|
- 新数据正常写入
|
|||
|
|
- **关联**:技术方案 §10.1 / §15 R3
|
|||
|
|
|
|||
|
|
#### TC-009-6 [P2] 持久化:profile.position 变更时清空 L3
|
|||
|
|
- **前置条件**:用户从"开发"调到"财务"
|
|||
|
|
- **测试步骤**:修改 profile.position + 触发 AI 回复
|
|||
|
|
- **预期结果**:原 L3 开发者资源清空,命中新 L3 财务资源
|
|||
|
|
- **关联**:PRD §4.7.7
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### TC-010:E2E 集成 + UI 行为
|
|||
|
|
|
|||
|
|
#### TC-010-1 [P0] E2E:员工发"VPN 申请"完整链路
|
|||
|
|
- **前置条件**:agent-browser + dev 环境
|
|||
|
|
- **测试步骤**:
|
|||
|
|
1. 打开 H5 员工端
|
|||
|
|
2. 发送"我要申请 VPN"
|
|||
|
|
3. 观察 AI 回复 + 右侧栏
|
|||
|
|
4. 点击"申请"
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 左侧气泡显示"VPN 申请"操作卡
|
|||
|
|
- 右侧栏顶部插入审批进度占位卡
|
|||
|
|
- 跳转企微审批表单
|
|||
|
|
- **关联**:技术方案 §3.2 时序图 / 端到端
|
|||
|
|
|
|||
|
|
#### TC-010-2 [P0] E2E:话题切换 + 持久化组合
|
|||
|
|
- **前置条件**:已有 L1/L2/progress 卡
|
|||
|
|
- **测试步骤**:
|
|||
|
|
1. 用户切换话题
|
|||
|
|
2. 验证 L1 清空
|
|||
|
|
3. 验证 L2/progress 保留
|
|||
|
|
4. 关闭浏览器重新打开
|
|||
|
|
5. 验证 L2/progress 仍在
|
|||
|
|
- **预期结果**:所有规则同时生效
|
|||
|
|
- **关联**:综合
|
|||
|
|
|
|||
|
|
#### TC-010-3 [P0] UI:右侧栏无标题
|
|||
|
|
- **前置条件**:任意场景
|
|||
|
|
- **测试步骤**:观察右侧栏
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 顶部无"⚡ 智能推荐"标题
|
|||
|
|
- 顶部无"相关推荐"/"运维提醒"/"常用资源"分组标题
|
|||
|
|
- 仅卡片内容
|
|||
|
|
- **关联**:PRD §4.5
|
|||
|
|
|
|||
|
|
#### TC-010-4 [P0] UI:FIFO 插入验证
|
|||
|
|
- **前置条件**:先产生卡 A,再产生卡 B
|
|||
|
|
- **测试步骤**:观察卡片顺序
|
|||
|
|
- **预期结果**:B 在 A 上方(最新优先)
|
|||
|
|
- **关联**:PRD §4.5 / §4.7.3
|
|||
|
|
|
|||
|
|
#### TC-010-5 [P0] UI:边框颜色区分 layer
|
|||
|
|
- **前置条件**:同时有 L1/L2/L3 卡
|
|||
|
|
- **测试步骤**:观察每张卡左边框
|
|||
|
|
- **预期结果**:
|
|||
|
|
- L1 = 绿色
|
|||
|
|
- L2 = 橙色
|
|||
|
|
- L3 = 灰色
|
|||
|
|
- A = 蓝色
|
|||
|
|
- progress = 紫色
|
|||
|
|
- **关联**:PRD §4.5
|
|||
|
|
|
|||
|
|
#### TC-010-6 [P1] UI:操作步骤可展开
|
|||
|
|
- **前置条件**:A 来源步骤卡
|
|||
|
|
- **测试步骤**:点击"展开 ▼"
|
|||
|
|
- **预期结果**:显示完整步骤列表,按钮变"收起 ▲"
|
|||
|
|
- **关联**:PRD §4.6
|
|||
|
|
|
|||
|
|
#### TC-010-7 [P1] 性能:右侧栏渲染 < 200ms
|
|||
|
|
- **前置条件**:10 张卡准备就绪
|
|||
|
|
- **测试步骤**:使用浏览器 Performance API 测量
|
|||
|
|
- **预期结果**:render 时间 < 200ms
|
|||
|
|
- **关联**:技术方案 §14.1
|
|||
|
|
|
|||
|
|
#### TC-010-8 [P1] 性能:T1 异步触发 < 3s
|
|||
|
|
- **前置条件**:正常响应
|
|||
|
|
- **测试步骤**:测量从用户发消息到右侧栏出现卡的时间
|
|||
|
|
- **预期结果**:< 3s
|
|||
|
|
- **关联**:技术方案 §14.1
|
|||
|
|
|
|||
|
|
#### TC-010-9 [P1] 性能:T0 同步触发零延迟
|
|||
|
|
- **前置条件**:Dify 返回 action
|
|||
|
|
- **测试步骤**:测量 ai_reply 与右侧栏卡的时间差
|
|||
|
|
- **预期结果**:同一 WS 包发出(0ms 延迟)
|
|||
|
|
- **关联**:技术方案 §14.1
|
|||
|
|
|
|||
|
|
#### TC-010-10 [P1] WS 断连降级
|
|||
|
|
- **前置条件**:手动断开 WS
|
|||
|
|
- **测试步骤**:
|
|||
|
|
1. 断开 WS
|
|||
|
|
2. 触发 AI 回复
|
|||
|
|
3. 重连 WS
|
|||
|
|
- **预期结果**:
|
|||
|
|
- 断连期间 store 保持现有卡
|
|||
|
|
- 重连后增量同步
|
|||
|
|
- **关联**:技术方案 §14.2
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、验收标准对照(PRD §4.7 5 个决策)
|
|||
|
|
|
|||
|
|
| 决策 | 测试用例覆盖 | 状态 |
|
|||
|
|
|------|------------|------|
|
|||
|
|
| ① 冷启动 A | TC-006(6 条) | ✅ 100% |
|
|||
|
|
| ② 多源合并 B | TC-005(8 条) | ✅ 100% |
|
|||
|
|
| ③ 触发失败降级 B | TC-007(8 条) | ✅ 100% |
|
|||
|
|
| ④ 话题切换检测 B | TC-008(8 条) | ✅ 100% |
|
|||
|
|
| ⑤ 跨会话持久化 B | TC-009(6 条) | ✅ 100% |
|
|||
|
|
| §4.7.1 4 类触发源 | TC-001~004(36 条) | ✅ 100% |
|
|||
|
|
| §4.7.2 3 种触发时机 | TC-001~003(28 条) | ✅ 100% |
|
|||
|
|
| §4.7.5 触发失败降级 | TC-007(8 条) | ✅ 100% |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、灰度验证标准
|
|||
|
|
|
|||
|
|
| 阶段 | 规模 | 通过条件 | 用例支撑 |
|
|||
|
|
|------|------|---------|---------|
|
|||
|
|
| **1%** | 10 人,1 天 | 无 P0/P1 失败 | TC-010-1~10 全通过 |
|
|||
|
|
| **10%** | 100 人,2 天 | 点击率 > 5%(recommend_event 埋点) | TC-005/TC-009 |
|
|||
|
|
| **50%** | 500 人,3 天 | 点击率 > 10% | TC-005/TC-009 |
|
|||
|
|
| **100%** | 全量 | 点击率 > 15%,自助解决率 > 10% | 长期监控 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、风险与边界
|
|||
|
|
|
|||
|
|
| 边界场景 | 处理策略 |
|
|||
|
|
|---------|---------|
|
|||
|
|
| 浏览器禁用 localStorage | 持久化失效,仅当前会话有效 |
|
|||
|
|
| 用户清空浏览器数据 | 所有持久化数据丢失 |
|
|||
|
|
| 多设备登录同一账号 | localStorage 仅本机生效 |
|
|||
|
|
| Dify 升级改变 action 结构 | 兼容旧字段解析(向后兼容) |
|
|||
|
|
| 企微 webhook 推送频率异常 | 60s 轮询兜底 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、关联文档
|
|||
|
|
|
|||
|
|
- **PRD(冻结)**:`docs/01-产品文档/05-用户端H5/PRD-REQ-用户-006-智能推荐重构-v1.0-Frozen.md`
|
|||
|
|
- **技术方案**:`docs/02-技术文档/技术架构/技术方案-REQ-用户-006-智能推荐重构-v1.0.md`
|
|||
|
|
- **任务说明书**:`docs/07-项目管理/任务说明书/任务说明书-REQ-用户-006-智能推荐重构.md`
|
|||
|
|
- **原型图**:`docs/01-产品文档/05-用户端H5/原型-REQ-用户-006-智能推荐重构-v1.0.html`
|
|||
|
|
- **现有代码**:
|
|||
|
|
- `src/backend/tests/services/test_asset_recommend.py`(升级为 v2)
|
|||
|
|
- `src/backend/tests/services/test_recommend_progress.py`(新增)
|
|||
|
|
- `src/backend/tests/services/test_topic_detector.py`(新增)
|
|||
|
|
- `src/frontend-h5/tests/stores/recommendStore.test.ts`(新增)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十、变更日志
|
|||
|
|
|
|||
|
|
| 版本 | 日期 | 变更内容 | 作者 |
|
|||
|
|
|------|------|---------|------|
|
|||
|
|
| v1.0 | 2026-07-28 19:31 | 初版:76 条用例覆盖 4 类触发源 + 3 种时机 + 多源合并 + 冷启动 + 降级 + 话题切换 + 持久化 + E2E;100% 覆盖 PRD §4.7 5 个决策 | Duckula + 宋献 |
|