Files
qihuaiflow/tests/evolution-test-case-report.md
T
qyyfw 78ff261b5a 初始提交: Qihu-AIFlow v2.0.1 完整项目
- 前端 React+TypeScript (源码+构建产物)
- 后端 Python FastAPI
- 数据库迁移 001-015
- Docker部署配置
- 微信ClawBot API频道绑定
- 项目文档 README.md
2026-07-02 14:40:46 +08:00

28 KiB
Raw Permalink Blame History

测试用例 — AI自进化功能模块

1. 需求依据

  • PRD路径:/data/share/project/docs/PRD-self-evolution.md
  • 文档版本:v1.0(2026-05-26)
  • 功能概述:Qihu-AIFlow平台AI自进化功能。每个用户的AI在对话中持续学习进化,前端通过「AI进化驾驶舱」展示进化过程。深度整合xSkill开源框架,实现对话轨迹→原子任务→技能聚类→技能生成→灰度验证的完整流水线。

需求侧功能模块(共6大模块)

编号 需求模块 PRD章节 功能点数
R1 默认全局持续进化 7.2-功能一 5
R2 对话自动分析(xSkill流水线) 7.2-功能二 7
R3 技能库管理 7.2-功能三 6
R4 AI进化驾驶舱(4个子面板) 7.2-功能四 14
R5 与AI聊天无缝衔接 7.2-功能五 5
R6 数据隔离(用户级别) 7.2-功能六 6

2. 代码功能模块概览

2.1 后端代码模块

模块 说明 主要代码位置
技能管理API 技能CRUD、冻结/解冻、历史/轨迹查询 backend/python/app/api/evolution.py:33-139
进化事件API 进化事件列表查询 backend/python/app/api/evolution.py:143-157
驾驶舱数据API 技能树/时间线/统计/画像4面板数据 backend/python/app/api/evolution.py:160-202
轨迹提交API 对话轨迹提交入口 backend/python/app/api/evolution.py:205-214
EvolutionService 核心业务逻辑层,12个公开方法 backend/python/app/services/evolution_service.py
数据模型(ORM) 4张表定义 backend/python/app/models.py:741-792
路由注册 prefix="/app/api/evolution" backend/python/main.py:140

2.2 前端代码模块

模块 说明 主要代码位置
AI进化驾驶舱页面 主页面组件(4面板切换+数据加载) frontend/src/pages/front/EvolutionDashboard.tsx (631行)
驾驶舱样式 完整CSS样式 frontend/src/pages/front/EvolutionDashboard.css (1019行)
技能图谱面板 Panel A:按分类分组展示技能节点 EvolutionDashboard.tsx:48-152
进化时间线面板 Panel B:垂直时间线+事件筛选 EvolutionDashboard.tsx:155-201
技能使用统计面板 Panel C:排行+趋势图+饼图+提醒 EvolutionDashboard.tsx:205-340
AI能力画像面板 Panel D:等级环+雷达图+标签云+建议 EvolutionDashboard.tsx:344-500
evolutionAPI 前端API调用定义(15个方法) frontend/src/api/index.ts:415-455
类型定义 TypeScript interfaces frontend/src/types/index.ts:381-478
路由配置 #/evolution frontend/src/App.tsx:98
导航入口 侧边栏"AI进化" frontend/src/components/layout/FrontLayout.tsx:14

3. 需求与代码差异说明

3.1 PRD中未在代码中体现的内容

