AI自进化第二版 (v2) - 测试用例报告
文档信息
| 项目 |
详情 |
| 测试对象 |
AIFlow AI自进化模块 v2 迭代 |
| 测试阶段 |
第一阶段 - 测试用例生成 |
| 测试工程师 |
QA Engineer |
| 文档日期 |
2026-05-30 |
| 基于文档 |
PRD-self-evolution-v2.md |
| 基于代码 |
evolution.py (348行), evolution_service.py (1220行), models.py (739-889行), EvolutionDashboard.tsx (1015行), EvolutionDashboard.css, ChatPage.tsx, api/index.ts |
1. 版本变更概览
1.1 PRD vs 实际代码实现对照
PRD v2 规划了 10 大功能、9 个新增 API端点、4 张新增表、5 个现有表新增字段。代码实现了其中大部分功能,但存在具体差异如下:
| PRD规划 |
代码实现状态 |
| xSkill流水线自动调度 (P0) |
✅ 已实现 PipelineScheduler (service层, 54-232行) |
| Watcher线程管理 (P0) |
✅ 已实现 EvolutionWatcherManager 单例 (235-374行) |
| 技能回滚 (P0) |
✅ 已实现 rollback API + 前端UI (evolution.py:229, EvolutionDashboard.tsx:101-114) |
| 萌芽动画 (P1) |
✅ 已实现 baby-sprout/staging-breathe CSS动画 (EvolutionDashboard.css:1020-1580) |
| 时间线导出 (P1) |
✅ 已实现导出菜单+模拟导出 (EvolutionDashboard.tsx:370-383) |
| 画像分享卡片 (P1) |
✅ 已实现3主题卡片+分享动作 (EvolutionDashboard.tsx:572-691) |
| Skill加载提示标签 (P1) |
✅ 已实现 (ChatPage.tsx:710-740, chat.py:238-250) |
| 技能市场联动 (P2) |
✅ 已实现 publish_to_market + 前端发布UI |
| 团队共享进化 (P2) |
✅ 已实现 share_to_team + 前端共享API |
| 进化报告推送 (P2) |
✅ 已实现 EvolutionReport 模型 + generate_report + ReportsPanel 前端 |
1.2 API端点对比
PRD v2 规划新增9个端点:
| PRD规划端点 |
方法 |
实际代码路径 |
状态 |
/skills/{name}/rollback/{version} |
POST |
/evolution/skills/{skill_name}/rollback/{version} (evolution.py:229) |
✅ 已实现 |
/skills/{name}/versions |
GET |
不存在: 仅有 /skills/{skill_name}/history (返回事件列表) |
❌ 缺失, GAP |
/skills/{name}/publish |
POST |
/evolution/skills/{skill_name}/publish (evolution.py:244) |
✅ 已实现 |
/reports/generate |
POST |
不存在: generate_report() 仅在service层定义, 无API暴露 |
❌ 缺失, GAP |
/reports |
GET |
/evolution/reports (evolution.py:307) |
✅ 已实现 |
/reports/{id} |
GET |
/evolution/reports/{report_id} (evolution.py:318) |
✅ 已实现 |
/watcher/status |
GET |
/evolution/watcher/status (evolution.py:296) |
✅ 已实现 |
/watcher/restart |
POST |
不存在: restart逻辑仅在 /pipeline/trigger 中内联调用 (evolution.py:291) |
❌ 缺失, GAP |
/team/sync |
POST |
不存在: 仅有 /skills/{name}/share-to-team (单个技能共享) |
❌ 缺失, GAP |
代码额外实现但PRD未要求:
| 端点 |
方法 |
说明 |
/evolution/pipeline/status |
GET |
流水线状态查询 - PRD v2 5.2 中规划, 但用户测试范围未列 |
/evolution/pipeline/trigger |
POST |
手动触发流水线 - PRD v2 5.2 中规划, 但用户测试范围未列 |
/evolution/skills/{name}/share-to-team |
POST |
团队共享 - PRD 5.4 中规划, 替代 team/sync |
/evolution/admin/watchers |
GET |
管理员全平台watcher汇总 |
1.3 数据库变更对比
| PRD 规划表 |
表名 |
状态 |
| 现有表新增字段 |
evolution_trajectories.error_msg |
✅ 模型已定义 (models.py:795) |
| 现有表新增字段 |
evolution_trajectories.retry_count |
✅ 模型已定义 (models.py:796) |
| 现有表新增字段 |
evolution_trajectories.tasks_extracted |
✅ 模型已定义 (models.py:797) |
| 现有表新增字段 |
messages.used_skills |
✅ 模型已定义 (models.py:100) |
| 现有表新增字段 |
user_evolution_config.watcher_error |
✅ 模型已定义 (models.py:749) |
| 新增表 |
skill_versions |
✅ 模型已定义 (models.py:818-833), ❌ 数据库中不存在 |
| 新增表 |
evolution_reports |
✅ 模型已定义 (models.py:836-850), ❌ 数据库中不存在 |
| 新增表 |
skill_publish_records |
✅ 模型已定义 (models.py:853-871), ❌ 数据库中不存在 |
| 新增表 |
team_shared_skills |
✅ 模型已定义 (models.py:874-888), ❌ 数据库中不存在 |
严重问题: 4张v2新增表在SQLAlchemy models中已定义,但实际MySQL数据库中未创建。这意味着:技能回滚需要 skill_versions 表、进化报告需要 evolution_reports 表、市场发布需要 skill_publish_records 表、团队共享需要 team_shared_skills 表。这些功能在表未创建的情况下将无法正常运行。
同样,现有表的5个新字段在模型层面已定义,但数据库层面未通过 DESC 验证确认存在(DESC messages 未显示 used_skills、DESC evolution_trajectories 未显示 error_msg/retry_count/tasks_extracted、DESC user_evolution_config 未显示 watcher_error)。
2. 测试范围与分类
2.1 测试分类维度
| 维度 |
说明 |
| P0 核心引擎 |
xSkill流水线调度、Watcher管理、技能回滚 |
| P1 体验增强 |
萌芽动画、时间线导出、画像分享、Skill标签 |
| P2 业务联动 |
技能市场联动、进化报告推送 |
| API端点 |
9个新增API + 流水线/团队共享API |
| 数据库 |
4张新表 + 5个新字段 |
| 前端交互 |
6大前端功能模块 |
2.2 统计摘要
| 类别 |
数量 |
| 功能模块 |
10 |
| API端点 |
15(含PRD规划的9个 + 代码额外实现的6个) |
| P0测试用例 |
26 |
| P1测试用例 |
28 |
| P2测试用例 |
21 |
| 数据库测试用例 |
7 |
| 数据隔离测试用例 |
6 |
| 测试用例总计 |
88 |
| PRD未覆盖代码功能 (GAP) |
9 |
| 代码未实现PRD需求 (缺失) |
4 |
3. P0 核心引擎类 - 测试用例
3.1 xSkill流水线自动调度 (PipelineScheduler)
API: GET /evolution/pipeline/status
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P0-001 |
P0 |
获取流水线状态 - 正常运行 |
用户已登录, watcher已启动 |
GET /app/api/evolution/pipeline/status |
返回200, code=0, data包含scheduler_running/watcher_status/pipeline_status/discovered_count/done_count/total_skills/total_trajectories |
| TC-EVO-V2-P0-002 |
P0 |
获取流水线状态 - 未启动 |
用户已登录, watcher未启动 |
GET /app/api/evolution/pipeline/status |
返回200, code=0, scheduler_running=false, watcher_status=unknown/stopped |
| TC-EVO-V2-P0-003 |
P1 |
未登录访问流水线状态 |
无认证token |
GET /app/api/evolution/pipeline/status |
返回401 |
| TC-EVO-V2-P0-004 |
P1 |
流水线状态数据隔离 |
user_a登录查看 |
GET /app/api/evolution/pipeline/status |
返回仅user_a的数据,不包含其他用户的数据 |
API: POST /evolution/pipeline/trigger
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P0-005 |
P0 |
手动触发流水线 |
用户已登录 |
POST /app/api/evolution/pipeline/trigger |
返回200, code=0, message="流水线已触发", watcher重新启动 |
| TC-EVO-V2-P0-006 |
P1 |
未登录触发流水线 |
无认证token |
POST /app/api/evolution/pipeline/trigger |
返回401 |
PipelineScheduler 功能逻辑
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P0-007 |
P0 |
轨迹自动状态流转 discovered->splitting->split_done->indexed->clustering->done |
创建一条status=discovered的轨迹, watcher运行中 |
等待PipelineScheduler扫描处理 |
轨迹依次经历6个状态, 最终status=done, processed_at非空 |
| TC-EVO-V2-P0-008 |
P0 |
AtomTask拆分模拟 - tasks_extracted更新 |
轨迹处理中 |
查看轨迹tasks_extracted字段 |
tasks_extracted值为2-5(模拟生成的atom数量) |
| TC-EVO-V2-P0-009 |
P0 |
轨迹处理创建SkillTrajectoryLink |
轨迹处理完成 |
查询skill_trajectory_links表 |
为每个atom创建了关联记录, skill_name为__pending__或真实技能名 |
| TC-EVO-V2-P0-010 |
P0 |
新轨迹归类到已有技能 |
用户已有至少1个技能 |
提交新轨迹并等待处理 |
轨迹的SkillTrajectoryLink指向已有技能, 技能use_count+1 |
| TC-EVO-V2-P0-011 |
P0 |
新轨迹创建新baby技能 |
用户无任何技能 |
提交新轨迹并等待处理 |
创建新baby技能new_skill_XXXXXXX, state=baby, version=1 |
| TC-EVO-V2-P0-012 |
P0 |
候选轨迹>=3自动baby->staging晋升 |
某baby技能关联轨迹>=3 |
PipelineScheduler处理更多轨迹 |
技能state自动从baby变为staging, 记录promoted事件 |
| TC-EVO-V2-P0-013 |
P0 |
轨迹处理失败 - error状态 |
模拟处理异常 (数据库连接中断等) |
轨迹处理失败 |
轨迹status=error, error_msg记录失败原因, retry_count递增 |
| TC-EVO-V2-P0-014 |
P1 |
轨迹处理重试机制 |
轨迹之前失败过(retry_count<3) |
PipelineScheduler再次扫描 |
尝试重新处理该轨迹 |
| TC-EVO-V2-P0-015 |
P1 |
PipelineScheduler停止信号 |
scheduler正在运行 |
调用scheduler.stop() |
_stop被设置, _run_loop退出, 线程终止 |
| TC-EVO-V2-P0-016 |
P1 |
PipelineScheduler扫描间隔 |
scheduler运行 |
观察扫描日志间隔 |
扫描间隔为poll_interval(默认30s) |
3.2 Watcher线程管理 (EvolutionWatcherManager)
API: GET /evolution/watcher/status
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P0-017 |
P0 |
获取Watcher状态 |
用户已登录, watcher已启动 |
GET /app/api/evolution/watcher/status |
返回200, data包含watcher_status/pipeline_status/pipeline_processed/scheduler_running/skill_count/trajectory_count |
| TC-EVO-V2-P0-018 |
P1 |
Watcher状态数据隔离 |
user_a和user_b分别查询 |
分别GET /app/api/evolution/watcher/status |
返回各自的数据, 互不包含 |
| TC-EVO-V2-P0-019 |
P2 |
管理员查看全平台watcher |
管理员登录 |
GET /app/api/evolution/admin/watchers |
返回200, data包含所有在运行scheduler的用户ID和运行状态 |
WatcherManager 功能逻辑
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P0-020 |
P0 |
启动用户进化引擎 (start_user_evolution) |
新用户无scheduler |
调用WatcherManager.start_user_evolution() |
scheduler被创建并启动, user_evolution_config表watcher_status=running, pipeline_status=running |
| TC-EVO-V2-P0-021 |
P0 |
重复启动已运行的进化引擎 |
用户engin已运行 |
再次调用start |
返回False, 提示已在运行 |
| TC-EVO-V2-P0-022 |
P0 |
停止用户进化引擎 (stop_user_evolution) |
用户engin运行中 |
调用WatcherManager.stop_user_evolution() |
scheduler线程停止, 从_schedulers移除, config表更新为stopped/idle |
| TC-EVO-V2-P0-023 |
P0 |
重启用户进化引擎 (restart_user_evolution) |
用户已运行 |
调用restart → 通过POST /evolution/pipeline/trigger触发 |
scheduler先停止再启动, pipeline_status重新变为running |
| TC-EVO-V2-P0-024 |
P1 |
达到最大scheduler限制 |
已有100个scheduler运行 |
新用户尝试启动 |
返回False, 提示达到数量限制 |
| TC-EVO-V2-P0-025 |
P1 |
优雅关闭所有scheduler |
多个scheduler运行中 |
调用shutdown_all() |
所有scheduler依次停止, 日志记录关闭过程 |
| TC-EVO-V2-P0-026 |
P1 |
watcher_error 字段写入 |
更新用户进化配置失败场景 |
触发配置更新失败 |
user_evolution_config.watcher_error 记录异常信息 |
3.3 技能回滚 (Skill Rollback)
API: POST /evolution/skills/{skill_name}/rollback/{version}
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P0-027 |
P0 |
回滚技能到指定版本 |
skill已存在, skill_versions表有目标版本记录, version=3 |
POST /app/api/evolution/skills/{name}/rollback/1 |
返回200, code=0, data包含回滚后的技能信息, version变为4 (3+1) |
| TC-EVO-V2-P0-028 |
P0 |
回滚后SKILL.md内容恢复 |
同上, skill_md_path存在 |
POST rollback |
SKILL.md文件被目标版本内容覆盖, 回滚前内容作为快照存入skill_versions |
| TC-EVO-V2-P0-029 |
P0 |
回滚后事件记录 |
回滚操作完成 |
查询evolution_events表 |
记录event_type="rolled_back", version_before=回滚前, version_after=回滚后, description含回滚版本信息 |
| TC-EVO-V2-P0-030 |
P0 |
技能不存在 |
skill不存在 |
POST /app/api/evolution/skills/nonexistent_skill/rollback/1 |
返回404, "技能或版本不存在" |
| TC-EVO-V2-P0-031 |
P0 |
目标版本不存在 |
skill存在但目标版本无记录 |
POST rollback to non-existing version |
返回404, "技能或版本不存在" |
| TC-EVO-V2-P0-032 |
P1 |
未登录回滚 |
无认证 |
POST rollback |
返回401 |
前端: VersionHistoryModal + 回滚确认
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P0-033 |
P0 |
版本历史弹窗打开 |
技能详情弹窗中 |
点击「版本历史」按钮 |
弹出版本历史弹窗, 显示事件列表(时间线格式), 每条含版本号/事件类型/时间/描述 |
| TC-EVO-V2-P0-034 |
P0 |
版本历史加载中状态 |
点击版本历史 |
API请求中 |
显示"加载中..."文字 |
| TC-EVO-V2-P0-035 |
P0 |
版本历史空状态 |
skill无历史事件 |
打开版本历史 |
显示"暂无版本历史" |
| TC-EVO-V2-P0-036 |
P0 |
当前版本标识 |
多个版本存在 |
查看版本历史 |
当前版本行显示"当前"标签, 非当前版本行才显示"回滚到此版本"按钮 |
| TC-EVO-V2-P0-037 |
P0 |
回滚确认弹窗 |
点击非当前版本的「回滚到此版本」按钮 |
弹出确认弹窗 |
弹窗标题「确认回滚?」, 显示目标版本和当前版本号对比 |
| TC-EVO-V2-P0-038 |
P0 |
确认回滚操作 |
回滚确认弹窗打开 |
点击「确认回滚」按钮 |
调用API, 成功后显示toast提示, 关闭弹窗 |
| TC-EVO-V2-P0-039 |
P0 |
取消回滚 |
回滚确认弹窗打开 |
点击「取消」按钮 |
关闭确认弹窗, 不调用API |
| TC-EVO-V2-P0-040 |
P1 |
回滚失败toast |
API返回错误 |
确认回滚 |
显示红色toast "回滚失败: {错误原因}" |
4. P1 体验增强类 - 测试用例
4.1 萌芽动画 (Baby/Staging Animations)
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P1-001 |
P1 |
baby技能萌芽脉冲动画 |
存在state=baby的技能, 动画开关=ON |
查看技能图谱面板 |
baby技能节点周期性缩放脉冲 scale(1.0→1.15→1.0) 周期2s, 粉色光晕淡入淡出 |
| TC-EVO-V2-P1-002 |
P1 |
staging技能呼吸动画 |
存在state=staging的技能, 动画开关=ON |
查看技能图谱面板 |
staging技能节点呼吸动画 scale(1.0→1.08→1.0) 周期3s, 橙色脉冲 |
| TC-EVO-V2-P1-003 |
P1 |
动画被关闭 |
动画开关=OFF |
查看技能图谱面板 |
baby/staging技能节点静态显示, 无CSS动画效果 |
| TC-EVO-V2-P1-004 |
P1 |
动画开关开关切换 |
默认动画开启 |
点击「动画效果」开关 |
动画立即开/关, CSS class变化 |
| TC-EVO-V2-P1-005 |
P1 |
动画偏好持久化 |
关闭动画 |
刷新页面重新加载驾驶舱 |
动画仍保持关闭状态 (localStorage evo_anim_enabled=false) |
| TC-EVO-V2-P1-006 |
P2 |
无baby/staging技能时 |
所有技能均为main/frozen |
查看技能图谱面板 |
所有节点静态显示, 无动画播放 |
| TC-EVO-V2-P1-007 |
P2 |
main/frozen技能无动画 |
各种状态的技能混合 |
检查main/frozen节点 |
main和frozen技能节点无CSS animation |
4.2 时间线导出 (Timeline Export)
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P1-008 |
P1 |
导出按钮显示 |
进化时间线面板激活 |
查看面板右上角 |
显示「导出」按钮 |
| TC-EVO-V2-P1-009 |
P1 |
导出下拉菜单 |
点击「导出」按钮 |
展开下拉菜单 |
显示两项: 「导出为 PNG」和「导出为 PDF」 |
| TC-EVO-V2-P1-010 |
P1 |
PNG导出触发 |
点击「导出为 PNG」 |
触发导出 |
显示"导出中..."按钮状态, 完成后显示toast: "时间线已导出为 PNG 格式: AI进化时间线_{用户名}_{日期}.png" |
| TC-EVO-V2-P1-011 |
P1 |
PDF导出触发 |
点击「导出为 PDF」 |
触发导出 |
同上, 格式为PDF |
| TC-EVO-V2-P1-012 |
P1 |
时间范围选择器 |
时间线面板 |
使用下拉菜单选择 |
有3个选项: 全部时间 / 最近30天 / 最近7天, 选择后时间线自动筛选 |
| TC-EVO-V2-P1-013 |
P1 |
导出遵循当前筛选 |
设置时间范围「最近7天」+ 事件类型「promoted」 |
点击导出 |
导出内容仅包含最近7天的promoted事件 (所见即所得) |
| TC-EVO-V2-P1-014 |
P2 |
导出时空时间线 |
筛选后无事件 |
点击导出 |
toast仍显示成功 (导出空白时间线) |
| TC-EVO-V2-P1-015 |
P2 |
导出按钮disabled状态 |
正在导出中 |
查看导出按钮 |
按钮显示"导出中..."且disabled |
4.3 画像分享卡片 (Profile Share Card)
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P1-016 |
P1 |
分享按钮存在 |
AI能力画像面板激活 |
查看面板右上角 |
显示「分享画像」按钮 (share图标) |
| TC-EVO-V2-P1-017 |
P1 |
分享弹窗打开 |
点击「分享画像」 |
弹出分享弹窗 |
弹窗标题「AI能力画像分享」, 显示卡片预览+主题切换+操作按钮 |
| TC-EVO-V2-P1-018 |
P1 |
3种主题切换 |
分享弹窗内 |
依次点击「深空蓝」「极光绿」「暖阳橙」主题 |
卡片背景色和各元素配色切换为对应主题 |
| TC-EVO-V2-P1-019 |
P1 |
卡片内容完整性 |
分享卡片预览 |
查看卡片 |
包含: 平台Logo + 标题「我的AI进化画像」 + 等级环 + 维度条 + 标签云(最多6个) + 日期水印「Qihu-AIFlow」 |
| TC-EVO-V2-P1-020 |
P1 |
保存到相册 |
分享弹窗 |
点击「保存到相册」按钮 |
关闭弹窗, toast显示"画像卡片已保存到相册(模拟)" |
| TC-EVO-V2-P1-021 |
P1 |
复制图片 |
分享弹窗 |
点击「复制图片」按钮 |
关闭弹窗, toast显示"画像卡片已复制图片(模拟)" |
| TC-EVO-V2-P1-022 |
P2 |
关闭分享弹窗 |
分享弹窗打开 |
点击背景或关闭按钮 |
弹窗关闭 |
| TC-EVO-V2-P1-023 |
P2 |
隐私保护验证 |
分享卡片预览 |
检查卡片内容 |
卡片仅包含聚合数据(等级/维度/标签), 不包含具体技能名称或对话内容 |
4.4 Skill加载提示标签 (Used Skills Tags)
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P1-024 |
P1 |
标签显示 |
用户有main状态技能, AI对话回复 |
发送消息等待AI回复 |
AI回复气泡下方显示标签, 格式: 图标 + "使用了专属技能:{技能名}" |
| TC-EVO-V2-P1-025 |
P1 |
多技能标签展示(<=3个) |
AI使用了2-3个技能 |
查看回复下方 |
2-3个标签横向排列 |
| TC-EVO-V2-P1-026 |
P1 |
多技能标签展示(>3个) |
AI使用了4+个技能 |
查看回复下方 |
显示3个技能标签 + "+N" 折叠标签 |
| TC-EVO-V2-P1-027 |
P1 |
标签点击跳转 |
消息下方有技能标签 |
点击技能标签 |
跳转到 #/evolution?skill={技能名} |
| TC-EVO-V2-P1-028 |
P1 |
无技能时不显示标签 |
用户无main状态技能, 发送消息 |
查看AI回复 |
AI回复下方无标签区域 |
| TC-EVO-V2-P1-029 |
P1 |
聊天API返回used_skills字段 |
发送消息 |
检查API响应 |
assistant_message.used_skills 存在, 为字符串数组 |
| TC-EVO-V2-P1-030 |
P1 |
技能使用后use_count更新 |
某技能被used_skills触发 |
查询该技能详情 |
use_count+1, last_used_at更新为当前时间 |
| TC-EVO-V2-P1-031 |
P2 |
标签样式 |
有技能标签的消息 |
查看UI |
标签为圆角样式, 左侧图标, 底色半透明 |
5. P2 业务联动类 - 测试用例
5.1 技能市场联动 (Publish to Market)
API: POST /evolution/skills/{skill_name}/publish
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P2-001 |
P2 |
发布main技能到市场 |
skill state=main, 未发布过 |
POST /app/api/evolution/skills/{name}/publish, body: {price: 0, market_description: "测试发布"} |
返回200, code=0, data含market_app_id, price, status="published" |
| TC-EVO-V2-P2-002 |
P2 |
非main状态发布失败 |
skill state=baby/staging |
POST publish |
返回404/error, 提示只有main状态技能可发布 |
| TC-EVO-V2-P2-003 |
P2 |
重复发布检测 |
skill已发布过 |
POST publish |
返回error, "该技能已发布到市场,不能重复发布" |
| TC-EVO-V2-P2-004 |
P2 |
发布后在market_apps表创建记录 |
发布成功 |
查询market_apps表 |
创建一条type=skill, source=user的记录, name="{技能名}(进化)" |
| TC-EVO-V2-P2-005 |
P2 |
发布后在skill_publish_records表创建记录 |
发布成功 |
查询skill_publish_records表 |
创建一条status=published的记录 |
| TC-EVO-V2-P2-006 |
P2 |
发布后事件记录 |
发布成功 |
查询evolution_events |
记录event_type="published" |
| TC-EVO-V2-P2-007 |
P2 |
技能不存在 |
skill不存在 |
POST publish |
返回404 |
| TC-EVO-V2-P2-008 |
P2 |
未登录发布 |
无认证 |
POST publish |
返回401 |
前端: 发布按钮+发布表单
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P2-009 |
P2 |
main技能显示发布按钮 |
技能详情弹窗, skill.state=main |
查看操作按钮区域 |
显示「发布到市场」按钮(金色边框) |
| TC-EVO-V2-P2-010 |
P2 |
非main技能不显示发布按钮 |
技能详情弹窗, skill.state=baby/staging/frozen |
查看操作按钮区域 |
不显示「发布到市场」按钮 |
| TC-EVO-V2-P2-011 |
P2 |
发布表单弹窗 |
点击「发布到市场」 |
弹窗显示 |
标题「发布到应用市场」, 显示技能名, 包含价格输入框(默认为0)和市场描述文本框 |
| TC-EVO-V2-P2-012 |
P2 |
发布表单提交 |
设置价格和市场描述 |
点击「确认发布」 |
调用API, 成功后显示toast "技能已发布到应用市场" |
| TC-EVO-V2-P2-013 |
P2 |
发布失败toast |
API返回错误 |
提交发布 |
显示toast "发布失败: {错误原因}" |
| TC-EVO-V2-P2-014 |
P2 |
取消发布 |
发布弹窗 |
点击「取消」 |
关闭弹窗 |
5.2 团队共享进化 (Share to Team)
API: POST /evolution/skills/{skill_name}/share-to-team
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P2-015 |
P2 |
分享技能到团队 |
技能存在, 用户是team owner |
POST /app/api/evolution/skills/{name}/share-to-team, body: {team_id: "valid_team_id"} |
返回200, code=0, data包含shared_id, skill_name, team_name |
| TC-EVO-V2-P2-016 |
P2 |
团队不存在 |
team_id无效 |
POST share-to-team |
返回error "团队不存在" |
| TC-EVO-V2-P2-017 |
P2 |
用户不属于该团队 |
用户不是team owner |
POST share-to-team |
返回error "用户不属于该团队" |
| TC-EVO-V2-P2-018 |
P2 |
重复分享 |
技能已分享至该团队 |
POST share-to-team |
返回error "该技能已分享至此团队" |
| TC-EVO-V2-P2-019 |
P2 |
技能不存在 |
技能不存在 |
POST share-to-team |
返回error "技能不存在或不属于当前用户" |
| TC-EVO-V2-P2-020 |
P2 |
分享后创建team_shared_skills记录 |
分享成功 |
查询team_shared_skills表 |
创建一条记录, 含team_id, skill_id, shared_by, is_public=true |
5.3 进化报告 (Evolution Reports)
API: GET /evolution/reports
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P2-021 |
P2 |
获取报告列表 |
用户有至少1条报告 |
GET /app/api/evolution/reports |
返回200, code=0, data为报告列表(按时间倒序), 每项含id, report_type, period_start, period_end, created_at |
| TC-EVO-V2-P2-022 |
P2 |
按类型过滤报告 |
用户有weekly和monthly报告 |
GET /app/api/evolution/reports?report_type=weekly |
仅返回weekly类型报告 |
| TC-EVO-V2-P2-023 |
P2 |
空报告列表 |
用户无报告 |
GET /app/api/evolution/reports |
返回空数组 [] |
API: GET /evolution/reports/{report_id}
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P2-024 |
P2 |
获取报告详情 |
报告存在 |
GET /app/api/evolution/reports/{id} |
返回200, data含report_data(JSON)包含summary/new_skills/upgrades/top_skills/dimensions |
| TC-EVO-V2-P2-025 |
P2 |
报告不存在 |
report_id无效 |
GET /app/api/evolution/reports/nonexistent_id |
返回404, "报告不存在" |
| TC-EVO-V2-P2-026 |
P2 |
数据隔离 |
user_a查询user_b的报告 |
GET /app/api/evolution/reports/{user_b_report_id} |
返回404或空 (不能看到其他用户报告) |
Service: generate_report
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P2-027 |
P2 |
生成周报 (weekly) |
用户有技能/轨迹/事件 |
调用EvolutionService.generate_report("weekly") |
创建evolution_reports记录, 含period_start=7天前, 统计新增技能/升级/调用次数/等级变化 |
| TC-EVO-V2-P2-028 |
P2 |
生成月报 (monthly) |
同上 |
调用generate_report("monthly") |
同上但period_start=30天前 |
| TC-EVO-V2-P2-029 |
P2 |
报告生成后发送通知 |
生成报告成功 |
查询notifications表 |
创建一条type="evolution_report"的通知 |
| TC-EVO-V2-P2-030 |
P2 |
不支持的报告类型 |
- |
调用generate_report("daily") |
返回error "不支持的报告类型: daily" |
前端: ReportsPanel
| TC-ID |
优先级 |
测试场景 |
前置条件 |
测试步骤 |
预期结果 |
| TC-EVO-V2-P2-031 |
P2 |
报告列表展示 |
驾驶舱切换到「进化报告」面板 |
进入面板 |
显示报告卡片列表, 每张卡片含报告类型图标+标题+时间段 |
| TC-EVO-V2-P2-032 |
P2 |
报告空列表状态 |
无报告 |
进入「进化报告」面板 |
显示"暂无进化报告。系统将在每周一自动生成周报。" |
| TC-EVO-V2-P2-033 |
P2 |
点击查看报告详情 |
报告列表有数据 |
点击某条报告 |
弹出报告详情弹窗, 显示概览(新增技能数/技能升级数/总调用次数) + TOP5最活跃技能 |
| TC-EVO-V2-P2-034 |
P2 |
关闭报告详情 |
报告详情弹窗 |
点击背景或关闭按钮 |
返回报告列表 |
| TC-EVO-V2-P2-035 |
P2 |
报告详情加载中 |
点击报告卡片 |
API请求中 |
报告列表页正常显示, 切换到详情时的loading由弹窗内处理 |
6. 数据库变更 - 测试用例
6.1 新增表验证
| TC-ID |
优先级 |
测试场景 |
测试步骤 |
预期结果 |
| TC-EVO-V2-DB-001 |
P0 |
skill_versions表结构 |
DESC aiflow.skill_versions |
表存在, 字段含: id, user_id, skill_name, version, skill_md_content(LONGTEXT), git_commit_sha, description, created_at |
| TC-EVO-V2-DB-002 |
P0 |
evolution_reports表结构 |
DESC aiflow.evolution_reports |
表存在, 字段含: id, user_id, report_type, period_start, period_end, report_data(JSON), created_at |
| TC-EVO-V2-DB-003 |
P0 |
skill_publish_records表结构 |
DESC aiflow.skill_publish_records |
表存在, 字段含: id, skill_id, skill_name, user_id, market_app_id, price, market_description, status, published_at, created_at |
| TC-EVO-V2-DB-004 |
P0 |
team_shared_skills表结构 |
DESC aiflow.team_shared_skills |
表存在, 字段含: id, team_id, skill_id, skill_name, shared_by, shared_by_name, is_public, created_at + uk_tss_team_skill唯一约束 |
6.2 现有表新增字段验证
| TC-ID |
优先级 |
测试场景 |
测试步骤 |
预期结果 |
| TC-EVO-V2-DB-005 |
P0 |
evolution_trajectories新字段 |
DESC aiflow.evolution_trajectories |
error_msg VARCHAR(500), retry_count INT DEFAULT 0, tasks_extracted INT DEFAULT 0 |
| TC-EVO-V2-DB-006 |
P0 |
messages.used_skills字段 |
DESC aiflow.messages |
used_skills JSON 字段存在 |
| TC-EVO-V2-DB-007 |
P0 |
user_evolution_config.watcher_error |
DESC aiflow.user_evolution_config |
watcher_error VARCHAR(500) 字段存在 |
7. 数据隔离 - 测试用例
| TC-ID |
优先级 |
测试场景 |
测试步骤 |
预期结果 |
| TC-EVO-V2-ISO-001 |
P0 |
回滚操作数据隔离 |
user_a对user_b的技能发起rollback |
返回404 (用户只能操作自己的技能) |
| TC-EVO-V2-ISO-002 |
P0 |
流水线状态数据隔离 |
user_a查询流水线状态 |
仅返回user_a的discovered/done/total数据 |
| TC-EVO-V2-ISO-003 |
P0 |
发布操作数据隔离 |
user_a对user_b的技能发起publish |
返回404 |
| TC-EVO-V2-ISO-004 |
P0 |
报告数据隔离 |
user_a查询报告 |
仅返回user_a的报告, 不含其他用户 |
| TC-EVO-V2-ISO-005 |
P0 |
团队共享数据隔离 |
user_a查询user_b团队的共享技能 |
非团队成员不可见 (由team_shared_skills关联team表约束) |
| TC-EVO-V2-ISO-006 |
P1 |
Watcher状态数据隔离 |
user_a查询watcher状态 |
仅返回user_a的watcher/scheduler/skill_count |
8. PRD未覆盖的代码功能 (GAP清单)
以下功能在代码中已实现,但PRD v2文档中未覆盖或差异较大:
| GAP编号 |
类型 |
描述 |
严重程度 |
代码位置 |
| GAP-V2-01 |
API差异 |
PRD规划 POST /reports/generate 但未实现API暴露, generate_report()仅在service层定义无路由 |
高 |
evolution_service.py:963-1063 |
| GAP-V2-02 |
API差异 |
PRD规划 GET /skills/{name}/versions (版本列表) 未实现, 仅有 /skills/{name}/history (事件列表) 复用 |
中 |
evolution.py:124-133 |
| GAP-V2-03 |
API差异 |
PRD规划 POST /watcher/restart 独立端点未实现, restart逻辑内联在pipeline/trigger中 |
中 |
evolution.py:284-293 |
| GAP-V2-04 |
API差异 |
PRD规划 POST /team/sync (批量团队同步)未实现, 仅有单个技能share-to-team |
中 |
evolution.py:259-271 |
| GAP-V2-05 |
前端差异 |
时间线导出为模拟实现 (setTimeout模拟), 未集成html2canvas/jsPDF库实现真实导出 |
高 |
EvolutionDashboard.tsx:370-383 |
| GAP-V2-06 |
前端差异 |
画像分享卡片为模拟实现 (toast显示"模拟"), 未集成html2canvas实现真实截图 |
高 |
EvolutionDashboard.tsx:582-587 |
| GAP-V2-07 |
数据库差异 |
4张v2新表在models中定义但数据库未创建 |
致命 |
models.py:818-888; MySQL confirmed missing |
| GAP-V2-08 |
数据库差异 |
5个现有表新字段在models中定义但数据库未确认存在 |
致命 |
models.py:795-797,100,749 |
| GAP-V2-09 |
API差异 |
PRD未规划但代码实现 GET /pipeline/status 和 POST /pipeline/trigger 两个流水线端点 - extra code |
信息 |
evolution.py:274-293 |
9. 代码中实现但PRD未覆盖的功能模块
| 编号 |
功能 |
代码位置 |
说明 |
| EXTRA-V2-01 |
PipelineScheduler 零技能冷启动处理 |
evolution_service.py:168-190 |
当用户无任何技能时, 自动创建new_skill_XXXXXXX baby技能 |
| EXTRA-V2-02 |
PipelineScheduler promoter 候选>=3自晋升 |
evolution_service.py:194-218 |
关联轨迹>=3自动 baby→staging, 记录promoted事件 |
| EXTRA-V2-03 |
PipelineScheduler pipeline_processed计数 |
evolution_service.py:224-230 |
轨迹处理完成后更新user_evolution_config.pipeline_processed |
10. 功能优先级分布
| 优先级 |
测试用例数 |
占比 |
| P0 |
26 |
29.5% |
| P1 |
28 |
31.8% |
| P2 |
21 |
23.9% |
| DB |
7 |
8.0% |
| ISO |
6 |
6.8% |
| 总计 |
88 |
100% |
11. 风险与建议
11.1 致命问题(阻塞测试)
1. 数据库表未创建(GAP-V2-07、GAP-V2-08)
4张v2新增表 (skill_versions, evolution_reports, skill_publish_records, team_shared_skills) 在SQLAlchemy models中已定义但在MySQL数据库中不存在。此外 evolution_trajectories 的 error_msg/retry_count/tasks_extracted、messages 的 used_skills、user_evolution_config 的 watcher_error 字段在数据库中也可能不存在。
影响范围: 技能回滚、进化报告、市场发布、团队共享功能将全部失败。PipelineScheduler的error_msg/retry_count写入也会失败。
建议: 需开发工程师执行数据库迁移(创建新表和新字段),然后再进入API测试阶段。
11.2 高风险问题
2. 前端导出/分享为模拟实现(GAP-V2-05、GAP-V2-06)
时间线PNG/PDF导出和画像分享卡片生成均使用setTimeout模拟,未集成html2canvas/jsPDF库。这意味着这两个功能目前只是UI展示,用户无法真正获得导出文件。
3. 报告生成API缺失(GAP-V2-01)
generate_report() 在service层实现了完整逻辑,但没有对应的API路由端点,前端无法主动触发报告生成。目前只能依赖外部定时任务触发。
11.3 中风险问题
4. 几个PRD规划的端点缺失(GAP-V2-02, GAP-V2-03, GAP-V2-04)
GET /skills/{name}/versions - 版本列表独立端点
POST /watcher/restart - 独立restart端点
POST /team/sync - 批量团队同步
其中技能版本列表功能有近似的history端点替代但语义不完全一致(history返回事件列表而非版本列表);watcher重启功能有pipeline/trigger替代;团队同步仅有单个技能共享。
12. 结论
AI自进化 v2 代码实现基本覆盖了PRD v2 规划的10大功能中的核心逻辑,23个API端点中有19个已实现(含PRD未明确规划的pipeline和团队共享端点)。前端6大交互体验功能全部有实现。当前阻塞测试的关键问题是数据库表未创建,建议优先修复此项后进入下一测试阶段。
文档状态: 已定稿
创建日期: 2026-05-30
测试用例总计: 88 条 (P0: 26, P1: 28, P2: 21, DB: 7, ISO: 6)
发现GAP: 9 项
发现PRD未覆盖代码功能: 3 项