编号 PRD功能点 状态 说明
GAP-01 技能回滚:POST /skills/{name}/rollback/{version} ❌ 未实现 PRD明确要求回滚到历史版本,但API中无此端点,前端无回滚UI
GAP-02 对话溯源跳转:点击来源对话可跳转到原始对话记录 ❌ 未实现 PRD要求"点击可跳转到原始对话记录",前端技能详情弹窗中有来源轨迹按钮但仅调用API(evolutionAPI.getSkillTrajectories),后端 get_skill_trajectories 返回的是用户最近20条轨迹而非该技能的关联轨迹
GAP-03 新技能萌芽动画 ❌ 未实现 PRD面板A中要求"新技能生成时,技能树上有「萌芽」动画效果",前端代码中未找到相关CSS动画
GAP-04 时间线导出 ❌ 未实现 PRD面板B要求"支持将进化时间线导出为图片或PDF分享",前端代码中无导出功能
GAP-05 画像分享卡片 ❌ 未实现 PRD面板D要求"支持将AI能力画像生成为分享卡片",前端代码中无此功能
GAP-06 Skill加载提示标签 ❌ 未实现 PRD功能五要求"在消息下方显示小标签:🚀 使用了你的专属技能:XXX",代码中未见此实现
GAP-07 对话结束钩子(自动提交轨迹) ❌ 未自动触发 PRD要求对话结束时自动提交轨迹,但当前仅提供手动API入口 /trajectory/submit,前端ChatPage中未见对话结束自动调用的钩子
GAP-08 Watcher线程管理 ❌ 未实现 PRD要求用户注册后自动启动watcher线程持续进化,UserEvolutionConfig模型已定义但服务层无读写该表的代码,watcher状态管理未实现
GAP-09 xSkill管线自动调度 ❌ 未实现 PRD要求轨迹进入xSkill流水线自动处理,但后端仅实现轨迹落盘(status=discovered),后续状态流转(splitting→...→done)依赖外部xSkill进程
GAP-10 统计图表的交互联动 ❌ 未实现 PRD面板C要求"点击统计图表中的任意项可跳转到对应技能详情",前端StatisticsPanel中无此交互

3.2 PRD中未覆盖但代码中存在的功能模块

编号 代码模块 位置 说明 建议产品确认
EXTRA-01 evolutionAPI.submitTrajectory 提供独立的手动轨迹提交入口 api/index.ts:453 前端API层暴露了轨迹提交方法,但在当前驾驶舱页面中未被任何组件调用 是否需要在驾驶舱中增加手动提交轨迹的入口?
EXTRA-02 能力维度雷达图使用内联SVG实现 EvolutionDashboard.tsx:398-466 前端用内联SVG而非第三方图表库绘制雷达图,包含5层参考多边形、轴线、数据多边形 技术决策,无需产品确认

4. 测试用例

4.1 技能管理 API

TC-SKILL-01 [P0] 验证获取当前用户技能列表

  • 前置条件:用户已登录;数据库中存在该用户的技能数据
  • 步骤: [1] 使用有效JWT Token调用 GET /app/api/evolution/skills [2] 检查响应状态码和结构
  • 预期结果:
    • HTTP 200,响应包含 code: 0
    • data 为数组,每项包含 id, skill_name, description, tags, category, state, use_count, version, created_at, updated_at
    • 仅返回当前用户的技能数据,不包含其他用户的技能
  • 备注:默认按 updated_at 降序排列

TC-SKILL-02 [P0] 验证按状态过滤技能

  • 前置条件:数据库中存在不同状态的技能
  • 步骤: [1] 调用 GET /app/api/evolution/skills?state=baby [2] 调用 GET /app/api/evolution/skills?state=main [3] 调用 GET /app/api/evolution/skills?state=frozen [4] 调用 GET /app/api/evolution/skills?state=staging
  • 预期结果:
    • 每次返回的技能 state 字段均匹配查询参数
    • 传入无效状态值时系统行为一致(返回空列表或400错误)
  • 备注:P0 覆盖核心过滤逻辑

TC-SKILL-03 [P0] 验证按关键词搜索技能

  • 前置条件:数据库中存在技能名包含"python"和"写作"的技能
  • 步骤: [1] 调用 GET /app/api/evolution/skills?keyword=python [2] 调用 GET /app/api/evolution/skills?keyword=写作 [3] 调用 GET /app/api/evolution/skills?keyword=不存在的关键词
  • 预期结果:
    • [1][2] 返回 skill_name 包含关键词的技能
    • [3] 返回空列表
  • 备注:模糊匹配

TC-SKILL-04 [P1] 验证技能列表排序功能

  • 前置条件:数据库中存在多条技能记录
  • 步骤: [1] 调用 GET /app/api/evolution/skills?sort_by=use_count&order=desc [2] 调用 GET /app/api/evolution/skills?sort_by=created_at&order=asc [3] 调用 GET /app/api/evolution/skills?sort_by=invalid_field
  • 预期结果:
    • [1] 按使用次数降序排列
    • [2] 按创建时间升序排列
    • [3] 返回错误或默认排序回退

TC-SKILL-05 [P0] 验证获取技能详情

  • 前置条件:数据库中存在技能名为"fix_python_bug"的技能
  • 步骤: [1] 调用 GET /app/api/evolution/skills/fix_python_bug [2] 调用 GET /app/api/evolution/skills/不存在的技能名
  • 预期结果:
    • [1] HTTP 200,返回完整技能信息(含 skill_md_content 字段)
    • [2] HTTP 404,提示技能不存在
  • 备注:如果 skill_md_path 文件存在,skill_md_content 应包含文件内容

TC-SKILL-06 [P0] 验证编辑技能元数据

  • 前置条件:存在可编辑的技能
  • 步骤: [1] 调用 PUT /app/api/evolution/skills/{skill_name},body: {"description": "新描述", "tags": ["新标签"], "category": "新分类"} [2] 再次获取该技能详情,检查变更 [3] 检查进化事件表中是否记录了编辑事件
  • 预期结果:
    • [1] HTTP 200,返回更新后的技能对象,version 字段 +1
    • [2] 技能详情反映变更
    • [3] evolution_events 表中新增一条 event_type="edited" 的记录,含 version_before/version_after
  • 备注:仅可编辑 description, tags, category

TC-SKILL-07 [P0] 验证删除技能

  • 前置条件:存在可删除的技能
  • 步骤: [1] 记录删除前的技能列表总数 N [2] 调用 DELETE /app/api/evolution/skills/{skill_name} [3] 调用 GET /app/api/evolution/skills 检查技能列表 [4] 调用 GET /app/api/evolution/skills/{skill_name} 确认已不存在 [5] 检查进化事件表中是否记录了删除事件
  • 预期结果:
    • [2] HTTP 200
    • [3] 技能列表总数为 N-1
    • [4] HTTP 404
    • [5] evolution_events 表中新增 event_type="deleted" 的记录
  • 备注:删除后事件表仍保留历史记录

TC-SKILL-08 [P0] 验证冻结技能

  • 前置条件:存在一个 state 为 "main" 的技能
  • 步骤: [1] 调用 POST /app/api/evolution/skills/{skill_name}/freeze [2] 调用 GET /app/api/evolution/skills/{skill_name} 确认状态 [3] 对已冻结的技能再次调用 freeze
  • 预期结果:
    • [1] HTTP 200,state 变为 "frozen"
    • [2] state 为 "frozen"
    • [3] 幂等操作,不报错(state 保持 "frozen")
    • 事件表中新增 event_type="frozen" 的记录

TC-SKILL-09 [P0] 验证解冻技能

  • 前置条件:存在一个 state 为 "frozen" 的技能
  • 步骤: [1] 调用 POST /app/api/evolution/skills/{skill_name}/unfreeze [2] 调用 GET /app/api/evolution/skills/{skill_name} 确认状态
  • 预期结果:
    • [1] HTTP 200,state 变为 "main"
    • [2] state 为 "main"
    • 事件表中新增 event_type="unfrozen" 的记录

TC-SKILL-10 [P1] 验证技能版本历史查询

  • 前置条件:某技能经历多次编辑/冻结/解冻操作
  • 步骤: [1] 调用 GET /app/api/evolution/skills/{skill_name}/history [2] 检查返回的事件列表
  • 预期结果:
    • HTTP 200,返回按照 created_at 排序的事件列表
    • 每项包含 event_type, description, version_before, version_after, created_at
    • 支持未操作过的技能(返回空数组)

TC-SKILL-11 [P1] 验证技能来源轨迹查询

  • 前置条件:存在技能和对应的轨迹数据
  • 步骤: [1] 调用 GET /app/api/evolution/skills/{skill_name}/trajectories
  • 预期结果:
    • HTTP 200
    • 返回该技能的关联轨迹列表(最多20条)
  • 备注:后端 get_skill_trajectories 当前仅按 user_id 过滤,未按 skill_name 过滤——此为缺陷,已记录在 3.1 GAP-02

4.2 进化事件 API

TC-EVENT-01 [P0] 验证获取进化事件列表

  • 前置条件:数据库中已有多条进化事件记录
  • 步骤: [1] 调用 GET /app/api/evolution/events [2] 检查返回的事件列表
  • 预期结果:
    • HTTP 200,最多返回50条(默认 limit)
    • 每项包含 id, skill_name, event_type, description, version_before, version_after, created_at
    • 仅返回当前用户的进化事件

TC-EVENT-02 [P1] 验证按事件类型筛选

  • 前置条件:数据库中有不同类型的进化事件
  • 步骤: [1] 调用 GET /app/api/evolution/events?event_type=created [2] 调用 GET /app/api/evolution/events?event_type=frozen [3] 调用 GET /app/api/evolution/events?event_type=edited
  • 预期结果:每次返回的事件类型均匹配筛选条件

TC-EVENT-03 [P1] 验证按技能名筛选事件

  • 前置条件:某技能有多个关联事件
  • 步骤: [1] 调用 GET /app/api/evolution/events?skill_name={skill_name}
  • 预期结果:仅返回该技能相关的进化事件

TC-EVENT-04 [P2] 验证limit参数边界

  • 前置条件:数据库中有大量事件记录
  • 步骤: [1] 调用 GET /app/api/evolution/events?limit=1 [2] 调用 GET /app/api/evolution/events?limit=200 [3] 调用 GET /app/api/evolution/events?limit=201 [4] 调用 GET /app/api/evolution/events?limit=0
  • 预期结果:
    • [1] 返回1条
    • [2] 返回最多200条
    • [3] 返回错误或限制到200
    • [4] 返回错误或默认50条

4.3 驾驶舱面板 API

TC-DASH-01 [P0] 验证技能图谱数据 (dashboard/skill-tree)

  • 前置条件:用户拥有多个分类的技能
  • 步骤: [1] 调用 GET /app/api/evolution/dashboard/skill-tree [2] 检查返回结构
  • 预期结果:
    • HTTP 200
    • data.categories 为数组,每组包含 name 和 skills[]
    • data 包含统计字段:total_count, main_count, baby_count, staging_count, frozen_count
    • 技能数据仅限当前用户

TC-DASH-02 [P0] 验证进化时间线数据 (dashboard/timeline)

  • 前置条件:用户有进化事件记录
  • 步骤: [1] 调用 GET /app/api/evolution/dashboard/timeline [2] 检查返回数据
  • 预期结果:
    • HTTP 200
    • 返回事件列表,按 created_at 降序
    • 支持 event_type 筛选参数
    • 无事件时返回空数组

TC-DASH-03 [P0] 验证技能使用统计 (dashboard/statistics)

  • 前置条件:用户有使用统计的历史数据
  • 步骤: [1] 调用 GET /app/api/evolution/dashboard/statistics [2] 检查返回数据结构
  • 预期结果:
    • HTTP 200
    • data 包含字段:ranking[](TOP N排行)、total_use_count、category_distribution[]、daily_trend[]、low_use_skills[]
    • ranking 中每项含 skill_name, category, use_count, state, last_used_at
    • daily_trend 数据点含 date, count

TC-DASH-04 [P0] 验证AI能力画像 (dashboard/profile)

  • 前置条件:用户有足够的技能数据支撑画像计算
  • 步骤: [1] 调用 GET /app/api/evolution/dashboard/profile [2] 检查返回结构
  • 预期结果:
    • HTTP 200
    • data 包含字段:level(1-10的等级)、level_title(等级称号)、total_skills、active_skills、staging_skills、baby_skills、total_use_count
    • data.dimensions 为数组,每项含 label, value, maxValue
    • data.tags 为能力标签数组
    • data.growth_suggestions 为成长建议数组

TC-DASH-05 [P1] 验证驾驶舱数据空态响应

  • 前置条件:用户为新用户,无任何进化数据
  • 步骤: [1] 分别调用4个驾驶舱API端点 [2] 检查响应
  • 预期结果:均返回 HTTP 200,数据字段为空数组或零值,不报错

4.4 轨迹提交 API

TC-TRAJ-01 [P0] 验证提交对话轨迹

  • 前置条件:用户已登录
  • 步骤: [1] 调用 POST /app/api/evolution/trajectory/submit body: {"conversation_id": "conv-001", "messages": [{"role": "user", "content": "帮我写一个Python函数"}, {"role": "assistant", "content": "好的..."}]} [2] 检查响应 [3] 检查数据库 evolution_trajectories 表中新增记录 [4] 检查文件系统中轨迹文件是否生成
  • 预期结果:
    • [1] HTTP 200,message 为"轨迹已提交"
    • [2] data 包含 id, conversation_id, file_path, status="discovered", atom_count=0
    • [3] 数据库中有新记录,user_id 为当前用户
    • [4] 轨迹文件存在于 /data/share/project/data/users/{user_id}/trajectories/traj_{id}/traj_{id}.md

TC-TRAJ-02 [P1] 验证提交轨迹消息格式兼容性

  • 前置条件:用户已登录
  • 步骤: [1] 提交包含多条轮次对话的轨迹 [2] 读取生成的轨迹文件内容
  • 预期结果:
    • 轨迹文件格式为xSkill兼容的Markdown:# Conversation Trajectory + ## User / ## Assistant 交替分段
    • token_used 正确累计所有消息的 tokens 字段

TC-TRAJ-03 [P1] 验证轨迹提交数据隔离

  • 前置条件:两个不同用户(userA 和 userB)
  • 步骤: [1] userA 提交一个轨迹 [2] userB 调用 GET /app/api/evolution/events 查询事件 [3] userB 调用 GET /app/api/evolution/skills 查询技能
  • 预期结果:
    • [2] userB 看不到 userA 的轨迹数据
    • [3] userB 的技能数据不包含 userA 的技能

TC-TRAJ-04 [P2] 验证提交空消息列表

  • 前置条件:用户已登录
  • 步骤: [1] 调用 POST /app/api/evolution/trajectory/submit,body: {"conversation_id": "conv-empty", "messages": []}
  • 预期结果:
    • 返回成功(或合理的错误提示"消息列表不能为空")
    • 轨迹状态正确记录

4.5 数据隔离

TC-ISOL-01 [P0] 验证用户A不能访问用户B的技能

  • 前置条件:userA 和 userB 各自有技能数据
  • 步骤: [1] 使用 userA 的Token调用 GET /app/api/evolution/skills [2] 使用 userB 的Token调用 GET /app/api/evolution/skills [3] 使用 userA 的Token调用 GET /app/api/evolution/skills/{userB的skill_name}
  • 预期结果:
    • [1] 仅返回 userA 的技能
    • [2] 仅返回 userB 的技能
    • [3] HTTP 404,userA 无法通过猜解技能名获取 userB 的数据

TC-ISOL-02 [P0] 验证用户A不能操作用户B的技能

  • 前置条件:userA 和 userB 各自有技能
  • 步骤: [1] 使用 userA 的Token调用 PUT /app/api/evolution/skills/{userB的skill_name} 尝试编辑 [2] 使用 userA 的Token调用 DELETE /app/api/evolution/skills/{userB的skill_name} 尝试删除 [3] 使用 userA 的Token调用 POST /app/api/evolution/skills/{userB的skill_name}/freeze 尝试冻结
  • 预期结果:所有操作返回 HTTP 404(技能不存在),不修改 userB 的数据

TC-ISOL-03 [P1] 验证用户A不能查看用户B的进化事件

  • 前置条件:两个用户都有进化事件
  • 步骤: [1] 使用 userA 的Token调用 GET /app/api/evolution/events [2] 检查返回列表中是否出现 userB 的技能名
  • 预期结果:不包含任何 userB 相关的事件

TC-ISOL-04 [P1] 验证用户A不能查看用户B的驾驶舱数据

  • 前置条件:两个用户都有进化数据
  • 步骤: [1] 使用 userA 的Token分别调用4个驾驶舱API [2] 检查返回数据中是否包含 userB 的技能/事件信息
  • 预期结果:所有驾驶舱API仅返回当前用户的数据

4.6 前端—AI进化驾驶舱页面

TC-FE-01 [P0] 验证驾驶舱页面加载

  • 前置条件:用户已登录(admin账号)
  • 步骤: [1] 导航到 #/evolution [2] 观察页面加载过程 [3] 检查页面标题和统计摘要
  • 预期结果:
    • 页面正常渲染,显示"AI进化驾驶舱"标题
    • 加载过程中显示 loading spinner + "正在加载进化数据..." 文字
    • 加载完成后显示统计数字(技能总数/已成熟/萌芽中)
    • Console 无JS错误

TC-FE-02 [P0] 验证技能图谱面板(Panel A)

  • 前置条件:用户有技能数据
  • 步骤: [1] 切换到"技能图谱"面板 [2] 检查技能节点展示 [3] 鼠标悬停在技能节点上 [4] 点击某个技能节点
  • 预期结果:
    • 技能按 category 分组展示,不同状态用不同颜色标识(baby=粉色/main=绿色/staging=橙色/frozen=灰色)
    • hover 显示 tooltip(技能名+描述+版本+更新时间)
    • 点击弹出详情弹窗(名称/状态/版本/使用次数/分类/标签/操作按钮)
    • 底部有状态色标图例
    • 无技能时显示空态

TC-FE-03 [P0] 验证进化时间线面板(Panel B)

  • 前置条件:用户有进化事件数据
  • 步骤: [1] 切换到"进化时间线"面板 [2] 检查时间线布局 [3] 点击不同的筛选按钮(全部/诞生/晋升/里程碑/更新/冻结/退回) [4] 检查事件卡片内容
  • 预期结果:
    • 垂直时间线展示,左侧圆点+连接线,右侧卡片
    • 卡片显示:事件类型+技能名+描述+时间戳
    • 筛选按钮正常工作,筛选结果正确
    • 无事件时显示空态

TC-FE-04 [P0] 验证技能使用统计面板(Panel C)

  • 前置条件:用户有使用统计数据
  • 步骤: [1] 切换到"技能使用统计"面板 [2] 检查技能使用排行 [3] 检查调用趋势图 [4] 检查类别分布饼图 [5] 检查低使用技能提醒(如有)
  • 预期结果:
    • 排行条形图正常渲染,Top 3 带紫色渐变标记
    • 趋势柱状图显示 Top 4 技能
    • 饼图中心显示总调用次数,图例显示各分类占比
    • 超过30天未使用的技能显示黄色警告提醒
    • 无数据时显示"暂无数据"
    • Panel切换时按需加载统计数据

TC-FE-05 [P0] 验证AI能力画像面板(Panel D)

  • 前置条件:用户有足够的技能数据
  • 步骤: [1] 切换到"AI能力画像"面板 [2] 检查等级卡片 [3] 检查能力雷达图 [4] 检查能力标签云 [5] 检查成长建议
  • 预期结果:
    • 等级卡片显示环形进度条(level/10)+ 等级数字 + 称号 + 四项统计
    • 雷达图显示能力维度(文字创作/数据分析/代码能力/知识问答/流程自动化/创意生成等)
    • 标签云有4级尺寸和6种颜色循环
    • 成长建议列表以黄色星标开头
    • 无画像数据时显示空态

TC-FE-06 [P1] 验证面板切换

  • 前置条件:页面已加载
  • 步骤: [1] 依次点击4个面板切换按钮 [2] 来回切换 panels [3] 切换过程中检查加载状态
  • 预期结果:
    • 面板切换流畅,当前面板高亮
    • statistics 和 profile 面板首次进入时显示"加载中..."
    • 返回已加载过的面板不重新请求数据

TC-FE-07 [P1] 验证错误状态和重试

  • 前置条件:页面已加载
  • 步骤: [1] 模拟后端API返回错误(或断开网络) [2] 观察页面反应 [3] 点击"重试"按钮
  • 预期结果:
    • 页面显示错误消息
    • "重试"按钮可见且可用
    • 点击"重试"重新发起API请求

TC-FE-08 [P1] 验证未登录状态

  • 前置条件:用户未登录
  • 步骤: [1] 清除 localStorage 中的 token [2] 导航到 #/evolution
  • 预期结果:自动重定向到 #/login

TC-FE-09 [P2] 验证CSS样式完整性

  • 前置条件:页面正常加载
  • 步骤: [1] 检查所有面板的CSS类名是否存在 [2] 检查loading spinner动画是否流畅 [3] 检查响应式布局(不同分辨率下)
  • 预期结果:
    • 所有CSS类在 EvolutionDashboard.css 中有定义
    • 旋转动画正常工作
    • 各分辨率下布局正常

4.7 前端—技能管理UI(技能详情弹窗中的操作)

TC-FE-MGR-01 [P1] 验证技能详情弹窗中显示操作按钮

  • 前置条件:在技能图谱面板中点击某技能节点
  • 步骤: [1] 检查弹窗内容 [2] 确认操作按钮可见
  • 预期结果:
    • 弹窗显示技能完整信息
    • 包含编辑/删除/冻结(或解冻)等操作按钮
    • 操作按钮根据技能状态正确切换(已冻结显示"解冻",否则显示"冻结")

TC-FE-MGR-02 [P1] 验证前端调用冻结API

  • 前置条件:弹窗中显示"冻结"按钮
  • 步骤: [1] 点击"冻结"按钮 [2] 观察反馈 [3] 刷新技能列表确认状态变化
  • 预期结果:
    • API调用 /app/api/evolution/skills/{name}/freeze 成功
    • 技能状态变为"frozen"
    • 前端显示操作成功提示

TC-FE-MGR-03 [P1] 验证前端调用删除API

  • 前置条件:弹窗中显示"删除"按钮
  • 步骤: [1] 点击"删除"按钮 [2] 确认删除(如有确认弹窗) [3] 观察技能列表变化
  • 预期结果:
    • API调用 DELETE /app/api/evolution/skills/{name} 成功
    • 技能从列表中移除
    • 前端显示删除成功提示

4.8 数据库表结构验证

TC-DB-01 [P0] 验证 evolution_skills 表结构

  • 前置条件:数据库连接正常
  • 步骤: [1] 查询表结构 [2] 验证所有字段存在且类型正确
  • 预期结果:表包含字段: id(PK), user_id(FK+INDEX), skill_name, description, tags(JSON), category, state, use_count, version, skill_md_path, git_commit_sha, last_used_at, created_at, updated_at

TC-DB-02 [P0] 验证 evolution_events 表结构

  • 前置条件:数据库连接正常
  • 步骤: [1] 查询表结构
  • 预期结果:表包含字段: id(PK), user_id(FK+INDEX), skill_name, event_type, description, version_before, version_after, created_at

TC-DB-03 [P0] 验证 evolution_trajectories 表结构

  • 前置条件:数据库连接正常
  • 步骤: [1] 查询表结构
  • 预期结果:表包含字段: id(PK), user_id(FK+INDEX), conversation_id, file_path, status, atom_count, token_used, created_at, processed_at

TC-DB-04 [P0] 验证 user_evolution_config 表结构

  • 前置条件:数据库连接正常
  • 步骤: [1] 查询表结构
  • 预期结果:表包含字段: id(PK), user_id(FK+UNIQUE+INDEX), skill_dir_path, trajectory_dir_path, watcher_status, created_at, updated_at

4.9 技能状态流转验证

TC-STATE-01 [P0] 验证技能状态 baby → main

  • 前置条件:存在 state="baby" 的技能
  • 步骤: [1] 通过数据层直接更新该技能 state="main" [2] 调用 GET /app/api/evolution/skills/{skill_name} 确认状态
  • 预期结果:状态成功变更为 main

TC-STATE-02 [P0] 验证技能状态 main → staging → main

  • 前置条件:存在 state="main" 的技能
  • 步骤: [1] 更新 state="staging" [2] 查询确认 [3] 更新 state="main" [4] 查询确认
  • 预期结果:状态变更成功

TC-STATE-03 [P0] 验证技能状态 main → frozen → main

  • 前置条件:存在 state="main" 的技能
  • 步骤: [1] 调用 freeze API [2] 确认 state="frozen" [3] 调用 unfreeze API [4] 确认 state="main"
  • 预期结果:完整走通 freeze→unfreeze 循环,事件表记录完整

5. 测试用例统计

类别 P0 P1 P2 合计
技能管理 API 7 2 0 9
进化事件 API 1 2 1 4
驾驶舱面板 API 4 1 0 5
轨迹提交 API 1 2 1 4
数据隔离 2 2 0 4
前端驾驶舱页面 4 3 1 8
前端技能管理UI 0 3 0 3
数据库表结构 4 0 0 4
技能状态流转 3 0 0 3
合计 26 15 3 44

6. PRD未覆盖的代码功能模块(需产品确认)

编号 模块 代码位置 建议确认项
EXTRA-01 独立轨迹提交API api/index.ts:453 驾驶舱页面是否需要手动轨迹提交入口?
EXTRA-02 SVG内联雷达图 EvolutionDashboard.tsx:398-466 技术决策,无需产品确认

7. 测试环境要求

  • 后端服务:Python FastAPI 服务运行于 localhost:18080
  • 前端服务:React 应用通过 Nginx 代理运行于 8080 端口
  • 数据库:MySQL 8 (localhost:3306, root/pwd2026)
  • 认证方式:JWT Bearer Token,通过 POST /app/api/auth/login 获取
  • 测试用户:admin (管理员), demo_user (普通用户)

文档生成时间:2026-05-29
文档版本:v1.0
基于代码版本:evolution.py (215行) + evolution_service.py (473行) + EvolutionDashboard.tsx (631行)
PRD版本:v1.0 (2026-05-26)