Files

196 KiB
Raw Permalink Blame History

TEST_CASES.md —— 需求测试用例与追溯矩阵

版本 1.0 | 作者 T(测试 agent)| 用例唯一来源:PRD.md(81 FR);请求/响应依据:API.md;分层与轮次纪律:TEST_PLAN.md;上游事实:DISCOVERY.md 本波(M0)交付:用例清单 + 双向追溯矩阵 + 执行说明 + E2E 骨架(2 条冒烟)。全量执行从 M2 集成后开始,按 TEST_PLAN §5 轮次纪律。 覆盖判据:每个 FR 至少 1 条 TC,且每条 TC 至少映射 1 个 FR(双向完整 = 主门禁 100%)。


1. 用例清单

1.1 编号与通用约定

  • 编号:TC-<模块>-<序号>;E2E 主线场景:TC-E2E-<主线号>-<视口>(视口 M=Mobile 390×844 / T=Tablet 768×1024 / D=Desktop 1440×900)。
  • 测试层:L1 后端单元(pytest -m unit,A 组自测)|L2 后端接口(pytest -m api,respx mock 上游,T 主写)|L2s 上游 smoke(bash tests/smoke_upstreams.sh)|L3 前端单元(vitest)|L4 前端组件(vitest + @vue/test-utils)|L5 端到端(Playwright,三档视口)|L6 验收(PM 人工)。
  • 优先级:P0 = 主流程/数据正确性/安全;P1 = 重要功能与降级;P2 = 视觉细节/辅助路径。
  • 可断言性要求:预期列均为可观察结果(元素存在/计数/请求体字段/HTTP 状态/存储值),无「检查是否正确」类断言。
  • 「依赖充值」标注:上游 QA 当前 LLM 402 降级(DISCOVERY.md §6.1),凡断言涉及自然语言答案内容的用例均标注「依赖充值」——充值前只能验证结构(answer 字段存在、非空或为 fallback 证据列表、text 块已渲染),充值后验证完整断言。检索/证据/图谱/来源类断言不受 402 影响。
  • 时序说明:流水线用例中的「pipeline 块状态依次 running→done」属 UI 状态推断,若无专门组件埋点,用例从渲染的相位卡/pipeline 卡状态文本断言;帧时序由 mock sse_frames.json 保证(与 TEST_CASES 无关的 fixture 细节以 PM 的 mock 为准)。

1.2 SHELL 应用外壳(FR-SHELL-001~007)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-SHELL-001 FR-SHELL-001 桌面三栏网格精确尺寸 Desktop 1440×900;AppShell 已挂载 1. 打开应用;2. 计算 .app-shell 的 grid-template-columns 与 rows 实际值(getComputedStyle);3. 计算 .session-panel/.chat-panel/.bench-panel 宽度 columns = 260px minmax(0,1fr) 380px;rows = 48px minmax(0,1fr) 28px;三栏实际宽度 260/800/380(1440 下);body computed overflow:hidden L5-D P0
TC-SHELL-002 FR-SHELL-001 缩放下无横向滚动条 Desktop 初始 1440×900 1. 将视口改为 1280×900、再 1440×900;2. 检查 document.documentElement.scrollWidth 与 clientWidth 两档下 scrollWidth ≤ clientWidth;body 不出现横向滚动条 L5-D P1
TC-SHELL-003 FR-SHELL-002 顶栏结构:Logo/标题/徽章/主题按钮 已有一个活动会话;浅色主题 1. 打开应用;2. 断言 .top-bar 高 48px;3. 检查左 Logo 圆点与「海古纪 PlantAI」文字(gradient text);4. 检查中部会话标题与状态徽章;5. 检查右侧主题切换按钮 .top-bar offsetHeight=48;logo 文字存在且带 background-clip:text 渐变;中部标题=当前会话 title;主题按钮可点 L5-D P1
TC-SHELL-004 FR-SHELL-002 顶栏无会话时显示「就绪」 数据库无任何会话 打开应用 顶栏中部徽章文本=「就绪」(labels.js 对应键) L4 P2
TC-SHELL-005 FR-SHELL-002 顶栏长标题省略 存在 title 为 60+ 字符的会话 1. 打开该会话;2. 检查顶栏标题元素 computed style 标题 text-overflow=ellipsis;不换行(white-space:nowrap);单行渲染 L5-D P2
TC-SHELL-006 FR-SHELL-003 状态栏静态结构 AppShell 已挂载;/api/health、/api/qa/info 正常 1. 检查 .status-bar 高 28px;2. 检查左 4 个 .agent-dot-item;3. 检查右侧版本/会话数/健康标记 高=28px;agent 点数量=4;右侧文本含 PlantAI RAG v0.1 与 QA 版本号(来自 /api/qa/info 的 version,如 1.1.73-assertion-anchored) L5-D P1
TC-SHELL-007 FR-SHELL-003 问答进行中状态栏四点联动 会话空闲;mock normal(SSE 回放) 1. 发起提问;2. 在 SSE 进行中读取四个 agent 点的状态类 相位推进到 X 时第 X 个点激活(如 planning 时第 1 点 pulse);progress 全部结束后四点定格(成功态) L5-D P1
TC-SHELL-008 FR-SHELL-004 左栏折叠为 64px 图标轨 Desktop 1440×900;左栏展开 1. 点击左栏折叠按钮;2. 检查 .session-panel 宽度与图标按钮(3 个 34×34);3. 刷新页面;4. 再次检查 折叠后宽度=64px;图标按钮=3 个;过渡 300ms;刷新后仍折叠 L5-D P1
TC-SHELL-009 FR-SHELL-004 左栏折叠状态持久化 同上 1. 折叠;2. 检查 localStorage['pa-side-collapsed'] localStorage 值为折叠标记;展开后标记被清除/反转 L5-D P2
TC-SHELL-010 FR-SHELL-005 右栏折叠保留手柄条 Desktop 1440×900;右栏展开 1. 点击右栏折叠;2. 检查手柄条尺寸与可见性;3. 点击手柄展开;4. 检查 localStorage['pa-bench-collapsed'] 折叠后 .bench-panel 隐藏但手柄条 28px 可见可点;点击后恢复展开;刷新后保持折叠态 L5-D P1
TC-SHELL-011 FR-SHELL-006 Aurora 背景不遮挡交互 任意视口;AppShell 已挂载 1. 检查 aurora 层 computed style;2. 点击顶栏主题按钮、会话列表项、作曲器输入框(逐个执行且均生效) aurora 层 position:fixed、z-index:0、pointer-events:none;上述交互全部可操作 L5-D P1
TC-SHELL-012 FR-SHELL-006 浅色主题 aurora 衰减 已切浅色 检查 aurora 层或根元素的 --pa-aurora-opacity computed 值=.08(UI_SPEC §1.2 令牌值) L4 P2
TC-SHELL-013 FR-SHELL-007 首屏初始化顺序与并行请求 深色主题已存 localStorage;无会话 1. 打开应用;2. 网络面板记录启动期请求 documentElement.dataset.theme 在应用挂载前已写入(断言:无白色闪屏——深色下首帧背景即深色;实现断言:main.js 在 createApp 前写 dataset);启动期存在 GET /api/sessions、/api/health、/api/qa/info 三个请求且并行(无串行依赖) L5-D + L3 P0
TC-SHELL-014 FR-SHELL-007 首屏接口失败不阻塞渲染 mock 对 /api/health 返回 500(或 BFF 停止) 打开应用 页面仍渲染 AppShell 与欢迎空态;健康标记显示降级/离线态;无未捕获异常 L5-D(mock error 场景) P1
TC-SHELL-015 FR-SHELL-007 无会话显示欢迎空态 数据库无会话 打开应用 对话区显示欢迎空态(渐变菱形 + 标题 + 3 张建议卡) L5-D P1

1.3 THEME 主题与无障碍(FR-THEME-001~006)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-THEME-001 FR-THEME-001 深色默认主题 首次打开(无 pa-theme 存储) 1. 打开应用;2. 检查 documentElement.dataset.theme 与 --pa-canvas computed 值 theme='dark';canvas=#0A0A10(rgb(10,10,16)) L5-D P0
TC-THEME-002 FR-THEME-001 浅色主题逐组件走查 已切浅色 逐个检查顶栏、会话项、气泡、作曲器、bench 面板的计算样式 无失色:各元素背景/文字均来自浅色令牌(canvas=#F6F8FC,surface-1=#FFFFFF);无深色令牌残留(如 #0A0A10 不再出现于背景) L5-D(或 L6 人工走查) P0
TC-THEME-003 FR-THEME-002 主题切换即时生效 默认深色 1. 点击顶栏主题按钮;2. 立即检查 documentElement.dataset.theme 与 localStorage;3. 刷新后复查 dataset.theme 即时='light';localStorage['pa-theme']='light';刷新后仍为 light;再切回同理 L5-D P0
TC-THEME-004 FR-THEME-002 主题图标旋转动画 同上 切换主题时检查图标 transform 图标日/月互换且 rotate 180°(transition 400ms) L5-D P2
TC-THEME-005 FR-THEME-003 浅色 glow 衰减 已切浅色 检查根元素 --pa-glow-opacity computed 值 值=.35(深色下=1) L4 P2
TC-THEME-006 FR-THEME-004 动效降级(reduced motion) 系统「减少动态效果」开启;Playwright 以 reducedMotion:'reduce' 启动 context 1. 打开应用;2. 检查 aurora/状态点/按钮的 animation 计算样式;3. 发起一次问答 @media (prefers-reduced-motion: reduce) 生效:所有元素 animation-duration=0 或 animation 为 none;running 状态以静态符号(实心点 + 文字徽章)可辨认,无 pulse/shimmer/spin 运动 L5-D(reducedMotion context) P1
TC-THEME-007 FR-THEME-005 焦点环样式 任意视口 Tab 键聚焦顶栏主题按钮与作曲器 textarea :focus-visible 输出 2px rgba(94,106,210,.5) 焦点环(outline-offset 1px) L5-D P1
TC-THEME-008 FR-THEME-005 纯键盘完成主流程 空数据库;mock normal 只用 Tab/Enter/Esc 完成:新建会话 → 聚焦输入 → 输入问题 → ⌘/Ctrl+Enter 发送 → Tab 切换工作台 tab → Esc 关闭面板 每一步可达且生效;Tab 顺序符合视觉顺序(顶栏 → 会话列表 → 对话 → 作曲器 → 工作台) L5-D(键盘驱动) P0
TC-THEME-009 FR-THEME-006 对比度达标(深色) 深色主题 抽检 .app-shell 内 3 处文本(正文 ink、muted、subtle)的计算颜色与 canvas 背景,按 WCAG 公式计算对比度 ink/canvas ≥15:1;ink-muted/canvas ≥4.5:1;ink-subtle 仅用于非关键信息 L5-D + L3(工具函数断言,可脚本化) P1
TC-THEME-010 FR-THEME-006 对比度达标(浅色) 浅色主题 同 TC-THEME-009 步骤,浅色令牌 ink(#16182A)/canvas(#F6F8FC) ≈ 计算值 ≥ 深色同等标准;ink-muted/canvas ≥4.5:1 L5-D P1

1.4 SESSION 会话管理(FR-SESSION-001~009)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-SESSION-001 FR-SESSION-001 列表按 updated_at 倒序 数据库 ≥3 个会话,updated_at 互异(fixtures 保证) 1. GET /api/sessions;2. 前端渲染列表;3. 依次读取条目标题 条目顺序 = updated_at 从新到旧 L2(fixture 会话数据)+ L4 P0
TC-SESSION-002 FR-SESSION-001 分组「今天/昨天/更早」 ≥3 个会话,时间分别落在今天/昨天/2 天前 渲染列表 三个组标签(11px/500/字距0.6px)按序出现,组内条目归属正确;组内按时间倒序 L4(clock mock) P1
TC-SESSION-003 FR-SESSION-001 空列表引导文案 数据库无会话 渲染列表 显示引导文案(「暂无会话」类 labels 文案);不渲染列表条目 L4 P2
TC-SESSION-004 FR-SESSION-002 状态点四态区分 4 个会话分别 idle/running/done/error 渲染列表 形状可区分:idle=空心、running=空心+脉冲动画、done=实心 success 色、error=实心 error 色;running 有 animation,其余无 L4 P1
TC-SESSION-005 FR-SESSION-003 新建会话 任意初始状态 1. 点击「新建会话」按钮;2. 观察网络请求与界面 发出 POST /api/sessions;列表新增一条「新会话」;切换为活动会话;对话区显示欢迎空态;不产生空消息(GET 详情 messages 为空数组) L5-D + L2 P0
TC-SESSION-006 FR-SESSION-003 新建连点不重复 同上 快速连点新建按钮 2 次 产生 2 个独立会话(列表+2,两条 POST);均切到最后创建的一个 L5-D P1
TC-SESSION-007 FR-SESSION-004 选择会话加载历史 会话含 text/table/sources/graph 块消息 点击该会话条目 发出 GET /api/sessions/{id};加载中显示骨架屏;完成后消息按块类型渲染:markdown 文本、表格(md-table 样式)、来源、图谱块均出现 L5-D(mock 会话详情含全块) P0
TC-SESSION-008 FR-SESSION-004 切换会话中断进行中流 会话 A 流式进行中;会话 B 存在 点击会话 B 会话 A 的 SSE 连接 abort(Network 面板连接关闭);会话 A 状态置 error;切回会话 A 后其消息标注「已中断」 L5-D(mock slow/正常流) P0
TC-SESSION-009 FR-SESSION-005 搜索过滤(中文/英文/大小写) ≥3 个会话,标题含中英文混排 1. 输入中文关键词;2. 输入英文小写;3. 输入英文大写;4. 输入无匹配词;5. 清空 匹配为 title 大小写不敏感子串;无匹配显示「无匹配会话」;清空恢复全量;过滤期间无网络请求 L5-D + L4 P1
TC-SESSION-010 FR-SESSION-006 重命名提交 活动会话 1. 双击标题进入编辑;2. 输入新名;3. 回车 PATCH /api/sessions/{id} 请求体 {title:新名};列表与顶栏标题同步更新 L5-D + L2 P1
TC-SESSION-011 FR-SESSION-006 重命名取消与空标题 同上 1. 编辑中按 Esc;2. 再次编辑并清空标题后回车 Esc 放弃改动;空标题提交按钮禁用或提交被拒,不发出 PATCH 空 title L5-D P2
TC-SESSION-012 FR-SESSION-007 删除需二次确认 2 个会话 1. 右键/菜单点删除;2. 出现确认弹层时点取消 未删除(列表不变、无 DELETE 请求) L5-D P1
TC-SESSION-013 FR-SESSION-007 删除当前会话切换 2 个会话;选中其中一个 删除并确认 DELETE /api/sessions/{id} 204;当前会话切换到剩余最新一个;刷新列表后已删会话不再出现 L5-D + L2 P0
TC-SESSION-014 FR-SESSION-007 删除最后一个会话显示空态 仅 1 个会话 删除并确认 列表空;对话区显示欢迎空态 L5-D P1
TC-SESSION-015 FR-SESSION-007 级联删除消息 会话含 2 条消息;BFF 真实 删除会话后 GET /api/sessions/{id} 返回 404(NOT_FOUND 信封);SQLite 中该会话消息行一并删除(L2 断言数据库) L2 P0
TC-SESSION-016 FR-SESSION-008 首问自动标题 新建会话 1. 提问(问题 40+ 字符);2. 检查 PATCH 请求与列表标题 PATCH 请求体 title = 问题前 30 字符 + 省略号;列表标题同步变化 L5-D + L2 P0
TC-SESSION-017 FR-SESSION-008 手动改名后不覆盖 会话 meta.title_manual=true(改过名) 1. 再次提问;2. 检查是否发出 title PATCH 不发出改 title 的 PATCH;标题保持手动值 L2(会话固定数据)+ L4 P1
TC-SESSION-018 FR-SESSION-009 活动态高亮 ≥2 个会话 1. 选中会话 A;2. 检查其 computed style;3. 悬停另一项 B 对比 A 有 2px 渐变左竖条 + g-to 8% 底色 + 内描边;与悬停态(B)可区分 L5-D P2

1.5 CHAT 对话与问答(FR-CHAT-001~015)

1.5.1 基础渲染

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-CHAT-001 FR-CHAT-001 欢迎空态元素与建议卡 无消息 打开应用 显示 46px 渐变菱形(✧)+ 渐变标题「海古纪 PlantAI 知识工作台」+ 副标题 + 3 张建议卡 L5-D P1
TC-CHAT-002 FR-CHAT-001 建议卡点击即提问 无消息;mock normal 点击第 1 张建议卡 卡片文本进入作曲器并直接发送;出现用户气泡(内容=卡片文本)与助手骨架;发出 POST /api/qa/chat/stream L5-D P0
TC-CHAT-003 FR-CHAT-002 用户气泡样式与长文本换行 任意 发送 300 字无空格长文本 气泡右对齐,宽度 ≤ 父容器 70%;文本换行且不溢出(scrollWidth ≤ 气泡宽度) L5-D P2
TC-CHAT-004 FR-CHAT-003 助手消息头部与悬停竖线 已有助手消息 1. 检查头部(24px 渐变头像 ✦ + 「PlantAI 智能体」+ 时间);2. 悬停消息左缘 头部三要素齐全;左缘 2px 竖线 hover 时出现渐变 L5-D P2
TC-CHAT-005 FR-CHAT-003 多块混排顺序 消息 blocks 为 [pipeline,text,table,sources,graph](mock 会话详情) 渲染该消息 各块按 blocks 数组顺序渲染;无块丢失 L5-D P1
TC-CHAT-006 FR-CHAT-004 Markdown 表格样式 消息含表格块(mock 含 md-table 内容的 text 块) 渲染 表格带 md-table 类:thead 2px 渐变下边框;数据格 mono 字体(表头为「说明」的列保持比例字体) L5-D P1
TC-CHAT-007 FR-CHAT-004 脚本注入被消毒 向问答返回的 answer 注入 <script>window.__pwned=1</script> 与 <img src=x onerror=...>(mock fixture 或 BFF 层构造) 渲染该答案 window.__pwned 为 undefined;DOM 中不存在 script 标签;onerror 未执行;内容经 DOMPurify 后 v-html L5-D(注入 fixture)+ L3(sanitize 单测) P0
TC-CHAT-008 FR-CHAT-014 流式自动滚动到底 mock normal;消息区可滚动 发起提问 流式更新期间滚动条持续贴近底部(scrollTop+clientHeight ≥ scrollHeight−10) L5-D P1
TC-CHAT-009 FR-CHAT-014 上滚暂停自动滚动 流式进行中 向上滚动 ≥100px 不再自动贴底;出现「回到最新」按钮 L5-D P1
TC-CHAT-010 FR-CHAT-014 「回到最新」恢复滚动 上滚暂停状态 点击「回到最新」按钮 滚动回底部;恢复自动滚动;按钮消失 L5-D P1
TC-CHAT-011 FR-CHAT-015 内联引用 chip 跳转高亮 答案含引用标记(citation 编号)与对应来源 点击引用 chip bench 切换到「文献来源」tab 并滚动定位到对应条目;该条目高亮 2s 后消失;chip 编号与列表条目序号一致 L5-D P1

1.5.2 作曲器

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-CHAT-012 FR-CHAT-005 输入框高度自适应 桌面 1. 输入 1 行文本测基线(min-height 46px);2. 输入 10 行文本 基线 ≥46px;随内容增高,最大 160px 后内部滚动(scrollHeight > clientHeight) L5-D P2
TC-CHAT-013 FR-CHAT-006 三模式切换 桌面;mock normal 依次点击 问答/方案/检索 pill 激活 pill 渐变底+白字+青光;非激活态可区分;切换即生效 L5-D P0
TC-CHAT-014 FR-CHAT-006 问答模式请求体 mock 正常;问答模式 提问并抓取 POST /api/qa/chat/stream 请求体 body.use_llm=true;question 为输入文本;无 native_chain 字段(或为 modes.js 定义默认) L5-D + L3(modes.js 参数集断言) P0
TC-CHAT-015 FR-CHAT-006 方案模式请求体 方案模式 同上 body.use_llm=true;native_chain_enabled=true;native_chain_max_hops=3;native_chain_top_k=5;端点仍为 /api/qa/chat/stream L5-D + L3 P0
TC-CHAT-016 FR-CHAT-006 检索模式请求与响应 检索模式 1. 提问;2. 观察端点为 /api/qa/search;3. 等待完成;4. 检查消息块 body.use_llm=false;响应 answer 为空;消息只含 sources(+pipeline)块,无 text 答案块 L5-D + L2 P0
TC-CHAT-017 FR-CHAT-007 快捷键发送 桌面 输入文字后按 ⌘/Ctrl+Enter 发送;出现用户气泡 L5-D P0
TC-CHAT-018 FR-CHAT-007 Enter 换行 桌面 输入文字后按 Enter(非组合键) 不发送;textarea 内换行(行数+1) L5-D P1
TC-CHAT-019 FR-CHAT-007 中英文输入法快捷键 IME 输入法激活(模拟 composition 事件) composition 期间按 Enter 不触发发送(组合输入确认才触发) L3(composition 事件模拟) P1
TC-CHAT-020 FR-CHAT-007 空输入与忙碌禁用 流式进行中 1. 空输入点发送;2. 流式中点发送 按钮 disabled(opacity .45);无新请求;底部提示文案显示快捷键说明 L5-D P1
TC-CHAT-021 FR-CHAT-011 停止流式 mock slow(长流) 1. 提问;2. 流式中点击「停止」 发送按钮已变为「停止」;点击后 SSE 连接关闭(Network 断言);消息置 error 并标注「已停止」;已收到的块保留 L5-D P0
TC-CHAT-022 FR-CHAT-011 停止后无悬挂请求 BFF 真实 + 上游 QA 流式中停止;随后检查 BFF 日志 前端 abort 后 BFF 取消上游请求(BFF 侧无悬挂 upstream 连接;日志有取消记录) L2(respx 断言 abort)+ L5 P1

1.5.3 流式主流程(FR-CHAT-008)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-CHAT-023 FR-CHAT-008 主流程-用户消息立即落库 mock normal;新会话 发送问题 用户气泡立即出现(不等后端);发出 POST /api/sessions/{id}/messages,body={role:user,text};落库成功 L5-D + L2 P0
TC-CHAT-024 FR-CHAT-008 主流程-会话置 running 与骨架 同上 发送后观察 会话状态置 running(左栏状态点脉冲动画);底栏 4 agent 点复位;出现助手骨架消息(status=streaming)含 pipeline 块,五相位全 waiting L5-D P0
TC-CHAT-025 FR-CHAT-008 主流程-progress 相位推进与阶段卡 mock normal(sse_frames 12 帧) 提问后观察 每帧 progress:pipeline 对应相位 running、此前相位 done;工作台「检索过程」新增阶段卡,数量=progress 帧数(11 个 stage 帧);阶段卡 label 为中文(如「已识别实体」) L5-D P0
TC-CHAT-026 FR-CHAT-008 主流程-complete 生成三块 mock normal;提问完成 等待 complete 消息含 text 块(揭示动画结束为最终文本)、sources 块、graph 块;pipeline 五相位全部 done;消息状态 done;会话状态 done L5-D P0
TC-CHAT-027 FR-CHAT-008 主流程-答案内容(依赖充值) mock normal(mock 答案为固定文本);真实上游需充值 断言答案文本 mock 下:答案文本与 mock fixture 一致(可断言内容);真实上游:answer 为自然语言答案(依赖充值,当前 402 下为 fallback 证据列表) L5-D / L6 P1
TC-CHAT-028 FR-CHAT-008 主流程-检查点持久化节奏 BFF 真实;流 ≥3s 提问并抓取 PATCH 请求 流式中每约 3s 发出 PATCH /api/sessions/{id}/messages/{mid}(块检查点);终态再发一次终态 PATCH(done/error) L2 + L5 P0
TC-CHAT-029 FR-CHAT-008 主流程-长任务持续反馈(240s) mock slow(长流,或上游真实 ~92s) 提问并计时观察 240s 内任一时刻页面均有视觉反馈(相位卡 shimmer/已耗时计数);无静止超过 5s 的状态(5s 间隔采样断言有动画元素或文本变化) L5-D(slow 场景) P0
TC-CHAT-030 FR-CHAT-008 网络中断重试按钮 流式中断网(playwright context.setOffline(true)) 1. 流式中断网;2. 观察消息状态;3. 恢复网络;4. 观察是否自动重连;5. 点「重试」 消息置 error,文案「连接中断」;出现「重试」按钮;不自动重连(恢复网络后无新请求,需手动点击);点重试后重新发起同问题请求 L5-D(offline 模拟) P0
TC-CHAT-031 FR-CHAT-008 刷新恢复中断会话 流式进行中刷新页面 刷新后检查该会话 显示最后检查点内容;标注「已中断」;会话状态 error;不自动重试 L5-D P0
TC-CHAT-032 FR-CHAT-008 同一会话并发提问防护 流式进行中 观察发送按钮 按钮 disabled;无法发送第二个问题 L5-D P1
TC-CHAT-033 FR-CHAT-008 同会话提问可引用上文(默认开;设置中关闭后恢复独立) 同一会话已完成一次提问 第二次提问并抓取请求体 第二次请求只含当前 question,无历史消息拼接(max_rounds:1 语义);UI 有「每次提问独立检索」提示文案 L2 + L5 P1

1.5.4 流水线卡与揭示动画(FR-CHAT-009 / FR-CHAT-010)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-CHAT-034 FR-CHAT-009 五相位视觉与颜色 流式中与完成后分别观察 pipeline 卡 检查五个 p-step 的颜色令牌与状态字形 相位色:规划#C0A8DD、检索#9FBBE0、证据#9FC9A2、生成#DFA88F、完成#C08532;状态字形 ✓done/●running/◌waiting;running 相位带 11px 旋转 spinner;卡头「⚙ 检索流水线」+ 整体状态徽章(语义色) L5-D P0
TC-CHAT-035 FR-CHAT-009 相位与语义色不混用 流式中出现错误(mock error 场景) 检查 pipeline 卡 相位点颜色只随相位走(五相位色);整体成败徽章只用语义色(success/error)——两者不互换 L5-D P1
TC-CHAT-036 FR-CHAT-010 揭示动画与跳过 mock normal;答案长度已知 1. 观察 complete 后答案揭示;2. 点击「跳过」 揭示速度 30ms/字符,尾部 8×15px 青色闪烁光标 + 3px shimmer 进度线;点「跳过」后立即显示全文,reveal 元素移除 L5-D P1
TC-CHAT-037 FR-CHAT-010 长答案 8s 上限 mock 构造 >2000 字符答案 测量揭示总时长 速度自动加快,总时长 ≤8s L5-D P2

1.5.5 错误与重试(FR-CHAT-012)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-CHAT-038 FR-CHAT-012 引用校验失败重试 BFF 对 invalid_llm_citation 已自动重试一次仍失败(L2 构造) 观察响应与界面 前端展示「引用校验失败,请重试」(INVALID_CITATION 信封 message)并提供重试按钮 L2(respx 断言 BFF 重试一次)+ L5 P0
TC-CHAT-039 FR-CHAT-012 其他错误展示 message mock scenario=error 提问 消息置 error;展示 error.message 文案(上游错误中文文案);提供重试按钮;已收到块保留 L5-D(error 场景) P0
TC-CHAT-040 FR-CHAT-012 重试同位置替换 错误后 点击重试 用相同问题与模式重新发起;不新增用户消息(消息列表长度不变,同一条助手消息位置更新) L5-D P0
TC-CHAT-041 FR-CHAT-012 SSE error/timeout 事件 mock 构造 event:error 与 event:timeout 帧 提问 error 帧→展示 error.message;timeout 帧→文案「检索超时」;两者均置消息 error 并保留已收到块 L5-D(定制 mock 流) P1

1.5.6 持久化与恢复(FR-CHAT-013)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-CHAT-042 FR-CHAT-013 块联合完整落库 BFF 真实;完成一次问答 检查 SQLite 该消息行 blocks 含 text/table/sources/graph/pipeline 等全部完成块;无 stream 块(瞬态已转 text);raw 字段保存完整归一化响应 L2 P0
TC-CHAT-043 FR-CHAT-013 刷新后恢复全部块 完成一次含表格/来源/图谱的问答 刷新页面并打开该会话 GET /api/sessions/{id} 后全部块正确重渲染(表格、来源、图谱可见);无数据丢失 L5-D P0

1.6 RETRIEVAL 检索过程(FR-RETRIEVAL-001~006)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-RETRIEVAL-001 FR-RETRIEVAL-001 阶段卡与 progress 帧一一对应 mock normal;完成一次问答 统计工作台 Tab1 卡片数与 Network 中 progress 帧数 卡片数 = progress 帧数(sse_frames 11 个 stage 帧 → 11 张卡);每卡含相位色图标 + 阶段中文名 + 状态点 + 耗时 mono L5-D P0
TC-RETRIEVAL-002 FR-RETRIEVAL-001 阶段卡展开体参数块 已有一张阶段卡 展开卡头 展开体显示 details 参数块(mono)+ 摘要行(如 entities 列表) L5-D P2
TC-RETRIEVAL-003 FR-RETRIEVAL-002 相位筛选 一次问答后存在 4 个相位卡片 依次点击 全部/规划/检索/证据/生成 chip 激活 chip 实心 #5E6AD2 底 + 白字;筛选后仅显示对应相位卡片(计数=对应相位帧数) L5-D P1
TC-RETRIEVAL-004 FR-RETRIEVAL-003 展开折叠与默认态 流式中(running 卡)与完成后各观察一次 1. 流式中看卡默认态;2. 完成后看默认态;3. 点击头部 运行中的卡默认展开;完成后自动折叠;点击切换展开/折叠;chevron 旋转 90°;展开体 fade-slide 200ms;各卡状态互相独立 L5-D P1
TC-RETRIEVAL-005 FR-RETRIEVAL-004 运行中效果 流式中 检查 running 卡 头部 shimmer 扫光(1.8s 循环)+ 状态点脉冲;完成后动效停止(animation none/移除) L5-D P2
TC-RETRIEVAL-006 FR-RETRIEVAL-005 检索计划展示与无 plan 不显示 mock normal(fixture 含 retrieval_plan)与无 plan 的响应各一次 检查列表顶部 含 retrieval_plan 时顶部只读信息块展示 plan;无 plan 时该区域不渲染(无空框);另展示 /api/qa/info 的 12 段 pipeline 静态说明 L5-D P1
TC-RETRIEVAL-007 FR-RETRIEVAL-006 空态 未提问 打开工作台 Tab1 显示「发起提问后,这里会实时展示检索过程」;无假卡片 L5-D P2

1.7 SOURCE 文献来源(FR-SOURCE-001~006)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-SOURCE-001 FR-SOURCE-001 来源列表条目数与元素 mock normal 完成问答(source_count=4) 打开工作台 Tab2 条目数 = 4(与响应 source_count 一致);每条:序号 + 标题(超长省略)+ mono 元信息行(PMID:xxx / DOI:xxx / 分数)+ 证据片段(默认 2 行截断) L5-D P0
TC-SOURCE-002 FR-SOURCE-001 证据片段展开 有一条来源 点击片段 展开显示完整 snippet;再点收起 L5-D P2
TC-SOURCE-003 FR-SOURCE-002 字段缺失不渲染占位 mock 构造 source 缺 pmid/pmcid/doi/section 的组合 渲染列表 缺失字段位置不显示占位符;页面文本中不含 undefined、null 字样 L5-D P0
TC-SOURCE-004 FR-SOURCE-003 外链优先级 4 个 source:a 有 url;b 无 url 有 doi;c 无 url/doi 有 pmid;d 无 url/doi/pmid 有 pmcid;e 全无 检查各条目链接 a 链=url;b=https://doi.org/{doi};c=PubMed PMID 链接;d=PMC 链接;e 无链接图标;点击新标签打开且带 rel="noopener" L5-D P1
TC-SOURCE-005 FR-SOURCE-004 证据链分组与展开 响应 chains 含 ≥2 个 chain_id 打开证据链区 按 chain_id 分组显示;组徽章显示跳数;展开后逐跳列表 源实体 —[关系]→ 目标实体,每跳附 paper_id/PMID;顺序与 hops 数组一致 L5-D P1
TC-SOURCE-006 FR-SOURCE-005 会话级聚合 同一会话完成 2 次问答(相同 paper 出现多次) 切到「本会话全部」 发出 GET /api/sessions/{id}/sources;按 paper_id 去重;每条 count = 该 paper 累计出现次数;去重后条数正确 L5-D + L2 P1
TC-SOURCE-007 FR-SOURCE-006 空态 mock scenario=empty 完成问答(source_count=0) 打开工作台 Tab2 显示「本次检索未命中文献」;无空列表框(无 .ft-item 元素) L5-D(empty 场景) P1

1.8 EXTRACT 提取任务(FR-EXTRACT-001~006)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-EXTRACT-001 FR-EXTRACT-001 任务列表与派生百分比 mock 任务列表(含 queued/running/completed/failed 各一) 打开工作台 Tab3 发出 GET /api/extraction/jobs;列表与响应一致;百分比派生正确:queued=5、running(35/75 按 stage)、completed=100、failed 无进度条且显示错误态;100% 为纯 success 色且无 sweep 扫光 L5-D + L2(BFF 派生断言) P0
TC-EXTRACT-002 FR-EXTRACT-002 任务详情 已有一个任务 点击展开 GET /api/extraction/jobs/{id};显示 status、message(中文进度)、stats 统计字段(stage/species/figure_table 计数) L5-D P1
TC-EXTRACT-003 FR-EXTRACT-002 未完成任务 plan 不显示 一个 running 任务 展开详情 plan 为 null 时不显示 plan 区块且无报错 L5-D P1
TC-EXTRACT-004 FR-EXTRACT-003 运行日志 mock 正常 打开运行日志 GET /api/extraction/run-log;mono 等宽展示;长日志在最大高度内滚动(scrollHeight > clientHeight 时出现内部滚动);自动贴底 L5-D P2
TC-EXTRACT-005 FR-EXTRACT-004 上传 PDF 成功 构造 ≤50MB PDF;mock 上传成功 附件按钮 → 选 PDF → 上传 POST /api/extraction/upload(multipart,Content-Type 含 multipart/form-data);显示上传进度;成功返回 job_id 并刷新列表(出现新任务) L5-D P1
TC-EXTRACT-006 FR-EXTRACT-004 非 PDF 被拒 一个 .txt 文件 尝试上传 被拒绝(前端拦截或 422);不发出上传请求(前端拦截时)或返回 VALIDATION 信封 L5-D + L2 P1
TC-EXTRACT-007 FR-EXTRACT-004 超 50MB 被拒 一个 >50MB PDF 尝试上传 被拒绝;提示超出大小限制;不发出上传请求 L5-D P2
TC-EXTRACT-008 FR-EXTRACT-004 上游失败错误文案 mock 返回 502(MinerU 不可用) 上传 展示上游 message 的明确错误文案(非堆栈);任务列表/详情为失败态 L5-D P1
TC-EXTRACT-009 FR-EXTRACT-005 轮询节奏 列表含一个 running 任务 观察 12s 内网络请求 每 5s 轮询一次 GET /api/extraction/jobs;全部终态后轮询停止(再观察 12s 无新请求) L5-D P1
TC-EXTRACT-010 FR-EXTRACT-005 切 tab 暂停轮询 running 任务存在;切换到其他 tab 观察网络 离开 Tab3 期间无 jobs 轮询请求;切回恢复 L5-D P2
TC-EXTRACT-011 FR-EXTRACT-006 离线降级 mock 对 extraction 返回 503(degraded) 打开 Tab3 显示离线提示与重试按钮;其他 tab(检索/来源/图谱)不受影响可正常使用 L5-D(degraded 场景) P1

1.9 KG 知识图谱(FR-KG-001~008)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-KG-001 FR-KG-001 答案图谱渲染(SVG 力导向) mock normal 完成问答(graph 块 6 节点 4 边) 打开工作台 Tab4 渲染手写 SVG 力导向图:节点圆点+标签;边为渐变线(#5E6AD2→#00D4FF)带关系名;节点与答案引用实体一致(与 graph 块节点 label 一致) L5-D P0
TC-KG-002 FR-KG-001 节点 >50 降级列表 mock 构造 graph 块 >50 节点 打开 Tab4 自动降级为列表视图并提示;不渲染 SVG 画布 L5-D P1
TC-KG-003 FR-KG-002 节点着色与图例 graph 块含 ≥2 种实体 type 检查节点颜色与图例 按 type 着色(品牌+辅助紫+五相位色板);底部图例存在且与节点颜色一一对应;同 type 在会话内颜色稳定(两次问答同一 type 颜色相同) L5-D P2
TC-KG-004 FR-KG-003 节点详情面板 graph 块有节点;Neo4j 不可用(mock 无 kg 或 503) 点击一个节点 侧滑详情面板显示实体属性(消息内已有属性);Neo4j 不可用时仍显示(不报错、不空白) L5-D P1
TC-KG-005 FR-KG-003 Neo4j 可用时拉全量属性 Neo4j 可用(真实上游或 mock) 点击节点 面板内额外数据来自 GET /api/kg/entities/{name}(发出该请求并渲染返回 properties) L5-D P2
TC-KG-006 FR-KG-004 实体搜索(精确/前缀) mock normal 1. 输入「OsSPL」;2. 回车 GET /api/kg/entities?q=OsSPL;结果显示(精确或前缀匹配项);响应 <1s(断言用时) L5-D + L2 P0
TC-KG-007 FR-KG-004 实体搜索选中渲染邻域 上一步结果 点击第一个结果 渲染该实体邻域(调 neighborhood 接口或 mock 数据);画布更新为该实体为中心 L5-D P1
TC-KG-008 FR-KG-005 邻域深度切换 mock normal 1. 深度选 1(默认)观察请求;2. 深度选 2 观察 请求 depth 参数分别为 1/2;渲染节点数随之变化;深度 2 时显示「较慢」提示文案(两跳实测约 13s) L5-D + L2 P1
TC-KG-009 FR-KG-005 节点上限 200 截断 mock 构造 >200 节点邻域 深度 2 展开 渲染节点数 ≤200;每跳按 paper_count/support_count 降序截断(L2 断言 BFF 截断逻辑);超限有提示不卡死 L2 + L5 P1
TC-KG-010 FR-KG-006 缩放平移(桌面) 画布有图 滚轮缩放;拖拽平移;双击 缩放范围 0.3×–3×;平移生效;双击复位到初始视图 L5-D P1
TC-KG-011 FR-KG-006 触摸缩放平移(移动端) Mobile 视口;画布有图 双指捏合;单指拖拽 双指缩放与单指拖拽均可用且流畅(缩放比例改变;拖拽后画布位移) L5-M(touch 模拟) P1
TC-KG-012 FR-KG-007 Neo4j 不可用降级 mock kg 接口返回 503(或 BFF 断开 Neo4j) 打开 Tab4 搜索框与邻域功能禁用并提示离线;答案图谱照常渲染;tab 不白屏 L5-D P1
TC-KG-013 FR-KG-008 空态 本次回答无 graph 数据(mock empty) 打开 Tab4 提示「本次检索未产生图谱关系」+ 引导使用实体搜索;不显示空画布 L5-D(empty 场景) P2

1.10 RESP 响应式(FR-RESP-001~013)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-RESP-001 FR-RESP-001 Desktop ≥1280 完整三栏 Desktop 1440×900 检查布局 三栏 260/1fr/380 可见(同 TC-SHELL-001) L5-D P0
TC-RESP-002 FR-RESP-002 Laptop 1024–1279 左栏自动折叠 视口 1200×900 检查布局 三栏保留;左栏宽=64px(自动折叠,无需点击);右栏=340px L5-D(1200×900) P1
TC-RESP-003 FR-RESP-003 Tablet 左抽屉 Tablet 768×1024 1. 检查布局(对话单栏铺满);2. 点顶栏汉堡 左栏默认隐藏;点汉堡后左抽屉 260px 滑入 + scrim 遮罩;顶栏有汉堡按钮;右栏为右抽屉(顶栏工作台按钮带来源数角标);点 scrim 或 Esc 关闭;动效 ease-out 300ms L5-T P0
TC-RESP-004 FR-RESP-004 Mobile 单栏与工作台覆盖层 Mobile 390×844 1. 检查布局;2. 点顶栏工作台按钮 顶栏=汉堡+标题+工作台按钮;对话铺满;作曲器吸底;工作台打开为全屏覆盖层+顶部 tab 条;底部状态栏隐藏(不可见);四个 agent 点合并为顶栏一枚聚合状态点;点 scrim 或 Esc 关闭 L5-M P0
TC-RESP-005 FR-RESP-005 viewport 与安全区 Mobile(iPhone 视口) 检查 meta 与 computed 值 <meta viewport> 含 viewport-fit=cover;作曲器 padding-bottom = env(safe-area-inset-bottom);顶栏 padding-top = env(safe-area-inset-top)(computed 值>0) L5-M P1
TC-RESP-006 FR-RESP-006 iOS 输入放大规避 Mobile 视口(<768px) 检查 textarea computed font-size font-size=16px;未使用 maximum-scale=1(meta 内容断言) L5-M P0
TC-RESP-007 FR-RESP-007 悬停态触摸等价 Mobile 视口;有来源条目与助手消息 检查来源外链图标、助手消息左缘线、会话条目样式 外链图标常驻可见;助手消息左缘线常驻;会话条目无 hover 底色依赖(点击反馈存在);@media (hover:hover) 包裹 hover 样式(L3 样式断言) L5-M P1
TC-RESP-008 FR-RESP-008 触控目标 44px Mobile 视口 检查会话条目、bench tab、模式 pill、图标按钮高度 min-height ≥44px(computed) L5-M P1
TC-RESP-009 FR-RESP-009 100dvh 视口高度 Mobile 视口 检查应用根容器高度 使用 100dvh(computed 解析为实际视口高度);存在 100vh 回退声明(L3 样式断言) L5-M P2
TC-RESP-010 FR-RESP-010 虚拟键盘适配 Mobile 视口;visualViewport 可模拟 聚焦 textarea(模拟键盘弹出压缩 visualViewport) 消息区高度压缩并保持贴底;作曲器始终可见(boundingBox 在视口内) L5-M P1
TC-RESP-011 FR-RESP-011 表格横向滚动 Mobile 视口;消息含宽表格 检查 md-table 容器 表格外层有横向滚动容器;容器 scrollWidth > clientWidth 时可横滑查看完整内容;字体字号未被压缩(computed font-size ≥ 桌面值) L5-M P1
TC-RESP-012 FR-RESP-012 移动端性能降级 Mobile 视口 检查 aurora 与图谱上限 aurora 模糊半径降低或 --pa-aurora-opacity:0;图谱节点数上限=30(构造 >30 节点 graph 块时渲染 ≤30 或降级列表) L5-M P2
TC-RESP-013 FR-RESP-013 手势(可选 N/A) Mobile 视口 左缘右滑 若实现:右滑开会话抽屉、右滑关工作台覆盖层可用;未实现不算缺陷,本条 N/A 记录 L5-M(标记 N/A) P2

1.11 HEALTH 健康与降级(FR-HEALTH-001~005)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-HEALTH-001 FR-HEALTH-001 健康轮询 30s 打开应用 观察 65s 内 GET /api/health 请求 挂载后立即一次;此后每 30s 一次(65s 内共 3 次) L5-D P1
TC-HEALTH-002 FR-HEALTH-001 轮询失败不弹窗 mock /api/health 持续 500 打开应用 无错误弹窗/未捕获异常;状态栏健康标记显示降级态 L5-D P1
TC-HEALTH-003 FR-HEALTH-001 上游恢复 30s 内解禁 mock 先 503 后恢复正常(场景切换) 1. 观察禁用态;2. 切回正常场景;3. ≤30s 内观察 上游恢复后 ≤30s(一个轮询周期内)对应功能自动解禁,无需手动刷新 L5-D P1
TC-HEALTH-004 FR-HEALTH-002 QA 不可用降级 mock scenario=degraded(/api/qa/* 503) 打开应用 作曲器禁用并显示「知识问答服务当前不可用」;历史会话仍可浏览(点击会话可看历史消息);无错误弹窗 L5-D(degraded 场景) P0
TC-HEALTH-005 FR-HEALTH-002 QA 降级信封语义 mock degraded 检查响应结构 HTTP 503 + {"ok":false,"error":{"code":"UPSTREAM_DOWN","message":"…","degraded":true}};前端按 degraded 处理(横幅/离线态)而非错误弹窗 L2 + L5 P0
TC-HEALTH-006 FR-HEALTH-003 Neo4j 不可用降级 mock kg 503 打开 Tab4 搜索/邻域禁用并提示离线;答案图谱照常渲染(同 TC-KG-012) L5-D P1
TC-HEALTH-007 FR-HEALTH-004 抽取不可用降级 mock extraction 503 打开 Tab3 仅 Tab3 降级(离线提示+重试按钮);其他 tab 正常(同 TC-EXTRACT-011) L5-D P1
TC-HEALTH-008 FR-HEALTH-005 网络中断提示与不自动重连 流式中断网(同 TC-CHAT-030) 1. 断网;2. 恢复网络观察 提示「连接中断」+ 重试按钮;不自动重连;无重复 LLM 调用(Network 无自动新请求) L5-D P0

1.12 非功能要求(PRD §14)对照用例

编号 对应要求 标题 前置条件 步骤 预期结果 测试层 优先级
TC-NFR-001 首屏可交互 桌面;mock normal 打开应用并计时(performance.timing / Playwright 计时) 桌面 <2s 可交互(首屏渲染+会话列表加载完成);手机 <3s L5-D / L5-M P1
TC-NFR-002 长任务反馈 mock slow(长流) 提问并采样 240s 内无静止 >5s 状态(同 TC-CHAT-029) L5-D P0
TC-NFR-003 Neo4j 凭据不下发 打开应用并抓取全部网络响应与 JS bundle 文本 浏览器侧任何响应/源码中不含 Neo4j 密码(<neo4j-password-in-.env> 等)与 bolt:// URI L5-D + L3(bundle 扫描) P0
TC-NFR-004 零外网请求 打开应用并抓取全部网络请求 所有请求 host 均为 127.0.0.1(或部署域);无 fonts.googleapis.com / CDN 域名请求 L5-D P1
TC-NFR-005 浏览器兼容基线 Chrome 110+/Firefox 110+/Safari 16+ Playwright 三浏览器各跑冒烟 2 条 冒烟通过(页面加载 + AppShell 存在) L5(chromium 常驻;firefox/webkit 每轮按需) P1

1.13 E2E 主线场景(TEST_PLAN §6 九条主线 × 三档视口)

编号规则 TC-E2E-<主线号>-<视口>,M=Mobile(390×844)|T=Tablet(768×1024)|D=Desktop(1440×900)。每条为一条用例,步骤与预期为该视口下的完整流程断言。全量用例在后续轮次落为 spec 文件;本波仅实现 TC-E2E-SMOKE-01/02(§1.14)。

编号 主线 视口 步骤 预期结果 优先级
TC-E2E-01-M 1 主流程 M 新建会话 → 问答模式提问 → 观察流水线五相位推进 → 等待答案揭示(含表格)→ 来源 tab 有数据 → 图谱 tab 渲染 → 刷新后历史恢复 五相位按序推进(waiting→running→done);答案揭示并含 md-table;Tab2 条目数=source_count;Tab4 SVG 图渲染;刷新后该会话消息完整恢复 P0
TC-E2E-01-T 1 主流程 T 同 TC-E2E-01-M(左栏经抽屉进入会话) 同 TC-E2E-01-M;另断言左/右抽屉开合正常 P0
TC-E2E-01-D 1 主流程 D 同 TC-E2E-01-M 同 TC-E2E-01-M P0
TC-E2E-02-M 2 检索模式 M 检索模式提问 → 等待完成 → 检查消息块 无 text 答案块;仅来源数据;请求体 use_llm=false 且端点 /api/qa/search P0
TC-E2E-02-T 2 检索模式 T 同 TC-E2E-02-M 同 TC-E2E-02-M P0
TC-E2E-02-D 2 检索模式 D 同 TC-E2E-02-M 同 TC-E2E-02-M P0
TC-E2E-03-M 3 错误与重试 M scenario=error 下提问 → 观察错误;scenario=degraded 下观察作曲器 error:错误文案展示+重试按钮可用(点击后重新发起);degraded:作曲器禁用+「知识问答服务当前不可用」提示 P0
TC-E2E-03-T 3 错误与重试 T 同 TC-E2E-03-M 同 TC-E2E-03-M P0
TC-E2E-03-D 3 错误与重试 D 同 TC-E2E-03-M 同 TC-E2E-03-M P0
TC-E2E-04-M 4 会话管理 M 新建/切换/重命名/删除/搜索过滤/观察分组 每步按 SESSION 用例断言:新建+1、切换加载历史、重命名同步顶栏、删除需确认且列表-1、搜索实时过滤、分组标签正确 P0
TC-E2E-04-T 4 会话管理 T 同 TC-E2E-04-M 同 TC-E2E-04-M P0
TC-E2E-04-D 4 会话管理 D 同 TC-E2E-04-M 同 TC-E2E-04-M P0
TC-E2E-05-M 5 中断 M 流式中途切会话 → 切回原会话 原会话置 error 且标注「已中断」;已收到块保留;无悬挂流 P0
TC-E2E-05-T 5 中断 T 同 TC-E2E-05-M 同 TC-E2E-05-M P0
TC-E2E-05-D 5 中断 D 同 TC-E2E-05-M 同 TC-E2E-05-M P0
TC-E2E-06-M 6 主题 M 深浅切换 → 刷新 切换即时生效(dataset.theme 与 localStorage);刷新后保持 P0
TC-E2E-06-T 6 主题 T 同 TC-E2E-06-M 同 TC-E2E-06-M P0
TC-E2E-06-D 6 主题 D 同 TC-E2E-06-M 同 TC-E2E-06-M P0
TC-E2E-07-M 7 图谱 M 实体搜索 → 选中渲染邻域 → 节点详情 → 双指缩放 + 单指拖拽 搜索结果渲染;邻域画布更新;详情面板打开;触摸缩放/拖拽生效 P1
TC-E2E-07-T 7 图谱 T 同 TC-E2E-07-M(触摸为单指拖拽+双指捏合) 同 TC-E2E-07-M P1
TC-E2E-07-D 7 图谱 D 实体搜索 → 邻域 → 详情 → 滚轮缩放/拖拽平移/双击复位 同 TC-E2E-07-M(桌面交互) P1
TC-E2E-08-M 8 抽取 M 任务列表 → 详情展开 → 运行日志;mock 下上传 PDF 列表渲染+百分比正确;详情字段齐全;日志滚动;上传成功返回 job_id 并刷新列表 P1
TC-E2E-08-T 8 抽取 T 同 TC-E2E-08-M 同 TC-E2E-08-M P1
TC-E2E-08-D 8 抽取 D 同 TC-E2E-08-M 同 TC-E2E-08-M P1
TC-E2E-09-M 9 响应式专项 M 布局断言(FR-RESP-004 全项)+ 移动端专项:安全区、16px 输入、44px 触控、表格横滚、键盘适配 顶栏=汉堡+标题+工作台按钮;作曲器吸底;工作台全屏覆盖层+tab 条;底栏隐藏;聚合状态点存在;safe-area padding 生效;textarea 16px;触控目标 ≥44px;宽表格横滚;聚焦时作曲器可见 P0
TC-E2E-09-T 9 响应式专项 T 布局断言(FR-RESP-003 全项:抽屉/scrim/角标) 单栏铺满;左右抽屉开合+scrim+Esc 关闭;汉堡与工作台按钮带来源数角标 P0
TC-E2E-09-D 9 响应式专项 D 布局断言(FR-RESP-001/002:1280 边界与 1200 折叠) 1440 完整三栏;1200 左栏自动折叠 64px 右栏 340px P0

1.14 E2E 冒烟骨架用例(本波已实现)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-E2E-SMOKE-01 FR-SHELL-007(页面加载) 页面加载冒烟 dev server 5180 可用;三档视口各跑一次 打开 / title 含「海古纪 PlantAI」;#app 可见且内容非空 L5-M/T/D P0
TC-E2E-SMOKE-02 FR-SHELL-001/003/FR-RESP-004(壳层;移动端底栏隐藏断言) AppShell 存在冒烟 同上 打开 / 存在 .app-shell 时:shell/top-bar 可见且无占位符;status-bar 在 ≥768px 视口可见、移动端隐藏(FR-RESP-004);M0 占位期(无 .app-shell)回退:.app-shell-placeholder 可见 L5-M/T/D P0

2. 追溯矩阵

2.1 统计总览

项 值
FR 总数 81
已覆盖 FR 81
未覆盖清单 (空)
TC 总数 179
孤儿 TC(无 FR 映射) 0
主门禁(FR→TC 且 TC→FR 双向完整) 81/81 = 100%

2.2 FR→TC 矩阵(每个 FR 列出其全部 TC)

FR 用例
FR-SHELL-001 TC-SHELL-001, TC-SHELL-002, TC-E2E-SMOKE-02, TC-E2E-09-D
FR-SHELL-002 TC-SHELL-003, TC-SHELL-004, TC-SHELL-005
FR-SHELL-003 TC-SHELL-006, TC-SHELL-007, TC-E2E-SMOKE-02
FR-SHELL-004 TC-SHELL-008, TC-SHELL-009
FR-SHELL-005 TC-SHELL-010
FR-SHELL-006 TC-SHELL-011, TC-SHELL-012
FR-SHELL-007 TC-SHELL-013, TC-SHELL-014, TC-SHELL-015, TC-E2E-SMOKE-01
FR-THEME-001 TC-THEME-001, TC-THEME-002
FR-THEME-002 TC-THEME-003, TC-THEME-004, TC-E2E-06-M, TC-E2E-06-T, TC-E2E-06-D
FR-THEME-003 TC-THEME-005
FR-THEME-004 TC-THEME-006
FR-THEME-005 TC-THEME-007, TC-THEME-008
FR-THEME-006 TC-THEME-009, TC-THEME-010
FR-SESSION-001 TC-SESSION-001, TC-SESSION-002, TC-SESSION-003, TC-E2E-04-M, TC-E2E-04-T, TC-E2E-04-D
FR-SESSION-002 TC-SESSION-004
FR-SESSION-003 TC-SESSION-005, TC-SESSION-006, TC-E2E-04-M, TC-E2E-04-T, TC-E2E-04-D
FR-SESSION-004 TC-SESSION-007, TC-SESSION-008, TC-E2E-04-M, TC-E2E-04-T, TC-E2E-04-D
FR-SESSION-005 TC-SESSION-009, TC-E2E-04-M, TC-E2E-04-T, TC-E2E-04-D
FR-SESSION-006 TC-SESSION-010, TC-SESSION-011, TC-E2E-04-M, TC-E2E-04-T, TC-E2E-04-D
FR-SESSION-007 TC-SESSION-012, TC-SESSION-013, TC-SESSION-014, TC-SESSION-015, TC-E2E-04-M, TC-E2E-04-T, TC-E2E-04-D
FR-SESSION-008 TC-SESSION-016, TC-SESSION-017
FR-SESSION-009 TC-SESSION-018
FR-CHAT-001 TC-CHAT-001, TC-CHAT-002
FR-CHAT-002 TC-CHAT-003
FR-CHAT-003 TC-CHAT-004, TC-CHAT-005
FR-CHAT-004 TC-CHAT-006, TC-CHAT-007
FR-CHAT-005 TC-CHAT-012
FR-CHAT-006 TC-CHAT-013, TC-CHAT-014, TC-CHAT-015, TC-CHAT-016, TC-E2E-02-M, TC-E2E-02-T, TC-E2E-02-D
FR-CHAT-007 TC-CHAT-017, TC-CHAT-018, TC-CHAT-019, TC-CHAT-020
FR-CHAT-008 TC-CHAT-023, TC-CHAT-024, TC-CHAT-025, TC-CHAT-026, TC-CHAT-027, TC-CHAT-028, TC-CHAT-029, TC-CHAT-030, TC-CHAT-031, TC-CHAT-032, TC-CHAT-033, TC-E2E-01-M, TC-E2E-01-T, TC-E2E-01-D, TC-E2E-05-M, TC-E2E-05-T, TC-E2E-05-D
FR-CHAT-009 TC-CHAT-034, TC-CHAT-035
FR-CHAT-010 TC-CHAT-036, TC-CHAT-037
FR-CHAT-011 TC-CHAT-021, TC-CHAT-022, TC-E2E-05-M, TC-E2E-05-T, TC-E2E-05-D
FR-CHAT-012 TC-CHAT-038, TC-CHAT-039, TC-CHAT-040, TC-CHAT-041, TC-E2E-03-M, TC-E2E-03-T, TC-E2E-03-D
FR-CHAT-013 TC-CHAT-042, TC-CHAT-043, TC-E2E-01-M, TC-E2E-01-T, TC-E2E-01-D
FR-CHAT-014 TC-CHAT-008, TC-CHAT-009, TC-CHAT-010
FR-CHAT-015 TC-CHAT-011
FR-RETRIEVAL-001 TC-RETRIEVAL-001, TC-RETRIEVAL-002
FR-RETRIEVAL-002 TC-RETRIEVAL-003
FR-RETRIEVAL-003 TC-RETRIEVAL-004
FR-RETRIEVAL-004 TC-RETRIEVAL-005
FR-RETRIEVAL-005 TC-RETRIEVAL-006
FR-RETRIEVAL-006 TC-RETRIEVAL-007
FR-SOURCE-001 TC-SOURCE-001, TC-SOURCE-002
FR-SOURCE-002 TC-SOURCE-003
FR-SOURCE-003 TC-SOURCE-004
FR-SOURCE-004 TC-SOURCE-005
FR-SOURCE-005 TC-SOURCE-006
FR-SOURCE-006 TC-SOURCE-007
FR-EXTRACT-001 TC-EXTRACT-001, TC-E2E-08-M, TC-E2E-08-T, TC-E2E-08-D
FR-EXTRACT-002 TC-EXTRACT-002, TC-EXTRACT-003, TC-E2E-08-M, TC-E2E-08-T, TC-E2E-08-D
FR-EXTRACT-003 TC-EXTRACT-004, TC-E2E-08-M, TC-E2E-08-T, TC-E2E-08-D
FR-EXTRACT-004 TC-EXTRACT-005, TC-EXTRACT-006, TC-EXTRACT-007, TC-EXTRACT-008, TC-E2E-08-M, TC-E2E-08-T, TC-E2E-08-D
FR-EXTRACT-005 TC-EXTRACT-009, TC-EXTRACT-010
FR-EXTRACT-006 TC-EXTRACT-011
FR-KG-001 TC-KG-001, TC-KG-002
FR-KG-002 TC-KG-003
FR-KG-003 TC-KG-004, TC-KG-005
FR-KG-004 TC-KG-006, TC-KG-007, TC-E2E-07-M, TC-E2E-07-T, TC-E2E-07-D
FR-KG-005 TC-KG-008, TC-KG-009, TC-E2E-07-M, TC-E2E-07-T, TC-E2E-07-D
FR-KG-006 TC-KG-010, TC-KG-011, TC-E2E-07-M, TC-E2E-07-T, TC-E2E-07-D
FR-KG-007 TC-KG-012
FR-KG-008 TC-KG-013
FR-RESP-001 TC-RESP-001, TC-E2E-09-D
FR-RESP-002 TC-RESP-002, TC-E2E-09-D
FR-RESP-003 TC-RESP-003, TC-E2E-09-T
FR-RESP-004 TC-RESP-004, TC-E2E-09-M, TC-E2E-SMOKE-02
FR-RESP-005 TC-RESP-005, TC-E2E-09-M
FR-RESP-006 TC-RESP-006, TC-E2E-09-M
FR-RESP-007 TC-RESP-007, TC-E2E-09-M
FR-RESP-008 TC-RESP-008, TC-E2E-09-M
FR-RESP-009 TC-RESP-009, TC-E2E-09-M
FR-RESP-010 TC-RESP-010, TC-E2E-09-M
FR-RESP-011 TC-RESP-011, TC-E2E-09-M
FR-RESP-012 TC-RESP-012, TC-E2E-09-M
FR-RESP-013 TC-RESP-013(N/A 可选)
FR-HEALTH-001 TC-HEALTH-001, TC-HEALTH-002, TC-HEALTH-003
FR-HEALTH-002 TC-HEALTH-004, TC-HEALTH-005, TC-E2E-03-M, TC-E2E-03-T, TC-E2E-03-D
FR-HEALTH-003 TC-HEALTH-006, TC-KG-012
FR-HEALTH-004 TC-HEALTH-007, TC-EXTRACT-011
FR-HEALTH-005 TC-HEALTH-008, TC-CHAT-030

非功能要求(PRD §14,非 FR 编号)由 TC-NFR-001~005 覆盖:首屏性能(TC-NFR-001)、长任务反馈(TC-NFR-002)、凭据安全(TC-NFR-003)、零外网(TC-NFR-004)、浏览器兼容(TC-NFR-005)。

2.3 TC→FR 矩阵(每条 TC 列出其全部 FR,证明无孤儿)

TC FR
TC-SHELL-001 FR-SHELL-001
TC-SHELL-002 FR-SHELL-001
TC-SHELL-003 FR-SHELL-002
TC-SHELL-004 FR-SHELL-002
TC-SHELL-005 FR-SHELL-002
TC-SHELL-006 FR-SHELL-003
TC-SHELL-007 FR-SHELL-003
TC-SHELL-008 FR-SHELL-004
TC-SHELL-009 FR-SHELL-004
TC-SHELL-010 FR-SHELL-005
TC-SHELL-011 FR-SHELL-006
TC-SHELL-012 FR-SHELL-006
TC-SHELL-013 FR-SHELL-007
TC-SHELL-014 FR-SHELL-007
TC-SHELL-015 FR-SHELL-007
TC-THEME-001 FR-THEME-001
TC-THEME-002 FR-THEME-001
TC-THEME-003 FR-THEME-002
TC-THEME-004 FR-THEME-002
TC-THEME-005 FR-THEME-003
TC-THEME-006 FR-THEME-004
TC-THEME-007 FR-THEME-005
TC-THEME-008 FR-THEME-005
TC-THEME-009 FR-THEME-006
TC-THEME-010 FR-THEME-006
TC-SESSION-001 FR-SESSION-001
TC-SESSION-002 FR-SESSION-001
TC-SESSION-003 FR-SESSION-001
TC-SESSION-004 FR-SESSION-002
TC-SESSION-005 FR-SESSION-003
TC-SESSION-006 FR-SESSION-003
TC-SESSION-007 FR-SESSION-004
TC-SESSION-008 FR-SESSION-004
TC-SESSION-009 FR-SESSION-005
TC-SESSION-010 FR-SESSION-006
TC-SESSION-011 FR-SESSION-006
TC-SESSION-012 FR-SESSION-007
TC-SESSION-013 FR-SESSION-007
TC-SESSION-014 FR-SESSION-007
TC-SESSION-015 FR-SESSION-007
TC-SESSION-016 FR-SESSION-008
TC-SESSION-017 FR-SESSION-008
TC-SESSION-018 FR-SESSION-009
TC-CHAT-001 FR-CHAT-001
TC-CHAT-002 FR-CHAT-001
TC-CHAT-003 FR-CHAT-002
TC-CHAT-004 FR-CHAT-003
TC-CHAT-005 FR-CHAT-003
TC-CHAT-006 FR-CHAT-004
TC-CHAT-007 FR-CHAT-004
TC-CHAT-008 FR-CHAT-014
TC-CHAT-009 FR-CHAT-014
TC-CHAT-010 FR-CHAT-014
TC-CHAT-011 FR-CHAT-015
TC-CHAT-012 FR-CHAT-005
TC-CHAT-013 FR-CHAT-006
TC-CHAT-014 FR-CHAT-006
TC-CHAT-015 FR-CHAT-006
TC-CHAT-016 FR-CHAT-006
TC-CHAT-017 FR-CHAT-007
TC-CHAT-018 FR-CHAT-007
TC-CHAT-019 FR-CHAT-007
TC-CHAT-020 FR-CHAT-007
TC-CHAT-021 FR-CHAT-011
TC-CHAT-022 FR-CHAT-011
TC-CHAT-023 FR-CHAT-008
TC-CHAT-024 FR-CHAT-008
TC-CHAT-025 FR-CHAT-008
TC-CHAT-026 FR-CHAT-008
TC-CHAT-027 FR-CHAT-008
TC-CHAT-028 FR-CHAT-008
TC-CHAT-029 FR-CHAT-008
TC-CHAT-030 FR-CHAT-008, FR-HEALTH-005
TC-CHAT-031 FR-CHAT-008
TC-CHAT-032 FR-CHAT-008
TC-CHAT-033 FR-CHAT-008
TC-CHAT-034 FR-CHAT-009
TC-CHAT-035 FR-CHAT-009
TC-CHAT-036 FR-CHAT-010
TC-CHAT-037 FR-CHAT-010
TC-CHAT-038 FR-CHAT-012
TC-CHAT-039 FR-CHAT-012
TC-CHAT-040 FR-CHAT-012
TC-CHAT-041 FR-CHAT-012
TC-CHAT-042 FR-CHAT-013
TC-CHAT-043 FR-CHAT-013
TC-RETRIEVAL-001 FR-RETRIEVAL-001
TC-RETRIEVAL-002 FR-RETRIEVAL-001
TC-RETRIEVAL-003 FR-RETRIEVAL-002
TC-RETRIEVAL-004 FR-RETRIEVAL-003
TC-RETRIEVAL-005 FR-RETRIEVAL-004
TC-RETRIEVAL-006 FR-RETRIEVAL-005
TC-RETRIEVAL-007 FR-RETRIEVAL-006
TC-SOURCE-001 FR-SOURCE-001
TC-SOURCE-002 FR-SOURCE-001
TC-SOURCE-003 FR-SOURCE-002
TC-SOURCE-004 FR-SOURCE-003
TC-SOURCE-005 FR-SOURCE-004
TC-SOURCE-006 FR-SOURCE-005
TC-SOURCE-007 FR-SOURCE-006
TC-EXTRACT-001 FR-EXTRACT-001
TC-EXTRACT-002 FR-EXTRACT-002
TC-EXTRACT-003 FR-EXTRACT-002
TC-EXTRACT-004 FR-EXTRACT-003
TC-EXTRACT-005 FR-EXTRACT-004
TC-EXTRACT-006 FR-EXTRACT-004
TC-EXTRACT-007 FR-EXTRACT-004
TC-EXTRACT-008 FR-EXTRACT-004
TC-EXTRACT-009 FR-EXTRACT-005
TC-EXTRACT-010 FR-EXTRACT-005
TC-EXTRACT-011 FR-EXTRACT-006, FR-HEALTH-004
TC-KG-001 FR-KG-001
TC-KG-002 FR-KG-001
TC-KG-003 FR-KG-002
TC-KG-004 FR-KG-003
TC-KG-005 FR-KG-003
TC-KG-006 FR-KG-004
TC-KG-007 FR-KG-004
TC-KG-008 FR-KG-005
TC-KG-009 FR-KG-005
TC-KG-010 FR-KG-006
TC-KG-011 FR-KG-006
TC-KG-012 FR-KG-007, FR-HEALTH-003
TC-KG-013 FR-KG-008
TC-RESP-001 FR-RESP-001
TC-RESP-002 FR-RESP-002
TC-RESP-003 FR-RESP-003
TC-RESP-004 FR-RESP-004
TC-RESP-005 FR-RESP-005
TC-RESP-006 FR-RESP-006
TC-RESP-007 FR-RESP-007
TC-RESP-008 FR-RESP-008
TC-RESP-009 FR-RESP-009
TC-RESP-010 FR-RESP-010
TC-RESP-011 FR-RESP-011
TC-RESP-012 FR-RESP-012
TC-RESP-013 FR-RESP-013(N/A 可选)
TC-HEALTH-001 FR-HEALTH-001
TC-HEALTH-002 FR-HEALTH-001
TC-HEALTH-003 FR-HEALTH-001
TC-HEALTH-004 FR-HEALTH-002
TC-HEALTH-005 FR-HEALTH-002
TC-HEALTH-006 FR-HEALTH-003
TC-HEALTH-007 FR-HEALTH-004
TC-HEALTH-008 FR-HEALTH-005
TC-NFR-001 PRD §14 首屏可交互(非 FR)
TC-NFR-002 PRD §14 长任务反馈(非 FR)
TC-NFR-003 PRD §14 数据安全(非 FR)
TC-NFR-004 PRD §14 离线容忍(非 FR)
TC-NFR-005 PRD §14 浏览器支持(非 FR)
TC-E2E-01-M FR-CHAT-008, FR-CHAT-013
TC-E2E-01-T FR-CHAT-008, FR-CHAT-013
TC-E2E-01-D FR-CHAT-008, FR-CHAT-013
TC-E2E-02-M FR-CHAT-006
TC-E2E-02-T FR-CHAT-006
TC-E2E-02-D FR-CHAT-006
TC-E2E-03-M FR-CHAT-012, FR-HEALTH-002
TC-E2E-03-T FR-CHAT-012, FR-HEALTH-002
TC-E2E-03-D FR-CHAT-012, FR-HEALTH-002
TC-E2E-04-M FR-SESSION-001, FR-SESSION-003, FR-SESSION-004, FR-SESSION-005, FR-SESSION-006, FR-SESSION-007
TC-E2E-04-T FR-SESSION-001, FR-SESSION-003, FR-SESSION-004, FR-SESSION-005, FR-SESSION-006, FR-SESSION-007
TC-E2E-04-D FR-SESSION-001, FR-SESSION-003, FR-SESSION-004, FR-SESSION-005, FR-SESSION-006, FR-SESSION-007
TC-E2E-05-M FR-CHAT-008, FR-CHAT-011
TC-E2E-05-T FR-CHAT-008, FR-CHAT-011
TC-E2E-05-D FR-CHAT-008, FR-CHAT-011
TC-E2E-06-M FR-THEME-002
TC-E2E-06-T FR-THEME-002
TC-E2E-06-D FR-THEME-002
TC-E2E-07-M FR-KG-004, FR-KG-005, FR-KG-006
TC-E2E-07-T FR-KG-004, FR-KG-005, FR-KG-006
TC-E2E-07-D FR-KG-004, FR-KG-005, FR-KG-006
TC-E2E-08-M FR-EXTRACT-001, FR-EXTRACT-002, FR-EXTRACT-003, FR-EXTRACT-004
TC-E2E-08-T FR-EXTRACT-001, FR-EXTRACT-002, FR-EXTRACT-003, FR-EXTRACT-004
TC-E2E-08-D FR-EXTRACT-001, FR-EXTRACT-002, FR-EXTRACT-003, FR-EXTRACT-004
TC-E2E-09-M FR-RESP-004, FR-RESP-005, FR-RESP-006, FR-RESP-007, FR-RESP-008, FR-RESP-009, FR-RESP-010, FR-RESP-011, FR-RESP-012
TC-E2E-09-T FR-RESP-003
TC-E2E-09-D FR-RESP-001, FR-RESP-002, FR-SHELL-001
TC-E2E-SMOKE-01 FR-SHELL-007
TC-E2E-SMOKE-02 FR-SHELL-001, FR-SHELL-003, FR-RESP-004

2.4 模块分布

模块 TC 条数(含 E2E 拆分)
SHELL 15
THEME 10
SESSION 18
CHAT 43
RETRIEVAL 7
SOURCE 7
EXTRACT 11
KG 13
RESP 13
HEALTH 8
NFR(PRD §14) 5
E2E 主线/冒烟 29
合计 179

3. 执行说明

3.1 分层运行命令(TEST_PLAN §7)

# L1 后端单元(远端 plantai-bff conda 环境;A 组自测,T 复跑确认)
cd sdk && pytest tests -m unit -q

# L2 后端接口(respx mock 上游;用例见 L2 标注项)
cd sdk && pytest tests -m api -q

# L2s 上游 smoke(仅集成点 M2 与验收前手动各跑一次;远端本机执行)
bash tests/smoke_upstreams.sh

# L3+L4 前端(vitest;远端 ui/)
cd ui && npx vitest run

# L5 E2E(三档视口;dev server 由 playwright webServer 自动拉起或复用已启动的 5180)
cd ui && npx playwright test        # playwright 未安装时:npx playwright@1.49.1 test

3.2 Mock 场景使用(ARCHITECTURE.md §6)

mock server:python sdk/mock/mock_server.py(127.0.0.1:8099),场景经查询参数或请求头 X-Mock-Scenario 切换。E2E 中由测试代码在请求头注入或 mock 路由拦截实现:

scenario 用途 使用用例示例
normal 主流程(SSE 回放 12 帧真实时序) TC-CHAT-023~033、TC-E2E-01/02
empty 空结果(source_count=0、answer 为「未找到…」fallback) TC-SOURCE-007、TC-KG-013、TC-CHAT-027(空态分支)
slow 慢响应/长流(持续视觉反馈断言) TC-CHAT-021、TC-CHAT-029、TC-NFR-002
error 上游故障(502 UPSTREAM_ERROR) TC-CHAT-039、TC-E2E-03
degraded QA 不可用(503 UPSTREAM_DOWN) TC-HEALTH-004/005、TC-EXTRACT-011、TC-KG-012、TC-E2E-03

注意:mock 的场景切换仅覆盖 QA 端点;extraction/kg 的 503 降级在 E2E 中用 Playwright route 拦截模拟。

3.3 真实上游注意事项(DISCOVERY.md)

  1. QA LLM 402 降级(最重要):上游 DeepSeek 余额不足,degraded_execution=true,answer 为 fallback 证据列表而非自然语言答案。涉及自然语言答案内容的断言(TC-CHAT-027 等,标注「依赖充值」)在充值前执行时只验结构不断内容:answer 字段存在、text 块渲染、fallback 文案可见即可。检索/证据/来源/图谱断言(sources、chains、graph 块)不受 402 影响,照常执行。
  2. 耗时:单次 search ≈92s、stream ≈37–38s(DISCOVERY.md §4/§6.8)。真实上游的 L5/L6 用例需把 expect 超时调到 ≥180s(search 模式)/≥120s(chat 模式);BFF 读超时 300s。
  3. 上游只绑 127.0.0.1:L2s 必须在远端本机跑;Mac 本地经 SSH 隧道跑(见脚本注释)。
  4. Neo4j 当选实例 direct-v1-full(bolt 18788 / HTTP 18575),schema canonical;/api/kg/* 依赖 BFF 的 Bolt 直连(上游 kg 路由已死,不探测)。
  5. 抽取上游:8000 正常;7900 为容器(jobs 空属正常,BFF 只在 8000 不可达时回落);新上传任务可能因 MinerU 路径缺失 failed——TC-EXTRACT-008 就是断言该错误文案路径。

3.4 L5 运行环境一次性准备(已验证)

  • Node 18(远端):npx playwright@1.49.1 test 首次运行自动下载 chromium 1148(≈150MB)。实测 CDN 可达(Mac 直连 2.9MB/s)。
  • @playwright/test 模块解析:spec 文件位于 tests/e2e/,在 ui/node_modules 之外,Node 默认解析路径找不到 @playwright/test,会报 ERR_MODULE_NOT_FOUND。已在 Mac 本地验证(playwright 1.61.1 实测复现;1.49.1 CJS 变换同样回退到默认 ESM 解析,机制相同)。运行处须一次性执行(不污染任何 agent 归属文件——node_modules 不入库不同步):
    # 远端,一次性
    cd /home/xzq/5090/teamWorkspace/zh/PlantAI-rag-new
    ln -sfn ui/node_modules node_modules   # 若目录已存在先确认其内容再覆盖
    cd ui && npm install --save-dev @playwright/test@1.49.1   # 写入 package.json 需 PM 裁决,见 §5 未决问题 4
    
    Mac 本地本次验证的等价做法(未改动 ui/package.json):安装到 /tmp/pw-test-runner 后 ln -sfn /tmp/pw-test-runner/node_modules/@playwright/test ui/node_modules/@playwright/test,再 ln -sfn ui/node_modules <repo>/node_modules,以 playwright 1.61.1(匹配本机已缓存 chromium-1228)跑通 6/6。
  • 本地 Node 26 已知问题:playwright 1.49.1 的 module.register() loader 在 Node 26 + 系统高负载下启动极慢/挂起;远端 Node 18 无此问题。本地验证用 playwright 1.61.1 替代。
  • 本机验证结果(M0 冒烟):6 passed(mobile/tablet/desktop × 2 条冒烟)。冒烟断言对 B1 已交付的 AppShell 走真实分支(.app-shell/.top-bar/.status-bar,移动端 .status-bar 按 FR-RESP-004 断言隐藏),M0 占位期走占位回退分支。

4. E2E 骨架交付说明(本波)

文件 内容
ui/playwright.config.js 三项目 mobile(iPhone 14 390×844,触摸+UA)/tablet(iPad 768×1024)/desktop(1440×900);chromium;baseURL http://127.0.0.1:5180;webServer npm run dev -- --strictPort(已有 dev 复用);失败保留 trace/screenshot
tests/e2e/smoke.spec.js 2 条冒烟(TC-E2E-SMOKE-01/02),三档视口各跑一次共 6 条结果。AppShell 断言带 M0 占位回退(B1 交付后自动走真实分支,无需改测试)
tests/smoke_upstreams.sh L2s 冒烟:QA 7920 health/info、抽取 8000 health/jobs、7900 health、Neo4j(HTTP 18575 Cypher 只读查询)、mock 8099 health;PASS/FAIL 表 + 非零退出码;支持 QA_URL/EXTRACT_URL/ALT_URL/MOCK_URL/NEO4J_HTTP/TIMEOUT 环境变量覆盖

全量 L1–L5 执行从 M2 集成后开始(TEST_PLAN §5 轮次纪律);完整 E2E 用例(TC-E2E-01~09)按本文件在后续轮次落为 spec 文件。

5. 未决问题(提请 PM)

  1. 若干 UI 类断言依赖 UI_SPEC 类名(如 agent-dot-item、p-step);若 B1 实现时类名有偏差,需按 UI_SPEC §5.3 对齐(T 不自行改用例契约)。
  2. TC-EXTRACT-005/007(上传进度/超限)依赖 B2/B3 上传 UI 与 50MB 校验落点(前端或 BFF)——已按「前端拦截或 422」双路径写预期,无需改用例。
  3. TC-KG 节点详情在 Neo4j 不可用时的属性来源为「消息内 graph 块已有属性」;graph 块节点若不含属性字段,该断言在实现时需以实际块结构微调步骤(预期语义不变)。
  4. L5 依赖安装需 PM 裁决:tests/e2e/ 的 spec 需要解析 @playwright/test,而它位于 ui/node_modules 之外。两个方案二选一:(a) 远端一次性 npm install --save-dev @playwright/test@1.49.1(写入 B1 归属的 ui/package.json,需 PM 批准);(b) 保持 npx playwright@1.49.1 并在远端建 node_modules 根符号链接 + @playwright/test 符号链接(不改 package.json,M2 前由 T/PM 在远端一次性执行)。本波按 (b) 在 Mac 本地验证通过(6/6 pass),建议远端集成点采用 (b)。
  5. task 验证命令差异:任务书给的验证命令 npx playwright test(无版本)在本机无已安装 playwright 时会从 npm 拉最新版;远端 Node 18 + npx playwright@1.49.1 仍会拉 1.49.1 的 chromium 1148(≈150MB,CDN 实测可达)。已在本文件 §3.4 记录完整步骤。

6. 生信流程编排(FR-BIO-001~032)

本节由 T1 编制(阶段 0,2026-09-05)。需求唯一来源:PRD.md §16;组件规格:UI_SPEC.md §8;分层与门禁:TEST_PLAN.md §9-12;端点事实:实施计划 §六。意图分流词典唯一事实源:docs/team/cases_bioflow_intent.md(前后端同表双跑)。 编号 TC-BIO-<模块>-<序号>;E2E 视口后缀 M/T/D(390×844 / 768×1024 / 1440×900)。分层:L1 生信服务单元(pytest -m bioflow_unit)|L2 生信接口(pytest -m bioflow_api,mock LLM/vstore/docker)|L2s 生信冒烟(bash bioflow_kernel/tests/smoke_golden.sh,仅集成点手动)|L3 前端单元(vitest)|L4 前端组件(vitest + @vue/test-utils)|L5(Playwright 三档视口)。 可断言性:预期列均为可观察断言(HTTP 状态/请求体字段/存储值/元素存在/计算样式值/事件序列),无「检查是否正确」类断言。 模块缩写:INTENT 意图分流 | API 生信服务端点 | RUN runner 状态机 | KERN 内核执行与 manifest | SSE 事件流 | DB 三表迁移 | FLOW 上下游集成 | STORE 前端 store | PATH 路径卡 | FORM 参数表单卡 | FILE 文件引导卡 | PROG 进度卡 | ARCH 存档卡 | JOB 生信任务面板 | PANE 生信档案面板 | ACT UI 动作矩阵 | DEPLOY 三形态部署 | REG 回归 | GOLD 金标与发布 | E2E 端到端主线。

6.1 用例清单

6.1.1 INTENT 意图分流(FR-BIO-001/FR-BIO-023/FR-BIO-026,词典唯一事实源 docs/team/cases_bioflow_intent.md)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-INTENT-001 FR-BIO-001 命中「帮我跑水稻 SPL 家族鉴定」 无附件、无活动文档 route("帮我跑水稻 SPL 家族鉴定") 返回 bioflow(词典用例表第 1 条) L3 P0
TC-BIO-INTENT-002 FR-BIO-001 命中「跑一下拟南芥 MADS-box 家族分析」 无附件、无活动文档 route("跑一下拟南芥 MADS-box 家族分析") 返回 bioflow L3 P0
TC-BIO-INTENT-003 FR-BIO-001 命中「请帮我鉴定水稻 SPL 家族」 无附件 route("请帮我鉴定水稻 SPL 家族") 返回 bioflow L3 P0
TC-BIO-INTENT-004 FR-BIO-001 命中「识别玉米 bZIP 家族成员」 无附件 route("识别玉米 bZIP 家族成员") 返回 bioflow L3 P0
TC-BIO-INTENT-005 FR-BIO-001 命中「帮我研究一下水稻 SPL 基因家族」 无附件 route("帮我研究一下水稻 SPL 基因家族") 返回 bioflow L3 P0
TC-BIO-INTENT-006 FR-BIO-001 命中「分析小麦 WRKY 转录因子家族」 无附件 route("分析小麦 WRKY 转录因子家族") 返回 bioflow L3 P0
TC-BIO-INTENT-007 FR-BIO-001 命中「做个大豆 NAC 家族分析」 无附件 route("做个大豆 NAC 家族分析") 返回 bioflow L3 P0
TC-BIO-INTENT-008 FR-BIO-001 命中「跑 SPL 家族」 无附件 route("跑 SPL 家族") 返回 bioflow L3 P0
TC-BIO-INTENT-009 FR-BIO-001 命中「水稻 SPL 家族,帮我跑」 无附件 route("水稻 SPL 家族,帮我跑") 返回 bioflow L3 P0
TC-BIO-INTENT-010 FR-BIO-001 命中「基因家族鉴定:水稻 SPL」 无附件 route("基因家族鉴定:水稻 SPL") 返回 bioflow L3 P0
TC-BIO-INTENT-011 FR-BIO-001 漏判安全:知识问答 无附件 route("什么是基因家族?") 返回 qa L3 P0
TC-BIO-INTENT-012 FR-BIO-001 漏判安全:光有动词 无附件 route("帮我跑一下") 返回 qa L3 P0
TC-BIO-INTENT-013 FR-BIO-001 漏判安全:光有家族名 无附件 route("SPL 家族") 返回 qa L3 P0
TC-BIO-INTENT-014 FR-BIO-001 漏判安全:无动词无家族 无附件 route("今天天气不错") 返回 qa L3 P1
TC-BIO-INTENT-015 FR-BIO-001 漏判安全:问方法 无附件 route("跑 SPL 家族鉴定需要准备什么输入?") 返回 qa L3 P0
TC-BIO-INTENT-016 FR-BIO-001 漏判安全:非生信对象 无附件 route("帮我跑一个数据分析") 返回 qa L3 P1
TC-BIO-INTENT-017 FR-BIO-001 漏判安全:闲聊 无附件 route("你好呀") 返回 qa L3 P1
TC-BIO-INTENT-018 FR-BIO-001 漏判安全:空字符串 无附件 route("") 返回 qa L3 P1
TC-BIO-INTENT-019 FR-BIO-001 漏判安全:纯空白 无附件 route(" ") 返回 qa L3 P1
TC-BIO-INTENT-020 FR-BIO-001 漏判安全:乱码 无附件 route("⚡☂☄ hmm") 返回 qa(非 bioflow) L3 P2
TC-BIO-INTENT-021 FR-BIO-001 漏判安全:未在词典的家族名 无附件 route("帮我跑香蕉 XYK 家族鉴定") 返回 qa(XYK 不在家族词典) L3 P1
TC-BIO-INTENT-022 FR-BIO-001 边界:大小写家族名 无附件 route("跑水稻 spl 家族鉴定") 返回 bioflow(家族名大小写不敏感) L3 P1
TC-BIO-INTENT-023 FR-BIO-001 边界:英文整句 无附件 route("Please run rice SPL family identification") 返回 bioflow L3 P1
TC-BIO-INTENT-024 FR-BIO-001 边界:标点夹杂 无附件 route("帮我跑(水稻 SPL 家族)鉴定!") 返回 bioflow L3 P1
TC-BIO-INTENT-025 FR-BIO-001 边界:超长文本(>200 字) 无附件 route(200 字长文含「跑水稻 SPL 家族鉴定」在末尾) 返回 bioflow L3 P2
TC-BIO-INTENT-026 FR-BIO-001 边界:家族名跨词干扰 无附件 route("这个 SPL 会议帮我跑一下流程") 返回 qa(SPL 后无家族/分析对象词) L3 P2
TC-BIO-INTENT-027 FR-BIO-001 附件存在不改判定 has_attachments=true route("帮我跑水稻 SPL 家族鉴定") 返回 bioflow L3 P1
TC-BIO-INTENT-028 FR-BIO-001 活动文档存在不改判定 has_active_artifact=true route("帮我跑水稻 SPL 家族鉴定") 返回 bioflow L3 P1
TC-BIO-INTENT-029 FR-BIO-001 docgen 优先:写报告 无附件、无活动文档 route("帮我生成一份水稻 SPL 家族分析报告") 返回 docgen(既有 docgen 路由在 bioflow 之前判定) L3 P0
TC-BIO-INTENT-030 FR-BIO-001 docgen 优先:撰写论文 无附件 route("帮我写一篇水稻基因家族研究论文") 返回 docgen L3 P1
TC-BIO-INTENT-031 FR-BIO-001 export 优先 has_active_artifact=true route("导出成 PDF") 返回 export L3 P1
TC-BIO-INTENT-032 FR-BIO-001 edit 优先:文档打开时改文字 has_active_artifact=true route("把这句话改成红色") 返回 edit L3 P1
TC-BIO-INTENT-033 FR-BIO-019 图表调整走 bioflow:文档打开时 has_active_artifact=true route("xxx 图表颜色换成红色") 返回 bioflow(图表类词命中生信,不进 edit) L3 P0
TC-BIO-INTENT-034 FR-BIO-023 存档复用命中:标准句式 无附件 route("用 XXX 存档任务的方法帮我跑水稻 SPL 家族鉴定") 返回 bioflow 且解析出复用意图(方法名=XXX) L3 P0
TC-BIO-INTENT-035 FR-BIO-023 存档复用命中:根据句式 无附件 route("根据 XXX 存档任务的方法帮我跑一下玉米 bZIP") 返回 bioflow 且复用意图成立 L3 P1
TC-BIO-INTENT-036 FR-BIO-023 存档复用命中:参考句式 无附件 route("参考 XXX 存档的方法再跑一个水稻 SPL") 返回 bioflow 且复用意图成立 L3 P1
TC-BIO-INTENT-037 FR-BIO-023 存档复用命中:按句式中文括号 无附件 route("用《XXX》存档任务的方法帮我跑小麦 WRKY 家族") 返回 bioflow 且方法名=XXX L3 P1
TC-BIO-INTENT-038 FR-BIO-023 存档复用边界:只有复用词无任务词 无附件 route("用 XXX 存档任务的方法") 返回 qa(无「帮我跑 xxxx」目标) L3 P1
TC-BIO-INTENT-039 FR-BIO-023 存档复用边界:无家族对象 无附件 route("用 XXX 存档任务的方法帮我跑 yyy") 返回 qa(yyy 无家族名匹配,漏判安全) L3 P1
TC-BIO-INTENT-040 FR-BIO-001 标点与空白容错 无附件 route("帮我跑 水稻 SPL 家族 鉴定") 返回 bioflow L3 P2
TC-BIO-INTENT-041 FR-BIO-001 命中 RNA-seq 无附件 route("帮我跑水稻叶片 RNA-seq 差异表达分析") 返回 bioflow L3 P0
TC-BIO-INTENT-042 FR-BIO-001 命中 WGS 无附件 route("帮我做水稻全基因组变异检测") 返回 bioflow L3 P1
TC-BIO-INTENT-043 FR-BIO-001 命中 GWAS 无附件 route("帮我跑水稻产量性状 GWAS 关联分析") 返回 bioflow L3 P1
TC-BIO-INTENT-044 FR-BIO-001 交互式补充未命中(词典无此规则,漏判安全) 会话上文为「帮我跑水稻 SPL 家族鉴定」已开任务 route("换玉米,重跑") 返回 qa(TL 2026-09-06 修订:与冻结词典一致;「换物种重跑」交互式补充转 P7 增强项) L3 P2
TC-BIO-INTENT-045 FR-BIO-026 流程咨询在生信流内 会话已有生信任务 route("identify 需要什么输入") 返回 bioflow 内 flow_qa 路径(不新建任务) L3 P1
TC-BIO-INTENT-046 FR-BIO-001 命中句不打乱 QA 流 无生信上下文 先 route("什么是 SPL 家族") 再 route("帮我跑水稻 SPL 家族鉴定") 第 1 条=qa、第 2 条=bioflow,两者互不影响 L3 P2
TC-BIO-INTENT-047 FR-BIO-001 词典同表后端一致性 后端 bioflow_service 已部署 后端对词典用例表 40+ 条输入逐一分流 后端判定结果与词典期望逐条一致(同表双跑) L2 P0

6.1.2 API 生信服务端点(实施计划 §六 20 端点;mock LLM/vstore/docker)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-API-001 FR-BIO-001 chat/stream 入口建立 SSE mock LLM/vstore POST /api/bioflow/chat/stream {"session_id":"s1","message":"帮我跑水稻 SPL 家族鉴定"} 流式读首个事件 响应 200;Content-Type=text/event-stream;首个事件类型=job_created(或 plan_ready),data 为 JSON L2 P0
TC-BIO-API-002 FR-BIO-002 候选路径随 plan_ready 下发 mock LLM 返回 3 条候选路径 读流至 plan_ready 事件 plan_ready.data.candidates 为数组,length 在 2~3;每条含 stages[](非空)与 purpose(非空字符串) L2 P0
TC-BIO-API-003 FR-BIO-003 伪造阶段被拒 mock LLM 候选含未知阶段「fake_stage_xyz」 读流至第 1 个 plan/error 事件 事件 data 含 code=UNKNOWN_STAGE 且 fake_stage_xyz 被点名;该候选不进入候选集 L2 P0
TC-BIO-API-004 FR-BIO-003 前置阶段自动补全 候选链缺 identify 前置 读流至 plan_ready 事件 data.candidates[*].stages 已含前置;data 或后续事件文本含「已自动补全」明示字段 auto_filled[]=前置阶段名 L2 P0
TC-BIO-API-005 FR-BIO-001 非生信消息不建任务 mock LLM 分流 POST 消息「什么是基因家族」读流 响应 200;事件含 message_done 且不含 job_created;data 不含 job_id L2 P0
TC-BIO-API-006 FR-BIO-001 空 message 422 无 POST {"session_id":"s1","message":""} 422;detail 含 message 字段错误 L2 P1
TC-BIO-API-007 FR-BIO-001 缺 message 字段 422 无 POST {"session_id":"s1"} 422;detail 含 message L2 P1
TC-BIO-API-008 FR-BIO-001 缺 session_id 422 无 POST {"message":"帮我跑水稻 SPL 家族鉴定"} 422;detail 含 session_id L2 P1
TC-BIO-API-009 FR-BIO-001 LLM 超时降级 mock LLM 延迟超过上限 读流至第 1 个事件 事件 data 含 code=PLAN_LLM_TIMEOUT 的降级提示;SSE 正常关闭 L2 P1
TC-BIO-API-010 FR-BIO-001 vstore 不可用降级 mock vstore 返回 500 读流至 plan_ready plan_ready 正常返回(LLM 直接候选);data.source 标记=llm_only;无 5xx 中断 L2 P1
TC-BIO-API-011 FR-BIO-023 存档复用句式接口路径 归档「XXX」存在且含参数 POST message「用 XXX 存档任务的方法帮我跑玉米 bZIP」读流至 job_created job_created.data.reused_archive=XXX;bio_jobs 行参数=存档参数 L2 P0
TC-BIO-API-012 FR-BIO-026 流程咨询接口路径 任务已存在 POST message「identify 需要什么输入」读流 事件含 message_done;data.citations[] 含来源文件+章节;不产生新 job_created L2 P0
TC-BIO-API-013 FR-BIO-014 断流时任务不回滚 mock docker 慢 流中途关闭客户端 任务在 DB 仍 in-flight;重连 events 接口可回放 L2 P1
TC-BIO-API-014 FR-BIO-001 客户端断开清理 任务尚未创建 收到首个字节后立即断开 服务端无未捕获异常;资源释放(无连接泄漏,服务存活) L2 P2
TC-BIO-API-015 FR-BIO-001 超长消息拒绝 无 POST message=100001 字符 422(max_length 超限)或 400;不触发 LLM 调用 L2 P1
TC-BIO-API-016 FR-BIO-031 并发 chat 上限 已有 3 个 in-flight 任务 再发起第 4 个任务型消息 第 4 个任务不立即执行;事件 data 含 queued=true 或状态=queued L2 P0
TC-BIO-API-017 FR-BIO-014 断线重连回放快照 任务含 3 阶段(1 done 1 running 1 waiting) GET /api/bioflow/jobs/{id}/events 首帧 首帧 data 为任务快照:stages 数组=3、每阶段含 status;无 stage_* 事件丢失 L2 P0
TC-BIO-API-018 FR-BIO-001 事件包含 plan_ready 后必有确认点 候选路径选定 读事件序列 序列中出现 stage_await_confirm(或 plan_ready);事件顺序由 seq 严格递增 L2 P1
TC-BIO-API-019 FR-BIO-001 chat/stream 400 请求体非 JSON 无 POST body="not-json" Content-Type: application/json 400 或 422 L2 P2
TC-BIO-API-020 FR-BIO-001 LLM 完全不可用 mock LLM 连接拒绝 读流至第 1 个事件 事件 data 含 code=PLAN_UNAVAILABLE;SSE 关闭;无 job 落库 L2 P1
TC-BIO-API-021 FR-BIO-002 catalog 返回全部阶段(与权威数据一致) 服务正常 GET /api/bioflow/catalog 200;data.stages 数组 length 与 bioflow_kernel/stage_image_map.json v2.0.0 的 stages 数一致(TL 2026-09-06 修订:当前 75,原 73 为 dev 旧树口径);每项含 name/description/params/inputs/outputs L2 P0
TC-BIO-API-022 FR-BIO-002 catalog 基因家族链全部阶段(与权威数据一致) 无 GET /api/bioflow/catalog?chain=gene_family 200;返回项数与 stage_image_map.json 的 family_chain 一致(TL 2026-09-06 修订:当前 21,原 18 为 dev 旧树口径);name 集合与 family_chain 一致 L2 P0
TC-BIO-API-023 FR-BIO-002 catalog 参数 schema 无 GET /api/bioflow/catalog?stage=identify 返回 identify 项;params[] 每项含 name/type/default/source/help;inputs 含 fasta/hmm 类 L2 P0
TC-BIO-API-024 FR-BIO-002 catalog 未知阶段 404 无 GET /api/bioflow/catalog?stage=nope 404 信封 code=NOT_FOUND L2 P1
TC-BIO-API-025 FR-BIO-002 catalog 镜像映射字段 无 GET /api/bioflow/catalog?stage=identify 该项 image 字段=bioflow-gf(与 stage_image_map.json 一致) L2 P1
TC-BIO-API-026 FR-BIO-002 catalog 缓存无效时重载 修改 catalog 源后 GET /api/bioflow/catalog 返回新数据(无服务重启);ETag 或 Last-Modified 变化 L2 P2
TC-BIO-API-027 FR-BIO-004 POST jobs 创建任务 候选链已选定 POST /api/bioflow/jobs {"session_id":"s1","title":"SPL 鉴定","stages":["identify","align","phylogeny"],"params":{}} 201;body 含 id/uuid、title、status=created、stages 数组 3 项(status=waiting) L2 P0
TC-BIO-API-028 FR-BIO-004 POST jobs 缺 stages 422 无 POST {"session_id":"s1","title":"t"} 422;detail 含 stages L2 P1
TC-BIO-API-029 FR-BIO-023 POST jobs 复用归档 归档 a1 含阶段链+参数 POST {"session_id":"s1","archive_id":"a1"} 201;body.stages=归档阶段链;params=归档参数;bio_archives 行 reused_count+1 L2 P0
TC-BIO-API-030 FR-BIO-004 POST jobs 未知 stage 拒绝 无 POST {"stages":["ghost_stage"]} 422/400;detail 点名 ghost_stage 不在 catalog L2 P1
TC-BIO-API-031 FR-BIO-004 POST jobs 缺 session_id 422 无 POST {"title":"t","stages":["identify"]} 422;detail 含 session_id L2 P1
TC-BIO-API-032 FR-BIO-024 GET jobs 列表 库中 3 个任务 GET /api/bioflow/jobs 200;data.items length=3;按 created_at 倒序;每项含 id/title/status/progress L2 P0
TC-BIO-API-033 FR-BIO-024 GET jobs 分页 25 个任务 GET /api/bioflow/jobs?page=2&page_size=10 200;items length=10;total=25 L2 P1
TC-BIO-API-034 FR-BIO-024 GET job 详情 任务含 3 阶段 GET /api/bioflow/jobs/{id} 200;body.stages length=3 且各含 stage/status/params;progress 为数字 0-100 L2 P0
TC-BIO-API-035 FR-BIO-024 GET job 404 无 GET /api/bioflow/jobs/not-exist 404 信封 code=NOT_FOUND L2 P1
TC-BIO-API-036 FR-BIO-024 任务阶段子资源 任务 j1 GET /api/bioflow/jobs/{j1}/stages 200;数组与任务阶段一致,含每阶段开始/结束时间 L2 P1
TC-BIO-API-037 FR-BIO-024 DELETE job 任务 j1 DELETE /api/bioflow/jobs/{j1} 204;GET 后 404;bio_stages 级联删除 L2 P1
TC-BIO-API-038 FR-BIO-024 DELETE 进行中任务 任务 running DELETE /api/bioflow/jobs/{id} 409 信封 code=JOB_RUNNING(拒绝) L2 P1
TC-BIO-API-039 FR-BIO-006 POST files 上传 任务 j1 起始阶段 await_files POST /api/bioflow/jobs/{j1}/files multipart file=test.fa 200;body 含 file_id/name/size=测试文件字节数/path 以 /job/{j1}/input/ 开头 L2 P0
TC-BIO-API-040 FR-BIO-006 上传写入任务目录 同上 上传后读服务器文件系统 文件存在于任务 input 目录;内容字节与上传一致 L2 P0
TC-BIO-API-041 FR-BIO-006 大文件流式上传 456MB fixture 上传并统计内存峰值 200;服务端内存峰值 < 200MB(流式不整读) L2 P0
TC-BIO-API-042 FR-BIO-007 路径登记合法 任务 j1 POST /api/bioflow/jobs/{j1}/files {"server_path":"/home/xzq/5090/teamWorkspace/zh/bioflow-data/examples/SPL.fa"} 200;body 含登记记录 path;GET files 列表可见;无文件复制(path 指向原位) L2 P0
TC-BIO-API-043 FR-BIO-007 路径登记不存在文件 无 POST files {"server_path":"/nonexistent/x.fa"} 400 信封 code=PATH_NOT_EXIST;无登记记录 L2 P0
TC-BIO-API-044 FR-BIO-007 路径登记目录而非文件 无 POST files {"server_path":"/tmp"} 400 信封 code=NOT_A_FILE L2 P1
TC-BIO-API-045 FR-BIO-007 路径登记非白名单根 无 POST files {"server_path":"/etc/passwd"} 403 信封 code=PATH_NOT_ALLOWED(限 BIOFLOW_DATA_ROOT/任务目录内) L2 P0
TC-BIO-API-046 FR-BIO-006 上传类型限制 任务 j1 上传 file.exe(扩展名不在白名单) 422;detail 指明扩展名不允 L2 P1
TC-BIO-API-047 FR-BIO-006 上传大小上限 任务 j1 上传超过上限的 fixture 413;detail 含 max_size 与实到字节数 L2 P1
TC-BIO-API-048 FR-BIO-006 GET files 列表 任务 j1 已登记 2 文件 GET /api/bioflow/jobs/{j1}/files 200;items length=2;每项含 name/path/size/registered_at;含服务器路径登记项 source=server_path L2 P0
TC-BIO-API-049 FR-BIO-006 上传完成事件 任务 j1 await_files 上传满足阶段输入 后续事件流出现 stage_started(该阶段不再 await_files);bio_stages 状态=waiting_confirm 或 running L2 P0
TC-BIO-API-050 FR-BIO-006 上传失败不登记 mock 磁盘写失败 上传 500 信封;files 列表不含该文件 L2 P2
TC-BIO-API-051 FR-BIO-006 同文件重复上传 已上传 a.fa 再次上传同名 a.fa 200;新 file_id;input 目录 a.fa 被覆盖(或 409 按实现断言其一,二选一固定) L2 P1
TC-BIO-API-052 FR-BIO-006 多文件并发上传 任务 j1 并发 3 个 multipart 上传 3 个均 200;files 列表 length=3;无文件交错损坏(各 size 与源一致) L2 P1
TC-BIO-API-053 FR-BIO-006 中文文件名 任务 j1 上传「水稻基因组.fa」 200;files 列表 name=水稻基因组.fa 且 URL 编码取回正确 L2 P2
TC-BIO-API-054 FR-BIO-006 空文件上传 任务 j1 上传 0 字节文件 200 且 size=0(或 422 按实现断言其一,二选一固定) L2 P2
TC-BIO-API-055 FR-BIO-006 GET files 单文件内容 已上传 a.fa GET /api/bioflow/jobs/{j1}/files/{file_id}/content 200;Content-Type 与文件一致;body 字节与源一致 L2 P1
TC-BIO-API-056 FR-BIO-008 confirm 发起执行 阶段 identify 状态 waiting_confirm POST /api/bioflow/jobs/{j1}/stages/identify/confirm {"params":{"cpu":8}} 200;body.status=running;bio_stages 参数已存 cpu=8 L2 P0
TC-BIO-API-057 FR-BIO-009 confirm 参数覆盖 默认参数 cpu=4 POST confirm {"params":{"cpu":16}} 后续 mock docker 命令含 --cpu 16(非 4);stage 执行用新值 L2 P0
TC-BIO-API-058 FR-BIO-008 confirm 拒绝非 schema 参数 无 POST confirm {"params":{"magic":"x"}} 422;detail 含 magic 未知参数 L2 P1
TC-BIO-API-059 FR-BIO-009 重复 confirm 幂等 阶段已 running 再次 POST confirm 409 信封 code=STAGE_NOT_CONFIRMABLE L2 P1
TC-BIO-API-060 FR-BIO-009 confirm 未知阶段 无 POST /stages/nope/confirm 404 信封 L2 P1
TC-BIO-API-061 FR-BIO-009 confirm 非等待态 阶段 done POST confirm 409 信封 code=INVALID_STAGE_TRANSITION L2 P1
TC-BIO-API-062 FR-BIO-012 rerun 失败阶段 阶段 failed POST /api/bioflow/jobs/{j1}/stages/{st}/rerun 200;状态=running 或 waiting_confirm(rerun_with_params);bio_stages 新增 attempt 记录 L2 P0
TC-BIO-API-063 FR-BIO-012 rerun 带新参数 阶段 failed POST rerun {"params":{"cpu":2}} mock docker 命令含 --cpu 2;成功后状态=done L2 P0
TC-BIO-API-064 FR-BIO-012 rerun 非 failed 409 阶段 done POST rerun 409 信封 code=STAGE_NOT_FAILED L2 P1
TC-BIO-API-065 FR-BIO-012 skip 失败阶段 阶段 failed POST /api/bioflow/jobs/{j1}/stages/{st}/skip 200;状态=skipped;事件流出现 stage_skipped L2 P0
TC-BIO-API-066 FR-BIO-012 skip 非 failed 409 阶段 running POST skip 409 信封 L2 P1
TC-BIO-API-067 FR-BIO-010 pause 生效 任务 2/5 阶段 running POST /api/bioflow/jobs/{j1}/pause 200;状态=paused;事件 job_paused;当前阶段不启新 docker L2 P0
TC-BIO-API-068 FR-BIO-010 pause 已完成任务 409 任务 done POST pause 409 信封 code=JOB_NOT_RUNNING L2 P1
TC-BIO-API-069 FR-BIO-010 resume 继续 任务 paused POST /api/bioflow/jobs/{j1}/resume 200;状态=running;等待确认的阶段回到 waiting_confirm(不跳过确认) L2 P0
TC-BIO-API-070 FR-BIO-010 resume 非 paused 409 任务 created POST resume 409 信封 L2 P1
TC-BIO-API-071 FR-BIO-011 manifest+日志尾 阶段 identify done GET /api/bioflow/jobs/{j1}/stages/identify/manifest 200;body 含 manifest 对象与 log_tail 字符串;log_tail 行数≤80 L2 P0
TC-BIO-API-072 FR-BIO-011 manifest 日志恰好 80 行边界 日志 80 行 fixture GET manifest log_tail 行数=80 且含第 1 行与第 80 行 L2 P1
TC-BIO-API-073 FR-BIO-011 日志超 80 行截尾 日志 200 行 fixture GET manifest log_tail 行数=80 且为最后 80 行(第 1 行=原第 121 行) L2 P1
TC-BIO-API-074 FR-BIO-011 manifest 404 未执行阶段 GET .../stages/nope/manifest 404 信封 L2 P1
TC-BIO-API-075 FR-BIO-011 manifest 判成败字段 阶段失败 fixture GET manifest body.manifest.status 存在且为 failed;log_tail 含报错行 L2 P0
TC-BIO-API-076 FR-BIO-011 日志尾含 ANSI 色码清洗 日志含 \x1b[31m GET manifest log_tail 不含原始转义序列(已清洗或原样两态断言其一) L2 P2
TC-BIO-API-077 FR-BIO-014 events SSE 全事件序列 mock 任务跑通 3 阶段 GET /api/bioflow/jobs/{j1}/events 收集全部事件 事件序列=job_created→plan_ready→stage_started→stage_log(≥1)→stage_await_confirm→stage_done(×3 阶段)→job_done;seq 严格递增 L2 P0
TC-BIO-API-078 FR-BIO-014 events 断线重连回放 任务 3 阶段(1 done 1 running 1 waiting) GET events 首帧快照后按事件序补齐历史:stage_done(第 1 阶段)必回放;不含重复 stage_done L2 P0
TC-BIO-API-079 FR-BIO-014 events 单阶段过滤 任务多阶段 GET /api/bioflow/jobs/{j1}/events?stage=identify 仅 identify 的事件;不含其他阶段事件 L2 P1
TC-BIO-API-080 FR-BIO-014 events 心跳保活 任务运行中无新事件 等待 2×心跳间隔 收到至少 1 条 :keepalive 注释行;连接未断 L2 P1
TC-BIO-API-081 FR-BIO-014 events job_done 后关闭 任务 done 读流至 job_done 收到 job_done 后服务端正常关闭连接 L2 P1
TC-BIO-API-082 FR-BIO-014 events 客户端断开清理 任务运行中 断开 events 连接 订阅者计数回落;服务无泄漏(再连正常) L2 P2
TC-BIO-API-083 FR-BIO-014 events 事件 id 递增 任务运行中 读全部事件 每个事件 data.seq 比前一事件 +1,无重复 seq L2 P1
TC-BIO-API-084 FR-BIO-019 revise 重跑绘图阶段 报告任务含绘图阶段 plot_heatmap POST /api/bioflow/report/{job_id}/revise {"target":"图1 颜色","instruction":"红色","params":{"color":"red"}} 200;body 含 rerun_stage=plot_heatmap;该阶段 attempt+1 且状态=running L2 P0
TC-BIO-API-085 FR-BIO-019 revise 后新图回填 绘图阶段重跑完成 轮询 job 状态至 done;GET report 报告 HTML 中对应图 fig://id 的 base64 内容变化(与 revise 前不同) L2 P0
TC-BIO-API-086 FR-BIO-019 revise 纯文字指令走 docgen 报告已登记 POST revise {"instruction":"首段字号加大"}(无图表目标) 不触发绘图阶段重跑;调用报告编辑链路(docgen);报告文字更新 L2 P1
TC-BIO-API-087 FR-BIO-020 存档 POST 任务 done 含报告 POST /api/bioflow/archives {"job_id":"j1","name":"SPL 水稻鉴定","description":"...","include_intermediate":true} 201;body 含 id/name/disk_path/size_bytes>0;磁盘路径目录存在且含 report.html L2 P0
TC-BIO-API-088 FR-BIO-020 存档名称缺失 422 任务 done POST {"job_id":"j1"} 422;detail 含 name L2 P1
TC-BIO-API-089 FR-BIO-020 放弃存档不调接口 前端已出提示 点击放弃后观察网络 无 POST /api/bioflow/archives 请求 L4 P1
TC-BIO-API-090 FR-BIO-022 GET archives 列表 3 个归档 GET /api/bioflow/archives 200;items length=3 按 created_at 倒序;每项含 name/description/size/disk_path L2 P0
TC-BIO-API-091 FR-BIO-022 GET archive 详情 归档 a1 GET /api/bioflow/archives/{a1} 200;含 stages 链、params、report_artifact、文件清单 L2 P0
TC-BIO-API-092 FR-BIO-022 DELETE archive 归档 a1 DELETE /api/bioflow/archives/{a1} 204;磁盘目录删除;GET 后 404 L2 P1
TC-BIO-API-093 FR-BIO-022 DELETE archive 404 无 DELETE /api/bioflow/archives/nope 404 信封 L2 P1
TC-BIO-API-094 FR-BIO-023 archive run 复用发起 归档 a1 POST /api/bioflow/archives/{a1}/run {"session_id":"s1","target":"玉米 bZIP"} 201;新任务 job_id 返回;stages=归档链;params 预填归档值 L2 P0
TC-BIO-API-095 FR-BIO-023 名称精确匹配优先 归档「SPL」与「SPL2」 POST archives/run {"name":"SPL"} 命中 SPL(精确优先) L2 P1
TC-BIO-API-096 FR-BIO-023 名称模糊候选 归档「水稻SPL」 POST archives/run {"name":"SPL 水稻"} 返回候选列表(≥1)且不含无关归档 L2 P1
TC-BIO-API-097 FR-BIO-023 复用无匹配 404 无 POST archives/run {"name":"不存在"} 404 信封 code=ARCHIVE_NOT_FOUND L2 P1
TC-BIO-API-098 FR-BIO-020 重名归档 409 已有归档名「X」 POST archives {"name":"X"} 409 信封(或 201 自动去重两态断言其一) L2 P2
TC-BIO-API-099 FR-BIO-025 health 探活 服务运行 GET /api/bioflow/health 200;body 含 status=ok 与 db 连通状态字段 L2 P0
TC-BIO-API-100 FR-BIO-028 BFF 反代开关开启态 BIOFLOW_ENABLED=true GET http://BFF/api/bioflow/health 200 且响应体=直连 8098 响应体 L2 P0
TC-BIO-API-101 FR-BIO-028 BFF 反代开关关闭态 BIOFLOW_ENABLED=false GET http://BFF/api/bioflow/health 404(路由未注册) L2 P0
TC-BIO-API-102 FR-BIO-028 反代 SSE 透传不缓冲 BFF 反代开启;任务运行 经 BFF 连 events 测首字节延迟 首帧到达延迟与直连差 <500ms;流连续无缓冲合并 L2 P0
TC-BIO-API-103 FR-BIO-028 BFF 停而生信服务直连可用 BFF 停止(mock) 直连 GET :8098/api/bioflow/health 200;任务可继续(GET jobs 正常) L2 P0
TC-BIO-API-104 FR-BIO-015 报告登记端点 任务 done 报告在任务目录 BFF 调用报告登记(字段 job_id/标题/md/图清单) doc_artifacts 表出现新行;字段与 docgen 报告表对齐 L2 P0
TC-BIO-API-105 FR-BIO-006 反代上传超时单独调大 BFF 反代开启 经 BFF 上传 456MB fixture 200;无 502/504;服务端统计耗时正常 L2 P1
TC-BIO-API-106 FR-BIO-007 路径登记经 BFF 反代 反代开启 经 BFF POST files {"server_path": 合法} 200 且直连与反代结果一致 L2 P2
TC-BIO-API-107 FR-BIO-004 jobs 创建后进度字段 新任务 GET job progress=0;stages 全部 waiting L2 P1
TC-BIO-API-108 FR-BIO-011 日志尾非 running 阶段也可见 阶段 done GET manifest 200;log_tail 非空(保留最后执行日志) L2 P1
TC-BIO-API-109 FR-BIO-031 第 4 并发任务排队 3 任务 running(mock) 创建第 4 任务并 confirm 第 4 任务不立即出 stage_started;前 3 任一完成后方出现 L2 P0
TC-BIO-API-110 FR-BIO-031 并发信号量可配 BIOFLOW_CONCURRENCY=1 重启 2 任务并发 始终只有 1 个 docker 在跑(mock 计数=1) L2 P1
TC-BIO-API-111 FR-BIO-031 重启续跑不重跑已完成 任务 3 阶段(1 done 1 running);重启服务 观察 重启后第 1 阶段保持 done(无新 attempt);第 2 阶段从断点续跑 L2 P0
TC-BIO-API-112 FR-BIO-024 任务列表过滤状态 库中 done/failed 各一 GET /api/bioflow/jobs?status=failed items 仅 failed 任务 L2 P1
TC-BIO-API-113 FR-BIO-024 任务列表按会话过滤 会话 s1 2 任务 GET /api/bioflow/jobs?session_id=s1 items length=2 L2 P1
TC-BIO-API-114 FR-BIO-002 catalog 阶段用途文案 无 GET catalog?stage=identify description 非空中文文案(含输入输出描述) L2 P1
TC-BIO-API-115 FR-BIO-029 执行日志含资源参数 阶段 running(mock docker 记录命令) 读 stage_log 日志或 mock 记录含 --cpus 与 --memory 数值 L2 P0
TC-BIO-API-116 FR-BIO-029 镜像按阶段映射 identify 阶段 mock 记录 docker 命令 命令镜像=bioflow-gf(stage_image_map 映射) L2 P0
TC-BIO-API-117 FR-BIO-029 容器 --user 宿主机 uid 阶段执行 mock 记录命令 含 --user 且值=服务进程 uid L2 P0
TC-BIO-API-118 FR-BIO-029 BIOFLOW_DATA 只读挂载 阶段执行 mock 记录命令 含 -v {BIOFLOW_DATA_ROOT}:/bioflow-data:ro L2 P0
TC-BIO-API-119 FR-BIO-029 容器退出即清理 阶段完成 mock 记录 含 --rm 标志 L2 P1
TC-BIO-API-120 FR-BIO-006 上传无任务 404 无 POST /api/bioflow/jobs/nope/files 404 信封 L2 P1
TC-BIO-API-121 FR-BIO-008 confirm 空参数体 阶段 waiting_confirm POST confirm {} 200;按默认参数执行 L2 P1
TC-BIO-API-122 FR-BIO-010 暂停含排队任务 任务 queued POST pause 200;队列移除且状态=paused L2 P1
TC-BIO-API-123 FR-BIO-016 报告登记含图清单 报告含 2 图 登记 doc_artifacts 行图清单字段含 2 个 fig id L2 P1
TC-BIO-API-124 FR-BIO-015 报告 HTML 单文件 任务 done 读任务目录报告文件 单 .html 文件;图以 data:image/...;base64 内嵌(无外部图文件引用) L2 P0
TC-BIO-API-125 FR-BIO-015 报告含各阶段 manifest 事实 任务 done 解析报告 HTML 含 identify 阶段输出数量等 manifest 事实数据 L2 P1
TC-BIO-API-126 FR-BIO-014 events 未知 job 404 无 GET /api/bioflow/jobs/nope/events 404 信封 L2 P1
TC-BIO-API-127 FR-BIO-011 stage_log 事件日志尾推送 阶段 running 读 events stage_log 事件 data.log 字段非空且随执行追加 L2 P0
TC-BIO-API-128 FR-BIO-014 断线期间事件不丢 任务 running;断开 5s 重连 重连读事件 断开期间产生的 stage_log 全部回放 L2 P0
TC-BIO-API-129 FR-BIO-020 存档含中间文件开关 任务 done 含中间文件 POST archives include_intermediate=true 磁盘目录含中间产物;size 更大 L2 P1
TC-BIO-API-130 FR-BIO-020 存档不含中间文件 同上 POST archives include_intermediate=false 磁盘目录不含中间产物目录 L2 P1
TC-BIO-API-131 FR-BIO-021 存档状态回复字段 存档完成 读对话消息 消息含名称/位置/大小三要素字段 L2 P0
TC-BIO-API-132 FR-BIO-023 run 后新任务入列表 POST archives/run GET jobs 新任务出现在列表(title 含 target) L2 P1
TC-BIO-API-133 FR-BIO-025 health 失败 503 服务 db 损坏(mock) GET health 503 或 200 带 db:error 字段(两态断言其一) L2 P1
TC-BIO-API-134 FR-BIO-028 生信服务独立进程 无 检查进程表 8098 进程独立于 BFF;BFF 重启后 8098 存活 L2s P0
TC-BIO-API-135 FR-BIO-028 独立 SQLite 无 检查文件 bioflow.db 存在于生信数据根;BFF 无同表 L2s P1
TC-BIO-API-136 FR-BIO-001 chat 流错误信封 mock LLM 500 读流 SSE data 含 code/msg 错误信封结构 L2 P1
TC-BIO-API-137 FR-BIO-002 plan_ready 用途字段非空 mock LLM 读 plan_ready 每条 candidate.purpose 非空 L2 P1
TC-BIO-API-138 FR-BIO-004 确认创建任务后 SSE 建库 前端确认 读事件 job_created 后 GET job 200 且状态=created L2 P0
TC-BIO-API-139 FR-BIO-031 任务失败不占并发 任务失败 创建新任务 confirm 新任务立即执行(信号量已释放) L2 P1
TC-BIO-API-140 FR-BIO-012 改参数重跑走 confirm 阶段 failed POST rerun {"params":{...}} 状态=waiting_confirm(表单再确认)或直接 running(两态断言其一) L2 P1
TC-BIO-API-141 FR-BIO-022 归档文件下载 归档 a1 GET /api/bioflow/archives/{a1}/download 200 zip/目录打包流;可解压 L2 P1
TC-BIO-API-142 FR-BIO-022 归档报告单独取 归档 a1 含报告 GET /api/bioflow/archives/{a1}/report 200;text/html 内容含 <html L2 P1
TC-BIO-API-143 FR-BIO-017 报告编辑落盘 报告已登记 PATCH 报告文字 200;磁盘 HTML 内容更新 L2 P1
TC-BIO-API-144 FR-BIO-019 revise 无绘图目标 422 报告任务 POST revise {"instruction":"不明确"} 422 或转 docgen(两态断言其一) L2 P2
TC-BIO-API-145 FR-BIO-002 chat/stream 多候选单选 3 候选 用户选第 2 条(消息或 API 选) 任务 stages=第 2 候选链 L2 P1
TC-BIO-API-146 FR-BIO-031 队列顺序 FIFO 并发满 3 任务排队 完成 1 个后先入队者先执行 L2 P1
TC-BIO-API-147 FR-BIO-010 自动连续模式接口字段 任务开启 auto_continue 读任务详情 job.auto_continue=true;阶段间跳过 confirm L2 P0
TC-BIO-API-148 FR-BIO-010 自动连续暂停停在下一阶段前 auto_continue 任务暂停 读任务 当前阶段等待且未 confirm;无跳过 L2 P1
TC-BIO-API-149 FR-BIO-004 创建任务重复 id 幂等 POST jobs 两次相同 payload 两次 产生 2 个不同 job id(或 409 二选一固定) L2 P2
TC-BIO-API-150 FR-BIO-009 confirm 参数类型校验 无 confirm {"params":{"cpu":"abc"}} 422;detail 含 cpu 类型错误 L2 P1

6.1.3 RUN runner 状态机(L1 单元,mock docker 执行)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-RUN-001 FR-BIO-031 全链成功推进 3 阶段任务 mock docker 全 0 退出 run 阶段状态依次 running→done;任务=done;事件序 stage_started/stage_done 成对 L1 P0
TC-BIO-RUN-002 FR-BIO-012 阶段失败转 failed mock docker 退出码 1 run 状态=failed;事件 stage_failed;后续阶段不执行(任务停在 failed 阶段) L1 P0
TC-BIO-RUN-003 FR-BIO-012 失败后 rerun 成功 同上 rerun attempt=2;状态 done;继续后续阶段 L1 P0
TC-BIO-RUN-004 FR-BIO-012 失败后 skip 阶段 failed skip 状态=skipped;事件 stage_skipped;后续阶段可执行 L1 P0
TC-BIO-RUN-005 FR-BIO-012 失败后改参数重跑 阶段 failed rerun_with_params {"cpu":8} 新执行命令含 cpu=8;成功 L1 P0
TC-BIO-RUN-006 FR-BIO-010 暂停在阶段边界 阶段 2 running 完成时 pause 观察 阶段 2 done 后阶段 3 不启动;任务=paused;事件 job_paused L1 P0
TC-BIO-RUN-007 FR-BIO-010 暂停后恢复续跑 任务 paused resume 从下一阶段继续;不重跑已完成 L1 P0
TC-BIO-RUN-008 FR-BIO-031 重启续跑不重跑 任务 2/5 阶段 done;模拟重启加载 DB 重启恢复 已 done 阶段 attempt 不变;从第 3 阶段续跑 L1 P0
TC-BIO-RUN-009 FR-BIO-031 重启恢复 in-flight running 阶段无完成标记;重启 恢复 该阶段按 manifest 判成败:有 manifest 且成功→done;否则重跑 L1 P0
TC-BIO-RUN-010 FR-BIO-031 并发上限排队 BIOFLOW_CONCURRENCY=3;4 任务 run 同时 running 的 docker ≤3;第 4 任务 queued L1 P0
TC-BIO-RUN-011 FR-BIO-031 并发槽释放 任务 1 完成 观察 队列头立即启动 L1 P1
TC-BIO-RUN-012 FR-BIO-029 阶段超时 mock docker 不退出;timeout=1s run 阶段=failed(reason=timeout);容器被 kill;日志含超时记录 L1 P0
TC-BIO-RUN-013 FR-BIO-031 日志截断只留尾 mock 输出 500 行 run bio_stages.log_tail 行数=80 且为末 80 行 L1 P0
TC-BIO-RUN-014 FR-BIO-029 退出码非 0 判失败 mock 退出码 3 run 状态=failed;log_tail 含 stderr L1 P0
TC-BIO-RUN-015 FR-BIO-031 退出码 0 但 manifest 缺 无 manifest 产出 run 阶段=failed(reason=no_manifest) L1 P0
TC-BIO-RUN-016 FR-BIO-029 manifest 失败标记判败 manifest status=failed run 阶段=failed(不因退出码 0 误判成功) L1 P0
TC-BIO-RUN-017 FR-BIO-005 输入缺失等待文件 阶段 input 文件不存在 run 至该阶段 状态=await_files;事件 stage_await_files;不启动 docker L1 P0
TC-BIO-RUN-018 FR-BIO-005 文件补齐自动推进 await_files 后登记文件 触发 状态转 waiting_confirm(手动)或 running(自动连续);事件 stage_started L1 P0
TC-BIO-RUN-019 FR-BIO-008 阶段前等待确认 手动模式 run 至阶段 状态=waiting_confirm;事件 stage_await_confirm;不执行 docker L1 P0
TC-BIO-RUN-020 FR-BIO-008 确认后执行 waiting_confirm confirm docker 命令以表单参数构造;状态=running L1 P0
TC-BIO-RUN-021 FR-BIO-010 自动连续跳过确认 auto_continue=true run 阶段间无 waiting_confirm;全程自动推进 L1 P0
TC-BIO-RUN-022 FR-BIO-010 自动连续可暂停 auto_continue 任务 pause 停在当前阶段边界;恢复后仍自动连续 L1 P0
TC-BIO-RUN-023 FR-BIO-031 暂停恢复重入安全 任务 paused resume 两次 第二次 resume 409/幂等无副作用 L1 P1
TC-BIO-RUN-024 FR-BIO-012 三选一状态校验 阶段 done rerun/skip 拒绝(状态机不越迁) L1 P1
TC-BIO-RUN-025 FR-BIO-031 并发信号量释放异常安全 docker 执行抛异常 观察 信号量释放;任务转 failed;服务不挂 L1 P1
TC-BIO-RUN-026 FR-BIO-031 阶段间输入传递 上游 manifest 含 artifacts 路径 run 下游 下游 docker 命令的 input 路径=上游 artifacts L1 P0
TC-BIO-RUN-027 FR-BIO-031 全部完成后归档提示事件 任务 done 观察 事件 job_done 后紧跟 archive_suggest(或前端判 done 出提示,两态断言其一) L1 P1
TC-BIO-RUN-028 FR-BIO-024 多任务互不串扰 2 任务并发 run 各自状态/参数独立;无共享状态污染 L1 P1
TC-BIO-RUN-029 FR-BIO-024 任务进度数值 3 阶段任务完成 1 读进度 progress=33(按完成阶段数/总阶段数) L1 P1
TC-BIO-RUN-030 FR-BIO-031 恢复时跳过已归档任务 已归档任务 in-flight 残留 重启 不重复执行(含 archive 状态检查) L1 P2
TC-BIO-RUN-031 FR-BIO-029 docker 失败重试策略 mock docker 偶发失败 run 按配置重试 N 次;最终 failed;attempt 数=N+1 L1 P1
TC-BIO-RUN-032 FR-BIO-005 多输入文件部分缺失 阶段需 2 文件缺 1 run await_files;事件 data 指明缺哪个文件 L1 P0
TC-BIO-RUN-033 FR-BIO-031 暂停时运行中阶段完成才停 阶段 running 且即将完成 pause 当前阶段完成→done 后任务才 paused(不杀容器) L1 P1
TC-BIO-RUN-034 FR-BIO-003 前置补全后链完整性 候选链缺前置 规划校验 补全后链包含前置;job.stages 完整 L1 P0
TC-BIO-RUN-035 FR-BIO-029 容器环境变量 BBA_* 注入 阶段执行 mock 记录命令 含 -e BBA_*(至少 BBA_PFAM_DIR/BBA_RAG_MAPPING_FILE 其一) L1 P0
TC-BIO-RUN-036 FR-BIO-029 任务目录挂载 阶段执行 mock 记录命令 含 -v {job_dir}/input:/job/input 与 -v {job_dir}/workspace:/job/workspace L1 P0
TC-BIO-RUN-037 FR-BIO-029 容器内命令形态 阶段执行 mock 记录命令 python -B -m cli.run_identify --input-dir /job/input --workspace /job/workspace(前缀两元素 python -B) L1 P0
TC-BIO-RUN-038 FR-BIO-031 阶段状态机非法迁移拒绝 任意状态 调用非法迁移 抛状态机错误/忽略(不写脏状态) L1 P1
TC-BIO-RUN-039 FR-BIO-031 runner 无阶段空任务 stages=[] run 直接 done;无 docker 调用 L1 P2
TC-BIO-RUN-040 FR-BIO-031 并发计数含 running 阶段 3 任务各 1 running 观察 计数=3;新任务排队 L1 P1
TC-BIO-RUN-041 FR-BIO-031 阶段等待确认不占并发 任务 waiting_confirm 观察 并发计数不含该任务 L1 P1
TC-BIO-RUN-042 FR-BIO-031 事件总线订阅多者广播 2 个 events 连接 run 1 阶段 两连接收到相同事件序列 L1 P1
TC-BIO-RUN-043 FR-BIO-031 心跳期无事件不空转 任务 paused 观察 CPU 无 busy-loop(等待用事件/队列阻塞) L1 P2
TC-BIO-RUN-044 FR-BIO-024 manifest 路径登记 阶段 done 读 bio_stages manifest_path 指向任务目录内真实文件 L1 P0
TC-BIO-RUN-045 FR-BIO-012 跳过事件携带阶段名 skip 读事件 stage_skipped.data.stage=阶段名 L1 P1
TC-BIO-RUN-046 FR-BIO-031 长时间任务状态可查 mock 慢执行 执行中 GET job 状态=running;无阻塞(独立线程/协程) L1 P1

6.1.4 KERN 内核执行与 manifest(L1 单元 mock 命令拼装 + L2s 真实冒烟)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-KERN-001 FR-BIO-029 docker 命令拼装基元 mock 拼装 identify 阶段命令 数组元素依次:docker,run,--rm,--user,uid,-v×3,--cpus,--memory,-e×N,镜像,python,-B,-m,cli.run_identify,参数… L1 P0
TC-BIO-KERN-002 FR-BIO-029 挂载三目录 mock 拼装 -v 含 input/workspace/BIOFLOW_DATA 三处;BIOFLOW_DATA 后带 :ro L1 P0
TC-BIO-KERN-003 FR-BIO-029 --cpus 注入 mock 拼装 含 --cpus 且值来自阶段配置 L1 P0
TC-BIO-KERN-004 FR-BIO-029 --memory 注入 mock 拼装 含 --memory 且格式如 64g L1 P0
TC-BIO-KERN-005 FR-BIO-029 环境变量拼装 mock 拼装 每项 env 输出为两个元素:-e 与 KEY=value L1 P0
TC-BIO-KERN-006 FR-BIO-029 容器命令转义安全 参数含空格 拼装 参数作为独立 argv 元素(subprocess list 传参,无 shell 注入) L1 P0
TC-BIO-KERN-007 FR-BIO-029 镜像映射查表 mock 查 align 阶段镜像 返回 bioflow-gf(stage_image_map.json) L1 P0
TC-BIO-KERN-008 FR-BIO-029 未知阶段镜像映射 mock 查未知阶段 返回 None 且执行前置拦截(不拼命令) L1 P1
TC-BIO-KERN-009 FR-BIO-029 超时 kill mock docker 超时 观察 调用 kill/terminate;阶段 failed L1 P0
TC-BIO-KERN-010 FR-BIO-030 金标 24 成员 ID 全等 bioflow-gf 镜像;金标输入 Ft.SPL 镜像内跑 identify 输出 ID 集合与 dev 预期 24 成员集合 diff 为空 L2s P0
TC-BIO-KERN-011 FR-BIO-030 金标 diff 命令空输出 同上 执行 diff 脚本 stdout 为空;脚本退出码 0 L2s P0
TC-BIO-KERN-012 FR-BIO-032 18 入口 --help 冒烟 4 镜像齐 对 18 个 cli.run_* 逐条 python -B -m cli.run_x --help 18/18 退出码 0;无 traceback L2s P0
TC-BIO-KERN-013 FR-BIO-032 镜像内 import 编译产物 bioflow-gf 镜像 python -c "import gfa_core.mas" 成功(.so 加载无 ImportError) L2s P0
TC-BIO-KERN-014 FR-BIO-030 manifest 解析成功路径 金标 manifest fixture 解析 字段齐:status/artifacts/outputs/params/耗时 L1 P0
TC-BIO-KERN-015 FR-BIO-030 manifest 缺失文件 无 manifest 文件 解析 返回错误(判失败 reason=no_manifest) L1 P0
TC-BIO-KERN-016 FR-BIO-030 manifest 非法 JSON 损坏内容 解析 返回解析错误;阶段 failed L1 P1
TC-BIO-KERN-017 FR-BIO-030 manifest status 缺失 JSON 无 status 键 解析 按退出码兜底判成败 L1 P1
TC-BIO-KERN-018 FR-BIO-030 artifacts 路径提取 manifest 含 artifacts 解析 提取为下游输入(跨阶段输入定位) L1 P0
TC-BIO-KERN-019 FR-BIO-030 路径不存在时报错 artifacts 指向缺失文件 解析 报错含具体路径(阶段失败) L1 P1
TC-BIO-KERN-020 FR-BIO-030 24 ID 去重与排序无关 金标输出乱序 比对 集合比对全等(顺序无关) L2s P1
TC-BIO-KERN-021 FR-BIO-032 4 镜像构建产物 build_all.sh 完成 检查 4 镜像 tag 均存在(docker images 可见) L2s P0
TC-BIO-KERN-022 FR-BIO-032 SHA256SUMS 产出 构建完成 检查 产物目录存在 SHA256SUMS 且含 4 条目 L2s P0
TC-BIO-KERN-023 FR-BIO-032 泄露门禁(明文凭据扫描) 构建产物 扫描 .so/明文 无 ACCESS_KEY/SECRET 类凭据命中 L2s P0
TC-BIO-KERN-024 FR-BIO-029 数据不进镜像 构建产物 检查镜像层 镜像内无金标/用户数据文件 L2s P1

6.1.5 SSE 事件流与断线回放(L1 单元帧解析 + L2 序列)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-SSE-001 FR-BIO-014 事件类型全集 mock 全链 收集事件 出现类型 ∈ {job_created, plan_ready, stage_started, stage_log, stage_done, stage_failed, stage_skipped, stage_await_confirm, stage_await_files, job_done, job_paused, job_archived} 且无未知类型 L1 P0
TC-BIO-SSE-002 FR-BIO-014 job_created 字段 创建任务 读事件 data 含 job_id/title/stages L1 P0
TC-BIO-SSE-003 FR-BIO-014 stage_started 字段 阶段启动 读事件 data 含 stage/attempt/ts L1 P0
TC-BIO-SSE-004 FR-BIO-014 stage_log 追加 阶段运行 读事件 data.log 非空;多帧顺序=日志顺序 L1 P0
TC-BIO-SSE-005 FR-BIO-014 stage_done 字段 阶段完成 读事件 data 含 stage/exit_code=0/manifest_ref L1 P0
TC-BIO-SSE-006 FR-BIO-014 stage_failed 字段 阶段失败 读事件 data 含 stage/exit_code 非 0/reason L1 P0
TC-BIO-SSE-007 FR-BIO-014 stage_skipped 字段 跳过 读事件 data 含 stage L1 P0
TC-BIO-SSE-008 FR-BIO-014 stage_await_confirm 字段 阶段待确认 读事件 data 含 stage/form_defaults(参数默认值) L1 P0
TC-BIO-SSE-009 FR-BIO-014 stage_await_files 字段 阶段待文件 读事件 data 含 stage/required_files[](含缺失文件名) L1 P0
TC-BIO-SSE-010 FR-BIO-014 job_done 收尾 任务完成 读事件 data 含 job_id/耗时;为最后事件 L1 P0
TC-BIO-SSE-011 FR-BIO-014 job_paused 字段 暂停 读事件 data 含 job_id/当前阶段 L1 P0
TC-BIO-SSE-012 FR-BIO-014 job_archived 字段 存档 读事件 data 含 archive_id L1 P1
TC-BIO-SSE-013 FR-BIO-014 seq 严格递增 mock 帧序列 解析 seq 后帧 seq=前帧 seq+1 L1 P0
TC-BIO-SSE-014 FR-BIO-014 帧解析空行容错 帧含多余空行 解析 正常解析不报错 L1 P1
TC-BIO-SSE-015 FR-BIO-014 多行 data 合并 data 分行发送 解析 事件 data 按 \n 合并 L1 P1
TC-BIO-SSE-016 FR-BIO-014 心跳注释忽略 帧含 :keepalive 解析 不产业务事件 L1 P1
TC-BIO-SSE-017 FR-BIO-014 坏帧不中断流 含未命名 data 帧 解析 跳过坏帧继续后续事件 L1 P1
TC-BIO-SSE-018 FR-BIO-014 前端 parser 兼容既有帧 既有 sse/parser.js 输出格式 解析 bioflow 帧 复用 parser 无改动可解析(红线零改动验证) L3 P0
TC-BIO-SSE-019 FR-BIO-014 事件序列全链顺序 mock 3 阶段 收集序列 相对序:job_created<plan_ready<首 stage_started<末 stage_done<job_done L2 P0
TC-BIO-SSE-020 FR-BIO-014 失败序列 mock 阶段 2 失败 收集 出现 stage_failed;无该阶段 stage_done;后续阶段无 stage_started L2 P0
TC-BIO-SSE-021 FR-BIO-014 跳过序列 mock skip 收集 stage_skipped 出现在 stage_failed 之后 L2 P0
TC-BIO-SSE-022 FR-BIO-014 断线回放快照结构 任务 3 阶段中途 重连首帧 首帧 data.type=snapshot;data.job.status 与 DB 一致;data.stages 逐阶段含 status L2 P0
TC-BIO-SSE-023 FR-BIO-014 回放补齐事件序 断开 5s 期间 2 条 stage_log 重连 快照后回放这 2 条;seq 连续 L2 P0
TC-BIO-SSE-024 FR-BIO-014 回放不重复已见事件 客户端带 last_seq 重连 重连 不重发 ≤last_seq 事件 L2 P0
TC-BIO-SSE-025 FR-BIO-014 前端重连机制 断网 30s 观察前端 自动重连(重试/退避);进度卡整体刷新 L3 P0
TC-BIO-SSE-026 FR-BIO-014 前端回放刷新进度卡 快照 1 done 1 running 1 waiting 应用快照 卡片三阶段状态与快照一致;日志尾区显示 L3 P0
TC-BIO-SSE-027 FR-BIO-014 重连失败提示 服务不可达 观察 进度卡显示断线态;有重连按钮/文案 L3 P1
TC-BIO-SSE-028 FR-BIO-014 events 与 chat/stream 事件同源 同任务 对比两流 事件类型与 seq 一致 L2 P1
TC-BIO-SSE-029 FR-BIO-014 事件延迟心跳期间无重复 job_done 任务 done 读流 job_done 仅 1 次 L2 P1
TC-BIO-SSE-030 FR-BIO-014 快照含日志尾 阶段 running 有日志 重连快照 snapshot.stages[*].log_tail 非空 L2 P0
TC-BIO-SSE-031 FR-BIO-014 Last-Event-ID 续传 断连时记录 id 重连带 Last-Event-ID 服务从该 id 后补发 L2 P1
TC-BIO-SSE-032 FR-BIO-014 前端事件更新器幂等 重复 stage_done 帧 应用两次 阶段状态仍 done;无异常 L3 P1

6.1.6 DB 三表迁移与持久化(L1)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-DB-001 FR-BIO-028 三表创建 空库 初始化 bio_jobs/bio_stages/bio_archives 三表存在;schema 含任务书字段 L1 P0
TC-BIO-DB-002 FR-BIO-028 迁移幂等 已初始化 重复跑迁移 无异常;schema_version 不变;表数不增 L1 P0
TC-BIO-DB-003 FR-BIO-028 版本升级迁移 v1 库 fixture 迁移至 v2 新列存在;旧数据保留 L1 P1
TC-BIO-DB-004 FR-BIO-028 阶段链 JSON 存取 任务 3 阶段 写入读回 stages 数组完整还原 L1 P0
TC-BIO-DB-005 FR-BIO-028 参数 JSON 存取 参数嵌套 写入读回 参数对象完整还原(含嵌套) L1 P0
TC-BIO-DB-006 FR-BIO-024 任务级联删除阶段 任务含 5 阶段 删任务 bio_stages 对应行=0 L1 P0
TC-BIO-DB-007 FR-BIO-022 归档外键任务 任务 j1 归档 删任务(若实现允许) 归档保留或级联(两态断言其一,按实现固定) L1 P1
TC-BIO-DB-008 FR-BIO-028 时间戳字段 创建任务 读行 created_at/updated_at 非空且 ISO 格式 L1 P1
TC-BIO-DB-009 FR-BIO-028 状态枚举约束 写入 写非法状态值 拒绝或枚举约束错误 L1 P1
TC-BIO-DB-010 FR-BIO-031 并发写安全 2 协程更新同任务 并发写 无死锁;最终状态一致 L1 P1
TC-BIO-DB-011 FR-BIO-024 log_tail 持久化 阶段运行 更新 log_tail 读回与内存一致 L1 P0
TC-BIO-DB-012 FR-BIO-021 归档大小与路径字段 存档 读 bio_archives 行 size_bytes>0;disk_path 非空且目录存在 L1 P0

6.1.7 FLOW 上下游集成(接口级)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-FLOW-001 FR-BIO-028 BFF 反代开启注册 BIOFLOW_ENABLED=true 启动 BFF 检查路由表 /api/bioflow/* 路由已注册(FastAPI routes 可见) L2 P0
TC-BIO-FLOW-002 FR-BIO-028 BFF 反代关闭不注册 BIOFLOW_ENABLED=false 检查路由表 无 /api/bioflow/* 路由 L2 P0
TC-BIO-FLOW-003 FR-BIO-016 报告登记进 doc_artifacts 生信任务 done 登记 doc_artifacts 新行;kind=bioflow_report 或等价字段 L2 P0
TC-BIO-FLOW-004 FR-BIO-016 报告登记字段对齐 登记 读行 job_id/标题/md/图清单与 docgen 表字段对齐(缺字段报错) L2 P0
TC-BIO-FLOW-005 FR-BIO-015 fig:// 图引用渲染 报告含 fig://fig1 渲染报告 img src 变为 data:image/...base64;无 fig:// 残留 L3 P0
TC-BIO-FLOW-006 FR-BIO-015 fig:// 未知 id 降级 fig://nope 渲染 图位置显示占位/跳过且不报错 L3 P1
TC-BIO-FLOW-007 FR-BIO-016 DocPane 白底预览 报告登记 打开 DocPane 容器 computed background=#FFFFFF(白底);图文正常 L4 P0
TC-BIO-FLOW-008 FR-BIO-019 revise 触发预览刷新 图表调整后 观察 DocPane 预览重新加载;新图可见 L3 P0
TC-BIO-FLOW-009 FR-BIO-026 vstore flow_docs 检索 flow_docs 集合已入库 检索「identify 需要什么输入」 返回块含源文件+章节;top1 相关 L2 P0
TC-BIO-FLOW-010 FR-BIO-023 存档复用端到端接口链 归档 a1 POST archives/{a1}/run 新任务→表单预填→confirm→执行,参数=归档值(全链) L2 P0

6.1.8 STORE 前端 store(L3 vitest)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-STORE-001 FR-BIO-001 sendBioflow 动作存在 store 挂载 调用 sendBioflow(msg) 消息进入 messages 数组且 blocks 含 bioflow 类块 L3 P0
TC-BIO-STORE-002 FR-BIO-001 分流未命中不触发生信 mock 词典 发送「什么是基因家族」 走原 send() 路径;不产生 bioflow 请求 L3 P0
TC-BIO-STORE-003 FR-BIO-002 候选路径写入消息 mock plan_ready 应用事件 消息 blocks 含 path 块且 candidates.length 2~3 L3 P0
TC-BIO-STORE-004 FR-BIO-004 确认后创建任务状态 mock job_created 应用事件 bioflowJob 状态写入 store(jobId 非空) L3 P0
TC-BIO-STORE-005 FR-BIO-011 阶段状态更新 mock stage 事件序列 逐帧应用 store 中阶段状态 waiting→running→done 逐帧一致 L3 P0
TC-BIO-STORE-006 FR-BIO-012 失败事件置 failed mock stage_failed 应用 store 阶段 status=failed 且 error 文案存在 L3 P0
TC-BIO-STORE-007 FR-BIO-011 日志尾追加 mock stage_log×3 应用 store logTail 追加为整体,长度=三帧之和 L3 P0
TC-BIO-STORE-008 FR-BIO-014 快照整体替换 mock snapshot 应用 store 阶段数组被快照整体替换(引用变化) L3 P0
TC-BIO-STORE-009 FR-BIO-014 断线重连触发 SSE 断开(mock) 等待 store 触发 reconnect;成功后应用快照 L3 P0
TC-BIO-STORE-010 FR-BIO-006 上传进度状态 mock XHR 进度 45% 上传 store uploadProgress=45 L3 P0
TC-BIO-STORE-011 FR-BIO-009 表单值提交 mock dispatch confirmStage(stage, params) 请求体 params 与表单一致 L3 P0
TC-BIO-STORE-012 FR-BIO-010 自动连续开关状态 mock 切换 autoContinue store.autoContinue=true 且随任务持久化字段下发 L3 P0
TC-BIO-STORE-013 FR-BIO-010 暂停/恢复动作 mock dispatch pauseJob/resumeJob store 状态 paused/running;发出对应 POST L3 P0
TC-BIO-STORE-014 FR-BIO-012 三选一动作 mock dispatch rerunStage/skipStage/rerunWithParams 分别发出 rerun/skip/rerun 请求;请求体正确 L3 P0
TC-BIO-STORE-015 FR-BIO-023 存档复用预填 mock archive_loaded 应用 store.formDefaults=存档参数;来源标记=archive L3 P0
TC-BIO-STORE-016 FR-BIO-025 探活结果 mock health 200/500 初始化 200→bioflowAvailable=true;500/超时→false L3 P0
TC-BIO-STORE-017 FR-BIO-021 存档状态回复写入 mock archive_done 应用 消息块含名称/位置/大小三字段 L3 P0
TC-BIO-STORE-018 FR-BIO-024 面板任务列表 mock jobs loadJobs store.jobs 数组与接口一致(排序) L3 P0
TC-BIO-STORE-019 FR-BIO-022 档案列表 mock archives loadArchives store.archives 数组与接口一致 L3 P0
TC-BIO-STORE-020 FR-BIO-014 事件乱序容错 mock 乱序帧 应用 不崩溃;状态不回退(done 不再变 running) L3 P1
TC-BIO-STORE-021 FR-BIO-014 会话切换隔离 2 会话各 1 任务 切换 store 当前任务随会话切换;互不污染 L3 P1
TC-BIO-STORE-022 FR-BIO-001 红线文件零改动校验 仓库 checkout 状态 对比 modes.js/labels.js/bench.js/qa.js/parser.js 与分支基线一致(无 diff) L3 P0

6.1.9 PATH 路径选择卡(flow-path-card,L4)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-PATH-001 FR-BIO-002 引导 UI 显示:卡片标题 mock 候选 2 条 挂载 标题文本=「🧬 分析路径选择」;卡体有 .flow-path-card 类 L4 P0
TC-BIO-PATH-002 FR-BIO-002 引导操作:候选行渲染 2-3 条候选 挂载 渲染 2-3 个候选行;每行含阶段序列文本(首阶段加粗)与用途文本 L4 P0
TC-BIO-PATH-003 FR-BIO-002 候选行阶段序列显示 候选 [identify,align,phylogeny] 挂载 行文本含「identify → align → phylogeny」;首阶段字重 600 L4 P0
TC-BIO-PATH-004 FR-BIO-002 引导操作:点选候选行 未选中 点击第 2 行 该行获得选中态(border 1.5px --pa-g-from;背景=gradient 8% 混色) L4 P0
TC-BIO-PATH-005 FR-BIO-002 引导 UI 显示:选中态边框 已选中 检查 computed style border-width=1.5px 且 border-color=var(--pa-g-from) L4 P0
TC-BIO-PATH-006 FR-BIO-002 确认按钮选中后可点 已选中 检查「确认此路径」按钮 disabled=false;背景为 --pa-gradient;文字白色 12.5px/600 L4 P0
TC-BIO-PATH-007 FR-BIO-002 确认按钮无选中禁用 未选中 检查 disabled=true;opacity=0.45 L4 P0
TC-BIO-PATH-008 FR-BIO-002 引导操作:确认发出选择 已选中候选 2 点击确认 触发 select 回调/请求,参数=候选 2 的 stages L4 P0
TC-BIO-PATH-009 FR-BIO-002 自然语言改选 候选 3 条 用户输入「换第二条」 回调携带选中索引 2(或经 LLM 解析) L4 P1
TC-BIO-PATH-010 FR-BIO-002 空候选不渲染 candidates=[] 挂载 卡体不渲染(或空态文案);不报错 L4 P1
TC-BIO-PATH-011 FR-BIO-002 单候选自动不强制 candidates=1 挂载 渲染 1 行;确认仍可用 L4 P2
TC-BIO-PATH-012 FR-BIO-003 前置补全明示 候选含 auto_filled 挂载 行内或提示区显示「已自动补全」标记与前置阶段名 L4 P0
TC-BIO-PATH-013 FR-BIO-004 确认卡逐阶段可读 path 确认态 挂载确认视图 逐阶段显示名称/用途/预计耗时三要素 L4 P0
TC-BIO-PATH-014 FR-BIO-004 确认后任务创建请求 确认卡 点击确认 发出 POST /api/bioflow/jobs;body.stages=选中链 L4 P0
TC-BIO-PATH-015 FR-BIO-002 路径卡主题令牌 深/浅主题 检查 computed 背景=surface-1;边框=hairline;圆角=r-lg L4 P1
TC-BIO-PATH-016 FR-BIO-002 移动端不溢出 390×844 挂载 卡片宽≤容器宽;无横向滚动 L5-M P1
TC-BIO-PATH-017 FR-BIO-004 阶段链超长显示 15 阶段候选 挂载 行内序列文本可换行/省略;行不撑破卡片 L4 P2
TC-BIO-PATH-018 FR-BIO-002 用途文本渲染 candidate.purpose 挂载 每行显示用途文本(非空) L4 P1
TC-BIO-PATH-019 FR-BIO-002 卡体尺寸 挂载 检查 computed padding=14px 16px;margin=14px 0 L4 P2
TC-BIO-PATH-020 FR-BIO-002 行 hover 态 未选中 hover 候选行 背景=surface-3(--pa-s3) L4 P1
TC-BIO-PATH-021 FR-BIO-002 键盘 Enter 确认 已选中;确认按钮聚焦 按 Enter 触发确认回调(同点击) L4 P1
TC-BIO-PATH-022 FR-BIO-002 选中后再点同行走自然语言修改 已选中行 1 再次点击行 1 无选中态抖动;回调幂等(保持选中) L4 P2

6.1.10 FORM 参数表单卡(flow-form-card,L4)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-FORM-001 FR-BIO-008 引导 UI 显示:表单卡标题 阶段 identify 待确认 挂载 标题=「⚙ identify 步骤 · 可调整参数」;.flow-form-card 存在 L4 P0
TC-BIO-FORM-002 FR-BIO-008 引导 UI 显示:前置文案 同上 挂载 对话区显示「XXXX 步骤,可调整参数如下,可按需调整,调整完毕后继续」文案 L4 P0
TC-BIO-FORM-003 FR-BIO-008 引导操作:字段渲染 参数 schema 3 字段 挂载 渲染 3 个字段行:label 12px ink-muted、宽 96px;input 存在 L4 P0
TC-BIO-FORM-004 FR-BIO-008 默认值显示 默认 cpu=4 挂载 input value=4 L4 P0
TC-BIO-FORM-005 FR-BIO-008 引导 UI 显示:来源标注 字段含 source 挂载 每字段下方 11px ink-subtle 文案含「默认值来源:阶段契约文档」 L4 P0
TC-BIO-FORM-006 FR-BIO-008 来源标注多类型 来源=参数预填值 挂载 标注文案区分「契约文档」与「参数预填」两来源 L4 P1
TC-BIO-FORM-007 FR-BIO-009 引导操作:编辑参数 input cpu 输入 8 v-model 值=8;无校验拦截 L4 P0
TC-BIO-FORM-008 FR-BIO-009 继续按钮执行 已改 cpu=8 点击「继续」 发出 confirm 请求 body.params.cpu=8 L4 P0
TC-BIO-FORM-009 FR-BIO-009 继续按钮样式 挂载 检查 「继续」--pa-gradient 白字 12.5px/600;r-md;padding 7px 16px L4 P1
TC-BIO-FORM-010 FR-BIO-010 自动连续开关存在 挂载 检查 「自动连续执行」标签 12px ink-muted + switch(mode-pill 同款) L4 P0
TC-BIO-FORM-011 FR-BIO-010 引导操作:开启自动连续 开关关 点击开关 switch 状态=开;随表单提交 auto_continue=true;后续阶段不再出表单卡 L4 P0
TC-BIO-FORM-012 FR-BIO-010 自动连续可关闭 开关开 点击 状态=关;切回手动(下一阶段仍出表单) L4 P0
TC-BIO-FORM-013 FR-BIO-008 input 聚焦态 未聚焦 聚焦 input border-color=var(--pa-g-from)(focus 态) L4 P1
TC-BIO-FORM-014 FR-BIO-008 数字参数类型校验 cpu 字段 输入非数字「abc」 提交被拦截/请求不发出;显示类型错误提示 L4 P0
TC-BIO-FORM-015 FR-BIO-008 必填参数空值 必填字段清空 点继续 不发出请求;该字段标错 L4 P1
TC-BIO-FORM-016 FR-BIO-008 范围校验 字段 min=1 max=64 输入 999 校验提示(1-64);不提交 L4 P1
TC-BIO-FORM-017 FR-BIO-008 可选参数留空 可选字段 留空提交 请求体不含该字段(或 null);后端按默认 L4 P1
TC-BIO-FORM-018 FR-BIO-009 提交中继续按钮禁用 mock 慢响应 点击继续 按钮 disabled+加载中态(spinner);不重复提交 L4 P0
TC-BIO-FORM-019 FR-BIO-009 提交失败可重试 mock confirm 500 点击继续 显示错误;按钮恢复可点;可再次提交 L4 P1
TC-BIO-FORM-020 FR-BIO-023 复用预填显示 归档预填 cpu=16 标注来源=存档 挂载 input=16;来源标注=存档名称 L4 P0
TC-BIO-FORM-021 FR-BIO-008 多阶段表单逐阶段出现 手动模式 3 阶段 推进 每阶段执行前都渲染该阶段表单(标题阶段名更新) L4 P0
TC-BIO-FORM-022 FR-BIO-008 表单关闭时机 阶段已 running 事件应用 表单卡消失/折叠(不再可编辑) L4 P1
TC-BIO-FORM-023 FR-BIO-008 键盘 Enter 提交 input 聚焦 按 Enter 触发继续(同点击) L4 P1
TC-BIO-FORM-024 FR-BIO-008 Esc 放弃编辑 已改未提交 按 Esc 恢复默认值(或提示放弃,两态断言其一) L4 P2

6.1.11 FILE 文件引导卡(flow-file-card,L4)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-FILE-001 FR-BIO-005 引导 UI 显示:缺失提示文案 阶段 await_files 挂载 对话出现「请将 xxx 数据文件拖入窗口上传至服务器,或在聊天窗口中指定数据文件的具体路径」文案且点名 xxx 文件名 L4 P0
TC-BIO-FILE-002 FR-BIO-005 引导 UI 显示:文件引导卡 同上 挂载 .flow-file-card 存在;内含拖放区与路径输入行 L4 P0
TC-BIO-FILE-003 FR-BIO-006 引导操作:拖拽上传 本地测试文件 拖入拖放区 发出 POST /api/bioflow/jobs/{id}/files(multipart);文件名正确 L4 P0
TC-BIO-FILE-004 FR-BIO-006 XHR 进度百分比 mock XHR 分片 上传 进度条 fill 宽度变化且旁注百分比 11px mono(如 45%)逐级上升至 100% L4 P0
TC-BIO-FILE-005 FR-BIO-006 进度条令牌复用 上传中 检查类名 使用 prog-track/prog-fill(track surface-2 r-pill 高 4px;fill --pa-gradient) L4 P1
TC-BIO-FILE-006 FR-BIO-006 点击上传 未拖入 点击拖放区 打开文件选择框;选择后上传 L4 P0
TC-BIO-FILE-007 FR-BIO-006 大文件不断流 456MB fixture(L5 mock) 上传 进度连续更新至 100%;无超时错误 L5-D P0
TC-BIO-FILE-008 FR-BIO-007 路径输入行存在 挂载 检查 input(同 8.2 规格)+「登记路径」pane-btn 同款按钮 L4 P0
TC-BIO-FILE-009 FR-BIO-007 引导操作:登记合法路径 输入合法服务器路径 点「登记路径」 发出 POST files {"server_path":路径};成功后显示登记项(含路径与状态) L4 P0
TC-BIO-FILE-010 FR-BIO-007 非法路径报错 输入 /nonexistent 登记 显示后端 400 错误文案(PATH_NOT_EXIST) L4 P0
TC-BIO-FILE-011 FR-BIO-006 上传成功状态 上传完成 观察 进度 100%;文件登记入列表(name/size 显示) L4 P0
TC-BIO-FILE-012 FR-BIO-006 上传失败可重试 mock 500 上传 错误文案显示;拖放区可再次上传 L4 P1
TC-BIO-FILE-013 FR-BIO-006 上传中拖放区禁用重复 上传进行中 再拖入 忽略/禁用(不发起第二个上传) L4 P1
TC-BIO-FILE-014 FR-BIO-006 文件满足后卡收起 阶段转 running 观察 文件卡消失或标记已完成 L4 P1
TC-BIO-FILE-015 FR-BIO-005 缺多文件点名列表 缺 fasta+cds 挂载 提示列出两个文件名 L4 P1
TC-BIO-FILE-016 FR-BIO-006 拖放区视觉规格 挂载 检查 computed border 2px dashed --pa-hairline-strong;r-lg;padding 24px;提示 12px ink-subtle 居中 L4 P1
TC-BIO-FILE-017 FR-BIO-006 拖入态高亮 拖入悬停 检查 border-color=gradient 45% 混色;背景=gradient 8% 混色 L4 P0
TC-BIO-FILE-018 FR-BIO-006 移动端触控上传 390×844 触摸 点击/长按上传 文件选择可用(触控目标≥44px) L5-M P1
TC-BIO-FILE-019 FR-BIO-007 路径输入聚焦态 未聚焦 聚焦 border=--pa-g-from L4 P2
TC-BIO-FILE-020 FR-BIO-007 路径输入 Enter 提交 输入合法路径 按 Enter 同点「登记路径」 L4 P1
TC-BIO-FILE-021 FR-BIO-006 类型不符文件 选择 .exe 上传 前端拦截或后端 422 文案显示 L4 P1
TC-BIO-FILE-022 FR-BIO-006 空文件提示 0 字节 上传 按实现断言:提示空文件或成功后 size=0 显示 L4 P2

6.1.12 PROG 阶段进度卡(bioflow-progress-card,L4)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-PROG-001 FR-BIO-011 引导 UI 显示:进度卡渲染 阶段链确定 挂载 .bioflow-progress-card 存在;复用 pipeline-card 结构(状态点/连接线/相位色令牌) L4 P0
TC-BIO-PROG-002 FR-BIO-011 引导操作:逐阶段点亮 3 阶段推进 应用事件 状态点顺序变化:done=--pa-t-done 底白 ✓;running=相位色底●+pulse;waiting=surface-3 底◌ L4 P0
TC-BIO-PROG-003 FR-BIO-011 引导 UI 显示:日志尾区 阶段 running 观察 仅 running/failed 阶段展开日志区:--pa-code-bg 底、mono 11px、padding 8px 10px、max-height 96px 滚动 L4 P0
TC-BIO-PROG-004 FR-BIO-011 日志尾随 SSE 追加 stage_log×3 应用 日志文本追加增长;滚动至底部 L4 P0
TC-BIO-PROG-005 FR-BIO-011 done 阶段日志收起 阶段 done 观察 该阶段日志区不展开(仅 running/failed 展开) L4 P1
TC-BIO-PROG-006 FR-BIO-012 失败标红 阶段 failed 观察 状态点=--pa-error 底 ✕;状态文字 error 色 12px/600 L4 P0
TC-BIO-PROG-007 FR-BIO-012 失败三选一按钮出现 阶段 failed 观察 重跑/跳过/改参数重跑三按钮(pane-btn 同款 12px,gap 8px)仅 failed 阶段显示 L4 P0
TC-BIO-PROG-008 FR-BIO-012 重跑生效 failed 点重跑 发出 rerun 请求;状态点转 running L4 P0
TC-BIO-PROG-009 FR-BIO-012 跳过生效 failed 点跳过 发出 skip 请求;状态=skipped(--pa-ink-subtle 底◌;文字 ink-subtle) L4 P0
TC-BIO-PROG-010 FR-BIO-012 改参数重跑生效 failed 点改参数重跑 出现参数表单(该阶段);提交后重跑 L4 P0
TC-BIO-PROG-011 FR-BIO-012 skipped 态视觉 阶段 skipped 检查 状态点=--pa-ink-subtle 底◌;文字 ink-subtle L4 P1
TC-BIO-PROG-012 FR-BIO-013 折叠分组 15 阶段链 挂载 阶段>10 自动分组折叠;组头 12px/600+展开箭头;默认展开运行中所在组 L4 P0
TC-BIO-PROG-013 FR-BIO-013 展开可见全部 折叠组 点组头 展开显示该组全部阶段 L4 P0
TC-BIO-PROG-014 FR-BIO-013 ≤10 阶段不折叠 10 阶段 挂载 无折叠组头(平铺 10 状态点) L4 P1
TC-BIO-PROG-015 FR-BIO-014 断线回放刷新进度卡 快照到达 应用 卡片整体刷新为快照状态(1 done 1 running 1 waiting 精确对应) L4 P0
TC-BIO-PROG-016 FR-BIO-014 回放后日志尾恢复 快照含 log_tail 应用 running 阶段日志区显示快照日志尾 L4 P1
TC-BIO-PROG-017 FR-BIO-010 暂停态视觉 任务 paused 观察 运行中状态点停止 pulse;显示「已暂停」徽章/文案 L4 P0
TC-BIO-PROG-018 FR-BIO-010 恢复后继续 任务 paused 点恢复 下一阶段启动(running 状态推进) L4 P0
TC-BIO-PROG-019 FR-BIO-011 进度卡与流水线卡同款视觉 对比 PipelineCard 检查 结构/状态点/连接线/相位色与 §4.4 pipeline-card 令牌一致(同款) L4 P1
TC-BIO-PROG-020 FR-BIO-012 失败后后续阶段 waiting 阶段 2 failed 观察 阶段 3+ 保持 waiting 不高亮 L4 P1
TC-BIO-PROG-021 FR-BIO-024 任务面板进度视图复用 面板内 观察 面板 DAG 与进度卡状态一致 L4 P1
TC-BIO-PROG-022 FR-BIO-012 三选一按钮键盘可达 failed Tab 至重跑按钮按 Enter 触发重跑 L4 P1
TC-BIO-PROG-023 FR-BIO-011 日志尾 max-height 滚动 日志 >6 行 检查 computed max-height=96px;overflow-y=auto L4 P2
TC-BIO-PROG-024 FR-BIO-011 移动端不溢出 390×844 挂载 卡片/日志区宽度≤容器;无横向滚动 L5-M P1

6.1.13 ARCH 存档提示卡(flow-archive-card,L4)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-ARCH-001 FR-BIO-020 引导 UI 显示:存档提示 任务 job_done 观察 对话出现「本次生信任务已完成,是否存档?可按你的要求命名并描述」12.5px L4 P0
TC-BIO-ARCH-002 FR-BIO-020 引导操作:命名输入 提示卡存在 输入名称 input 接受文本;无长度异常 L4 P0
TC-BIO-ARCH-003 FR-BIO-020 引导操作:描述输入 同上 输入描述 描述值随提交发送 L4 P0
TC-BIO-ARCH-004 FR-BIO-020 引导操作:点存档 已命名 点「存档」 发出 POST /api/bioflow/archives;body 含 job_id/name/description L4 P0
TC-BIO-ARCH-005 FR-BIO-020 存档按钮样式 挂载 检查 「存档」--pa-gradient 12.5px/600;「放弃」pane-btn 同款 12px L4 P1
TC-BIO-ARCH-006 FR-BIO-020 引导操作:放弃 提示卡存在 点「放弃」 卡片消失;无 POST /api/bioflow/archives 请求;任务无副作用 L4 P0
TC-BIO-ARCH-007 FR-BIO-021 引导 UI 显示:存档状态回复 存档完成事件 观察 消息显示存档状态:名称/位置/大小三要素 L4 P0
TC-BIO-ARCH-008 FR-BIO-021 名称缺省提交拦截 名称空 点存档 按钮禁用或提交被拦截(不发出空 name 请求) L4 P1
TC-BIO-ARCH-009 FR-BIO-021 存档中加载态 mock 慢 点存档 「存档」按钮 disabled+spinner;完成后恢复 L4 P1
TC-BIO-ARCH-010 FR-BIO-021 存档失败提示 mock 500 点存档 错误文案;按钮恢复可重试 L4 P1
TC-BIO-ARCH-011 FR-BIO-020 放弃后不重复提示 已放弃 观察 同一任务不再弹存档提示(或仅一次) L4 P2
TC-BIO-ARCH-012 FR-BIO-020 任务未完成无提示 任务 running 观察 无存档提示卡 L4 P1

6.1.14 JOB 生信任务面板(biojobs-pane,L4)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-JOB-001 FR-BIO-024 面板容器与 TAB 服务可达 打开 .biojobs-pane 存在;TAB 走 bench-tab 样式 L4 P0
TC-BIO-JOB-002 FR-BIO-024 任务列表渲染 3 任务 打开 3 个 session-item 形态列表项:标题 13px+状态徽章 L4 P0
TC-BIO-JOB-003 FR-BIO-024 多任务浏览流畅 25 任务 滚动列表 列表渲染流畅(虚拟滚动或分页);无卡顿崩溃 L5-D P1
TC-BIO-JOB-004 FR-BIO-024 阶段 DAG 渲染 选中任务 查看 纵向 2px hairline 连接线;节点 8px 圆点按阶段状态取色 L4 P0
TC-BIO-JOB-005 FR-BIO-024 DAG 状态取色 1 done 1 failed 1 running 查看 三节点颜色分别=done/error/相位色 L4 P1
TC-BIO-JOB-006 FR-BIO-024 manifest/日志浏览 阶段 done 打开 code-block 渲染(mono 12px,code-bg,滚动);manifest 与日志尾均可读 L4 P0
TC-BIO-JOB-007 FR-BIO-024 重跑按钮 任务 failed 点重跑 发出 rerun 请求;面板状态更新 L4 P0
TC-BIO-JOB-008 FR-BIO-024 删除任务 任务存在 点删除+确认 发出 DELETE;列表移除 L4 P1
TC-BIO-JOB-009 FR-BIO-024 运行中删除禁用 任务 running 检查 删除按钮禁用(409 预期) L4 P1
TC-BIO-JOB-010 FR-BIO-024 空任务列表 无任务 打开 空态文案显示 L4 P2
TC-BIO-JOB-011 FR-BIO-024 任务详情实时更新 任务 running 观察 面板状态随 SSE 事件实时刷新 L4 P0
TC-BIO-JOB-012 FR-BIO-025 探活失败隐藏 TAB health 不可达 初始化 「生信任务」TAB 不渲染 L4 P0
TC-BIO-JOB-013 FR-BIO-025 探活恢复显示 TAB health 恢复 刷新 TAB 出现 L4 P0
TC-BIO-JOB-014 FR-BIO-024 移动端 TAB 条接入 390×844 打开 生信 TAB 出现在移动端 tab 条;TAB 数断言更新 L5-M P1
TC-BIO-JOB-015 FR-BIO-024 进度数字显示 任务 33% 查看 列表/详情显示进度 33% L4 P1
TC-BIO-JOB-016 FR-BIO-024 日志尾 80 行上限显示 日志 200 行 查看 面板显示 80 行(后端截断后原样展示) L4 P1

6.1.15 PANE 生信档案面板(bioarchive-pane,L4)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-PANE-001 FR-BIO-022 面板容器与 TAB 服务可达 打开 .bioarchive-pane 存在;TAB 走 bench-tab L4 P0
TC-BIO-PANE-002 FR-BIO-022 档案列表 3 归档 打开 3 个列表项(标题+状态徽章/时间)按时间倒序 L4 P0
TC-BIO-PANE-003 FR-BIO-022 档案详情回看 选中归档 点开 显示详情:阶段链/参数/产物文件清单/报告 L4 P0
TC-BIO-PANE-004 FR-BIO-022 报告产物查看 归档含报告 详情内 报告可预览(HTML 渲染或打开) L4 P0
TC-BIO-PANE-005 FR-BIO-022 中间文件清单 归档含中间文件 详情 产物清单含中间文件条目 L4 P1
TC-BIO-PANE-006 FR-BIO-022 删除归档 选中归档 点删除+确认 发出 DELETE;列表移除;磁盘目录删除 L4 P0
TC-BIO-PANE-007 FR-BIO-022 删除二次确认 归档存在 点删除→取消 无 DELETE 请求 L4 P1
TC-BIO-PANE-008 FR-BIO-023 复用发起按钮 选中归档 点「复用发起」 发出 POST archives/{id}/run 或打开复用表单 L4 P0
TC-BIO-PANE-009 FR-BIO-023 复用预填表单 复用发起后 观察 参数表单出现且预填=存档参数 L4 P0
TC-BIO-PANE-010 FR-BIO-023 复用发起新任务 预填确认 确认 新任务出现在生信任务面板 L4 P0
TC-BIO-PANE-011 FR-BIO-022 空档案列表 无归档 打开 空态文案显示 L4 P2
TC-BIO-PANE-012 FR-BIO-022 归档大小显示 归档 1.2GB 列表 大小显示(人类可读格式) L4 P2
TC-BIO-PANE-013 FR-BIO-025 探活失败隐藏档案 TAB health 不可达 初始化 「生信档案」TAB 不渲染 L4 P0
TC-BIO-PANE-014 FR-BIO-025 探活恢复显示档案 TAB health 恢复 刷新 TAB 出现 L4 P0
TC-BIO-PANE-015 FR-BIO-022 移动端面板可切换 390×844 切到档案 TAB 面板正常显示;列表可滚动 L5-M P1
TC-BIO-PANE-016 FR-BIO-023 复用按钮键盘可达 选中归档 Tab+Enter 触发复用发起 L4 P2

6.1.16 ACT UI 动作矩阵(每条 TC = 一个可交互元素 × 一个动作;TEST_PLAN §10.3)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-ACT-001 FR-BIO-002 路径卡候选行·点击 候选 2 条 点击候选行 选中态样式生效(border/背景变化);回调参数=该行索引 L4 P0
TC-BIO-ACT-002 FR-BIO-002 路径卡候选行·双击 未选中 双击候选行 视为两次点击:状态保持选中;不产生重复回调 L4 P1
TC-BIO-ACT-003 FR-BIO-002 路径卡候选行·悬停 未选中 hover 行 背景=surface-3 L4 P0
TC-BIO-ACT-004 FR-BIO-002 路径卡候选行·悬停移出 悬停中 mouseleave 背景恢复 surface-1;选中态不丢 L4 P1
TC-BIO-ACT-005 FR-BIO-002 路径卡候选行·键盘 Enter 行聚焦 按 Enter 选中该行(同点击) L4 P0
TC-BIO-ACT-006 FR-BIO-002 路径卡候选行·键盘 Esc 弹层/聚焦态 按 Esc 关闭弹层或取消聚焦,不改变已确认状态 L4 P2
TC-BIO-ACT-007 FR-BIO-002 确认按钮·点击 已选中 点击 触发确认回调一次 L4 P0
TC-BIO-ACT-008 FR-BIO-002 确认按钮·双击 已选中 双击 只触发一次回调(防抖) L4 P1
TC-BIO-ACT-009 FR-BIO-002 确认按钮·悬停 未选中 hover 视觉反馈(渐变增亮);功能仍禁用 L4 P2
TC-BIO-ACT-010 FR-BIO-002 确认按钮·键盘 Enter 按钮聚焦且已选中 按 Enter 触发确认 L4 P0
TC-BIO-ACT-011 FR-BIO-002 确认按钮·键盘 Esc 按钮聚焦 按 Esc 取消聚焦;无确认 L4 P2
TC-BIO-ACT-012 FR-BIO-002 确认按钮·禁用态 未选中 检查 disabled;opacity=0.45;点击无回调 L4 P0
TC-BIO-ACT-013 FR-BIO-002 确认按钮·加载中态 确认请求中(mock 慢) 检查 disabled;spinner 显示;再次点击无重复请求 L4 P0
TC-BIO-ACT-014 FR-BIO-008 表单输入框·点击聚焦 input 点击 input 获得焦点;focus border=--pa-g-from L4 P0
TC-BIO-ACT-015 FR-BIO-008 表单输入框·失焦 聚焦中 点击别处 blur 触发;边框恢复;若有校验立即提示 L4 P0
TC-BIO-ACT-016 FR-BIO-008 表单输入框·键盘 Enter input 聚焦 按 Enter 触发继续(提交) L4 P0
TC-BIO-ACT-017 FR-BIO-008 表单输入框·键盘 Esc input 聚焦已改 按 Esc 撤销本次编辑恢复原值或放弃(两态断言其一) L4 P1
TC-BIO-ACT-018 FR-BIO-008 表单输入框·禁用态 阶段已 running 检查 input disabled L4 P0
TC-BIO-ACT-019 FR-BIO-008 表单输入框·悬停 未聚焦 hover 边框 hairline 不变(仅 focus 变渐变) L4 P2
TC-BIO-ACT-020 FR-BIO-009 继续按钮·点击 已编辑 点击 发出 confirm;参数=表单值 L4 P0
TC-BIO-ACT-021 FR-BIO-009 继续按钮·双击 可提交 双击 仅一次请求(提交中禁用) L4 P1
TC-BIO-ACT-022 FR-BIO-009 继续按钮·悬停 可提交 hover 渐变增亮反馈 L4 P2
TC-BIO-ACT-023 FR-BIO-009 继续按钮·键盘 Enter 按钮聚焦 按 Enter 提交 L4 P0
TC-BIO-ACT-024 FR-BIO-009 继续按钮·键盘 Esc 按钮聚焦 按 Esc 取消聚焦;不提交 L4 P2
TC-BIO-ACT-025 FR-BIO-009 继续按钮·禁用态 校验不通过 检查 disabled;点击无请求 L4 P0
TC-BIO-ACT-026 FR-BIO-009 继续按钮·加载中态 提交中 检查 disabled+spinner L4 P0
TC-BIO-ACT-027 FR-BIO-010 自动连续开关·点击开 开关关 点击 switch 状态=开;auto_continue=true 提交 L4 P0
TC-BIO-ACT-028 FR-BIO-010 自动连续开关·点击关 开关开 点击 状态=关;切回手动 L4 P0
TC-BIO-ACT-029 FR-BIO-010 自动连续开关·双击 关 双击 最终状态=开(两次切换);无异常 L4 P2
TC-BIO-ACT-030 FR-BIO-010 自动连续开关·悬停 任意 hover 光标指针/背景反馈;不切换状态 L4 P2
TC-BIO-ACT-031 FR-BIO-010 自动连续开关·键盘 Enter 开关聚焦 按 Enter 切换状态 L4 P1
TC-BIO-ACT-032 FR-BIO-010 自动连续开关·键盘 Esc 开关聚焦 按 Esc 取消聚焦;状态不变 L4 P2
TC-BIO-ACT-033 FR-BIO-010 自动连续开关·禁用态 任务已暂停/未开始 检查 disabled(按实现两态断言其一) L4 P1
TC-BIO-ACT-034 FR-BIO-006 拖放区·点击 未选择 点击 打开文件选择框(file input 触发) L4 P0
TC-BIO-ACT-035 FR-BIO-006 拖放区·悬停 未拖入 hover 样式不变(非拖入态) L4 P1
TC-BIO-ACT-036 FR-BIO-006 拖放区·拖入悬停 拖拽悬停中 dragover 拖入态:border=gradient 45%;背景=gradient 8% L4 P0
TC-BIO-ACT-037 FR-BIO-006 拖放区·离开 拖入中 dragleave 拖入态移除,恢复 dashed hairline-strong L4 P0
TC-BIO-ACT-038 FR-BIO-006 拖放区·拖入释放 拖入文件 drop 触发上传(POST multipart);进度出现 L4 P0
TC-BIO-ACT-039 FR-BIO-006 拖放区·禁用态 上传进行中 检查 再拖入不触发(忽略/禁用) L4 P0
TC-BIO-ACT-040 FR-BIO-006 拖放区·加载中态 上传中 检查 进度条可见;拖放区提示变化(百分比) L4 P0
TC-BIO-ACT-041 FR-BIO-007 路径输入行·点击聚焦 input 点击 焦点获得;边框渐变 L4 P0
TC-BIO-ACT-042 FR-BIO-007 路径输入行·失焦 聚焦中 移开 边框恢复 L4 P1
TC-BIO-ACT-043 FR-BIO-007 路径输入行·键盘 Enter 已输入路径 按 Enter 触发登记(同点按钮) L4 P0
TC-BIO-ACT-044 FR-BIO-007 路径输入行·键盘 Esc 聚焦已输入 按 Esc 清空输入或取消(两态断言其一) L4 P2
TC-BIO-ACT-045 FR-BIO-007 登记路径按钮·点击 合法路径 点击 发出登记请求 L4 P0
TC-BIO-ACT-046 FR-BIO-007 登记路径按钮·悬停 任意 hover pane-btn 悬停反馈;不触发请求 L4 P2
TC-BIO-ACT-047 FR-BIO-007 登记路径按钮·键盘 Enter 按钮聚焦 按 Enter 触发登记 L4 P1
TC-BIO-ACT-048 FR-BIO-007 登记路径按钮·禁用态 input 空 检查 disabled;点击无请求 L4 P0
TC-BIO-ACT-049 FR-BIO-007 登记路径按钮·加载中态 登记请求中 检查 disabled+spinner L4 P1
TC-BIO-ACT-050 FR-BIO-012 重跑按钮·点击 阶段 failed 点击 发出 rerun 请求 L4 P0
TC-BIO-ACT-051 FR-BIO-012 跳过按钮·点击 阶段 failed 点击 发出 skip 请求;状态=skipped L4 P0
TC-BIO-ACT-052 FR-BIO-012 改参数重跑按钮·点击 阶段 failed 点击 弹出该阶段参数表单 L4 P0
TC-BIO-ACT-053 FR-BIO-012 三选一按钮·悬停 阶段 failed hover 每个按钮 pane-btn 悬停反馈 L4 P2
TC-BIO-ACT-054 FR-BIO-012 三选一按钮·键盘 Enter 重跑按钮聚焦 按 Enter 触发重跑 L4 P0
TC-BIO-ACT-055 FR-BIO-012 三选一按钮·键盘 Esc 改参数表单弹出 按 Esc 表单关闭,不提交 L4 P1
TC-BIO-ACT-056 FR-BIO-012 三选一按钮·加载中态 重跑请求中 检查 三按钮 disabled L4 P1
TC-BIO-ACT-057 FR-BIO-012 三选一按钮·禁用态 阶段非 failed 检查 按钮不渲染(仅 failed 显示) L4 P0
TC-BIO-ACT-058 FR-BIO-013 折叠组头·点击 15 阶段链折叠组 点击组头 展开/收起切换;箭头方向变化 L4 P0
TC-BIO-ACT-059 FR-BIO-013 折叠组头·双击 折叠组 双击 最终状态=与初始相反(两次切换) L4 P2
TC-BIO-ACT-060 FR-BIO-013 折叠组头·悬停 折叠组 hover 组头悬停反馈 L4 P2
TC-BIO-ACT-061 FR-BIO-013 折叠组头·键盘 Enter 组头聚焦 按 Enter 切换展开/收起 L4 P1
TC-BIO-ACT-062 FR-BIO-013 折叠组头·键盘 Esc 展开中 按 Esc 收起(或保持,两态断言其一) L4 P2
TC-BIO-ACT-063 FR-BIO-024 面板操作按钮(重跑)·点击 任务 failed 点击 发出 rerun L4 P0
TC-BIO-ACT-064 FR-BIO-024 面板操作按钮(删除)·点击 任务存在 点击 弹确认层 L4 P0
TC-BIO-ACT-065 FR-BIO-024 面板操作按钮·悬停 任务行 hover pane-btn 悬停反馈 L4 P2
TC-BIO-ACT-066 FR-BIO-024 面板操作按钮·键盘 Enter 删除按钮聚焦 按 Enter 弹确认层 L4 P1
TC-BIO-ACT-067 FR-BIO-024 面板操作按钮·键盘 Esc 确认层弹出 按 Esc 关闭确认层不删除 L4 P1
TC-BIO-ACT-068 FR-BIO-024 面板操作按钮·禁用态 任务 running 检查删除按钮 disabled L4 P0
TC-BIO-ACT-069 FR-BIO-024 面板操作按钮·加载中态 重跑请求中 检查 disabled+spinner L4 P1
TC-BIO-ACT-070 FR-BIO-023 面板复用发起按钮·点击 选中归档 点击 打开复用表单(预填) L4 P0
TC-BIO-ACT-071 FR-BIO-023 面板复用发起按钮·悬停 选中归档 hover 悬停反馈 L4 P2
TC-BIO-ACT-072 FR-BIO-023 面板复用发起按钮·键盘 Enter 按钮聚焦 按 Enter 打开复用表单 L4 P1
TC-BIO-ACT-073 FR-BIO-023 面板复用发起按钮·加载中态 表单加载中 检查 disabled+spinner L4 P1
TC-BIO-ACT-074 FR-BIO-020 存档名称输入·点击聚焦 存档提示卡 点击 焦点;边框渐变 L4 P0
TC-BIO-ACT-075 FR-BIO-020 存档名称输入·失焦 聚焦中 移开 边框恢复 L4 P1
TC-BIO-ACT-076 FR-BIO-020 存档名称输入·键盘 Enter 已输入名称 按 Enter 触发存档 L4 P0
TC-BIO-ACT-077 FR-BIO-020 存档名称输入·键盘 Esc 聚焦中 按 Esc 清空或取消(两态断言其一) L4 P2
TC-BIO-ACT-078 FR-BIO-020 存档名称输入·禁用态 存档请求中 检查 disabled L4 P0
TC-BIO-ACT-079 FR-BIO-020 存档按钮·点击 已命名 点击 发出 POST archives L4 P0
TC-BIO-ACT-080 FR-BIO-020 存档按钮·双击 可提交 双击 仅一次请求 L4 P1
TC-BIO-ACT-081 FR-BIO-020 存档按钮·悬停 可提交 hover 渐变增亮 L4 P2
TC-BIO-ACT-082 FR-BIO-020 存档按钮·键盘 Enter 按钮聚焦 按 Enter 触发存档 L4 P1
TC-BIO-ACT-083 FR-BIO-020 存档按钮·禁用态 名称空 检查 disabled L4 P0
TC-BIO-ACT-084 FR-BIO-020 存档按钮·加载中态 存档中 检查 disabled+spinner L4 P0
TC-BIO-ACT-085 FR-BIO-020 放弃按钮·点击 存档提示卡 点击 卡片消失;无请求 L4 P0
TC-BIO-ACT-086 FR-BIO-020 放弃按钮·悬停 提示卡 hover pane-btn 悬停反馈 L4 P2
TC-BIO-ACT-087 FR-BIO-020 放弃按钮·键盘 Enter ���钮聚焦 按 Enter 放弃(卡片消失) L4 P1
TC-BIO-ACT-088 FR-BIO-020 放弃按钮·键盘 Esc 按钮聚焦 按 Esc 取消聚焦;卡片保留 L4 P2
TC-BIO-ACT-089 FR-BIO-020 放弃按钮·加载中态 存档请求中 检查 放弃按钮 disabled(防误操作) L4 P1
TC-BIO-ACT-090 FR-BIO-024 面板列表项·点击 任务列表 点击任务项 选中并展开详情(DAG 显示) L4 P0
TC-BIO-ACT-091 FR-BIO-024 面板列表项·悬停 列表 hover session-item 悬停反馈 L4 P1
TC-BIO-ACT-092 FR-BIO-022 档案列表项·点击 档案列表 点击 选中并显示详情 L4 P0
TC-BIO-ACT-093 FR-BIO-022 档案列表项·悬停 列表 hover 悬停反馈 L4 P1
TC-BIO-ACT-094 FR-BIO-011 进度卡日志区·点击滚动 日志溢出 点击日志区 区域获得焦点可滚动;不触发其他动作 L4 P2
TC-BIO-ACT-095 FR-BIO-011 进度卡日志区·悬停 日志溢出 hover 显示滚动条/悬停反馈 L4 P2

6.1.17 E2E 端到端主线(TEST_PLAN §11 九条 × 三档视口 M/T/D)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-E2E-001-M FR-BIO-002/004 E2E-01 主流程·移动端:候选路径卡出现 mock LLM 正常;390×844 发送「帮我跑水稻 SPL 家族鉴定」 对话出现 .flow-path-card;候选行数量∈[2,3];每行含阶段序列文本 L5-M P0
TC-BIO-E2E-002-M FR-BIO-004 E2E-01 主流程·移动端:点选与确认 候选卡已出现 点击第 1 候选行→点「确认此路径」 路径确认卡出现(逐阶段名称/用途/预计耗时);发出 POST /api/bioflow/jobs L5-M P0
TC-BIO-E2E-003-M FR-BIO-004 E2E-01 主流程·移动端:任务面板出现新任务 任务已创建 切到「生信任务」TAB 列表含新任务;状态=created L5-M P0
TC-BIO-E2E-004-M FR-BIO-005 E2E-01 主流程·移动端:文件引导卡 起始阶段缺 fasta 等待推进 对话出现缺文件提示(点名 fasta)+ .flow-file-card L5-M P0
TC-BIO-E2E-005-M FR-BIO-006 E2E-01 主流程·移动端:拖拽上传金标数据 本地金标输入可用 拖入 Ft.SPL pep 文件 进度条百分比逐级推进至 100%;POST files 发出 L5-M P0
TC-BIO-E2E-006-M FR-BIO-008/009 E2E-01 主流程·移动端:参数表单改一个参数 阶段待确认 表单卡出现后改 cpu=8→点「继续」 发出 confirm;请求体 params.cpu=8;阶段 running L5-M P0
TC-BIO-E2E-007-M FR-BIO-011 E2E-01 主流程·移动端:进度卡逐阶段流转 mock 全链 观察 状态点逐阶段点亮(waiting→running→done);运行中日志尾滚动更新 L5-M P0
TC-BIO-E2E-008-M FR-BIO-016 E2E-01 主流程·移动端:报告预览 任务完成报告登记 切文档 TAB 打开 DocPane 报告出现;预览白底(background=#FFFFFF);图可见 L5-M P0
TC-BIO-E2E-009-M FR-BIO-018 E2E-01 主流程·移动端:导出 PDF 报告已打开 点导出 PDF 下载事件触发;文件落盘且可打开(非 0 字节) L5-M P1
TC-BIO-E2E-010-M FR-BIO-020/021 E2E-01 主流程·移动端:存档提示→存档→状态回复 任务完成 观察提示卡→输入名称→点存档 POST archives 发出;回复消息含名称/位置/大小三要素 L5-M P0
TC-BIO-E2E-011-M FR-BIO-024 E2E-01 主流程·移动端:档案面板出现 已存档 切「生信档案」TAB 列表含新档案(名称正确) L5-M P0
TC-BIO-E2E-012-M FR-BIO-027 E2E-01 主流程·移动端:布局不溢出 全程 观察各步骤 .flow-path-card/.flow-form-card/.flow-file-card/.bioflow-progress-card 宽≤容器;无横向滚动 L5-M P1
TC-BIO-E2E-001-T FR-BIO-002/004 E2E-01 主流程·平板:候选路径卡出现 mock LLM 正常;768×1024 发送「帮我跑水稻 SPL 家族鉴定」 对话出现 .flow-path-card;候选行数量∈[2,3];每行含阶段序列文本 L5-T P0
TC-BIO-E2E-002-T FR-BIO-004 E2E-01 主流程·平板:点选与确认 候选卡已出现 点击第 1 候选行→点「确认此路径」 路径确认卡出现(逐阶段名称/用途/预计耗时);发出 POST /api/bioflow/jobs L5-T P0
TC-BIO-E2E-003-T FR-BIO-004 E2E-01 主流程·平板:任务面板出现新任务 任务已创建 切到「生信任务」TAB 列表含新任务;状态=created L5-T P0
TC-BIO-E2E-004-T FR-BIO-005 E2E-01 主流程·平板:文件引导卡 起始阶段缺 fasta 等待推进 对话出现缺文件提示(点名 fasta)+ .flow-file-card L5-T P0
TC-BIO-E2E-005-T FR-BIO-006 E2E-01 主流程·平板:拖拽上传金标数据 本地金标输入可用 拖入 Ft.SPL pep 文件 进度条百分比逐级推进至 100%;POST files 发出 L5-T P0
TC-BIO-E2E-006-T FR-BIO-008/009 E2E-01 主流程·平板:参数表单改一个参数 阶段待确认 表单卡出现后改 cpu=8→点「继续」 发出 confirm;请求体 params.cpu=8;阶段 running L5-T P0
TC-BIO-E2E-007-T FR-BIO-011 E2E-01 主流程·平板:进度卡逐阶段流转 mock 全链 观察 状态点逐阶段点亮(waiting→running→done);运行中日志尾滚动更新 L5-T P0
TC-BIO-E2E-008-T FR-BIO-016 E2E-01 主流程·平板:报告预览 任务完成报告登记 切文档 TAB 打开 DocPane 报告出现;预览白底(background=#FFFFFF);图可见 L5-T P0
TC-BIO-E2E-009-T FR-BIO-018 E2E-01 主流程·平板:导出 PDF 报告已打开 点导出 PDF 下载事件触发;文件落盘且可打开(非 0 字节) L5-T P1
TC-BIO-E2E-010-T FR-BIO-020/021 E2E-01 主流程·平板:存档提示→存档→状态回复 任务完成 观察提示卡→输入名称→点存档 POST archives 发出;回复消息含名称/位置/大小三要素 L5-T P0
TC-BIO-E2E-011-T FR-BIO-024 E2E-01 主流程·平板:档案面板出现 已存档 切「生信档案」TAB 列表含新档案(名称正确) L5-T P0
TC-BIO-E2E-012-T FR-BIO-027 E2E-01 主流程·平板:布局不溢出 全程 观察各步骤 .flow-path-card/.flow-form-card/.flow-file-card/.bioflow-progress-card 宽≤容器;无横向滚动 L5-T P1
TC-BIO-E2E-001-D FR-BIO-002/004 E2E-01 主流程·桌面:候选路径卡出现 mock LLM 正常;1440×900 发送「帮我跑水稻 SPL 家族鉴定」 对话出现 .flow-path-card;候选行数量∈[2,3];每行含阶段序列文本 L5-D P0
TC-BIO-E2E-002-D FR-BIO-004 E2E-01 主流程·桌面:点选与确认 候选卡已出现 点击第 1 候选行→点「确认此路径」 路径确认卡出现(逐阶段名称/用途/预计耗时);发出 POST /api/bioflow/jobs L5-D P0
TC-BIO-E2E-003-D FR-BIO-004 E2E-01 主流程·桌面:任务面板出现新任务 任务已创建 切到「生信任务」TAB 列表含新任务;状态=created L5-D P0
TC-BIO-E2E-004-D FR-BIO-005 E2E-01 主流程·桌面:文件引导卡 起始阶段缺 fasta 等待推进 对话出现缺文件提示(点名 fasta)+ .flow-file-card L5-D P0
TC-BIO-E2E-005-D FR-BIO-006 E2E-01 主流程·桌面:拖拽上传金标数据 本地金标输入可用 拖入 Ft.SPL pep 文件 进度条百分比逐级推进至 100%;POST files 发出 L5-D P0
TC-BIO-E2E-006-D FR-BIO-008/009 E2E-01 主流程·桌面:参数表单改一个参数 阶段待确认 表单卡出现后改 cpu=8→点「继续」 发出 confirm;请求体 params.cpu=8;阶段 running L5-D P0
TC-BIO-E2E-007-D FR-BIO-011 E2E-01 主流程·桌面:进度卡逐阶段流转 mock 全链 观察 状态点逐阶段点亮(waiting→running→done);运行中日志尾滚动更新 L5-D P0
TC-BIO-E2E-008-D FR-BIO-016 E2E-01 主流程·桌面:报告预览 任务完成报告登记 切文档 TAB 打开 DocPane 报告出现;预览白底(background=#FFFFFF);图可见 L5-D P0
TC-BIO-E2E-009-D FR-BIO-018 E2E-01 主流程·桌面:导出 PDF 报告已打开 点导出 PDF 下载事件触发;文件落盘且可打开(非 0 字节) L5-D P1
TC-BIO-E2E-010-D FR-BIO-020/021 E2E-01 主流程·桌面:存档提示→存档→状态回复 任务完成 观察提示卡→输入名称→点存档 POST archives 发出;回复消息含名称/位置/大小三要素 L5-D P0
TC-BIO-E2E-011-D FR-BIO-024 E2E-01 主流程·桌面:档案面板出现 已存档 切「生信档案」TAB 列表含新档案(名称正确) L5-D P0
TC-BIO-E2E-012-D FR-BIO-027 E2E-01 主流程·桌面:布局不溢出 全程 观察各步骤 .flow-path-card/.flow-form-card/.flow-file-card/.bioflow-progress-card 宽≤容器;无横向滚动 L5-D P1
TC-BIO-E2E-013-M FR-BIO-010 E2E-02 自动连续·移动端 mock 全链 开启自动连续开关→发起任务→中途暂停 阶段间无表单卡自动推进;暂停后停在下一阶段前(该阶段 waiting_confirm) L5-M P0
TC-BIO-E2E-013-T FR-BIO-010 E2E-02 自动连续·平板 mock 全链 同上 同上断言 L5-T P0
TC-BIO-E2E-013-D FR-BIO-010 E2E-02 自动连续·桌面 mock 全链 同上 同上断言 L5-D P0
TC-BIO-E2E-014-M FR-BIO-012 E2E-03 失败注入·移动端:三选一 mock 阶段 2 失败 推进至失败 进度卡标红(--pa-error ✕);三按钮出现 L5-M P0
TC-BIO-E2E-015-M FR-BIO-012 E2E-03 失败注入·移动端:重跑成功 阶段 failed 点重跑(mock 转成功) 状态转 running→done L5-M P0
TC-BIO-E2E-016-M FR-BIO-012 E2E-03 失败注入·移动端:跳过生效 阶段 failed 点跳过 状态=skipped;后续阶段推进 L5-M P0
TC-BIO-E2E-017-M FR-BIO-012 E2E-03 失败注入·移动端:改参数重跑 阶段 failed 点改参数重跑→改参数→继续 表单出现;按新参数重跑成功 L5-M P0
TC-BIO-E2E-014-T FR-BIO-012 E2E-03 失败注入·平板:三选一 mock 阶段 2 失败 推进至失败 进度卡标红(--pa-error ✕);三按钮出现 L5-T P0
TC-BIO-E2E-015-T FR-BIO-012 E2E-03 失败注入·平板:重跑成功 阶段 failed 点重跑(mock 转成功) 状态转 running→done L5-T P0
TC-BIO-E2E-016-T FR-BIO-012 E2E-03 失败注入·平板:跳过生效 阶段 failed 点跳过 状态=skipped;后续阶段推进 L5-T P0
TC-BIO-E2E-017-T FR-BIO-012 E2E-03 失败注入·平板:改参数重跑 阶段 failed 点改参数重跑→改参数→继续 表单出现;按新参数重跑成功 L5-T P0
TC-BIO-E2E-014-D FR-BIO-012 E2E-03 失败注入·桌面:三选一 mock 阶段 2 失败 推进至失败 进度卡标红(--pa-error ✕);三按钮出现 L5-D P0
TC-BIO-E2E-015-D FR-BIO-012 E2E-03 失败注入·桌面:重跑成功 阶段 failed 点重跑(mock 转成功) 状态转 running→done L5-D P0
TC-BIO-E2E-016-D FR-BIO-012 E2E-03 失败注入·桌面:跳过生效 阶段 failed 点跳过 状态=skipped;后续阶段推进 L5-D P0
TC-BIO-E2E-017-D FR-BIO-012 E2E-03 失败注入·桌面:改参数重跑 阶段 failed 点改参数重跑→改参数→继续 表单出现;按新参数重跑成功 L5-D P0
TC-BIO-E2E-018-M FR-BIO-014 E2E-04 断线回放·移动端 任务 3 阶段执行中 切断 SSE 30s→重连 进度卡恢复断线前状态;无进度丢失;日志尾恢复 L5-M P0
TC-BIO-E2E-018-T FR-BIO-014 E2E-04 断线回放·平板 任务 3 阶段执行中 切断 SSE 30s→重连 进度卡恢复断线前状态;无进度丢失;日志尾恢复 L5-T P0
TC-BIO-E2E-018-D FR-BIO-014 E2E-04 断线回放·桌面 任务 3 阶段执行中 切断 SSE 30s→重连 进度卡恢复断线前状态;无进度丢失;日志尾恢复 L5-D P0
TC-BIO-E2E-019-M FR-BIO-023 E2E-05 存档复用·移动端 归档 XXX 存在 发送「用 XXX 存档任务的方法帮我跑玉米 bZIP」→确认预填表单→执行 表单预填=XXX 参数(来源标注 XXX);新任务按此参数执行 L5-M P0
TC-BIO-E2E-019-T FR-BIO-023 E2E-05 存档复用·平板 归档 XXX 存在 同上 同上断言 L5-T P0
TC-BIO-E2E-019-D FR-BIO-023 E2E-05 存档复用·桌面 归档 XXX 存在 同上 同上断言 L5-D P0
TC-BIO-E2E-020-M FR-BIO-025 E2E-06 探活显隐·移动端 同部署 mock 停 8098→刷新 「生信任务/生信档案」TAB 与生信块分支消失;恢复 8098→刷新→出现 L5-M P0
TC-BIO-E2E-020-T FR-BIO-025 E2E-06 探活显隐·平板 同部署 mock 停 8098→刷新 「生信任务/生信档案」TAB 与生信块分支消失;恢复 8098→刷新→出现 L5-T P0
TC-BIO-E2E-020-D FR-BIO-025 E2E-06 探活显隐·桌面 同部署 mock 停 8098→刷新 「生信任务/生信档案」TAB 与生信块分支消失;恢复 8098→刷新→出现 L5-D P0
TC-BIO-E2E-021-M FR-BIO-019 E2E-07 图表调整·移动端 报告含图1 发送「图1 颜色换成红色」 触发绘图阶段重跑;新图回填报告;预览刷新(颜色变化) L5-M P0
TC-BIO-E2E-021-T FR-BIO-019 E2E-07 图表调整·平板 报告含图1 发送「图1 颜色换成红色」 触发绘图阶段重跑;新图回填报告;预览刷新(颜色变化) L5-T P0
TC-BIO-E2E-021-D FR-BIO-019 E2E-07 图表调整·桌面 报告含图1 发送「图1 颜色换成红色」 触发绘图阶段重跑;新图回填报告;预览刷新(颜色变化) L5-D P0
TC-BIO-E2E-022-M FR-BIO-026 E2E-08 知识库问答·移动端 flow_docs 已入库;生信会话 发送「identify 需要什么输入」 答案含引用块(源文件+章节);点引用跳转原文 L5-M P0
TC-BIO-E2E-022-T FR-BIO-026 E2E-08 知识库问答·平板 flow_docs 已入库;生信会话 发送「identify 需要什么输入」 答案含引用块(源文件+章节);点引用跳转原文 L5-T P0
TC-BIO-E2E-022-D FR-BIO-026 E2E-08 知识库问答·桌面 flow_docs 已入库;生信会话 发送「identify 需要什么输入」 答案含引用块(源文件+章节);点引用跳转原文 L5-D P0
TC-BIO-E2E-023-M FR-BIO-027 E2E-09 三档视口·移动端布局 390×844;进度卡/面板可见 观察五卡片+两面板 卡片/面板/进度卡不溢出;触控目标≥44px(按钮/候选行命中区) L5-M P0
TC-BIO-E2E-023-T FR-BIO-027 E2E-09 三档视口·平板布局 768×1024;进度卡/面板可见 观察五卡片+两面板 卡片/面板/进度卡不溢出;面板可切换 L5-T P0
TC-BIO-E2E-023-D FR-BIO-027 E2E-09 三档视口·桌面布局 1440×900;进度卡/面板可见 观察五卡片+两面板 卡片/面板/进度卡不溢出;面板可切换 L5-D P0
TC-BIO-E2E-024-M FR-BIO-018 E2E-01 主流程·移动端:导出 DOCX 报告已打开 点导出 DOCX 下载事件触发;文件落盘且可打开(非 0 字节) L5-M P1
TC-BIO-E2E-024-T FR-BIO-018 E2E-01 主流程·平板:导出 DOCX 报告已打开 点导出 DOCX 下载事件触发;文件落盘且可打开(非 0 字节) L5-T P1
TC-BIO-E2E-024-D FR-BIO-018 E2E-01 主流程·桌面:导出 DOCX 报告已打开 点导出 DOCX 下载事件触发;文件落盘且可打开(非 0 字节) L5-D P1
TC-BIO-E2E-025-M FR-BIO-001 E2E 漏判安全·移动端 mock 发送「什么是基因家族」 走 qa 流;无 .flow-path-card;无 bioflow 请求 L5-M P0
TC-BIO-E2E-025-T FR-BIO-001 E2E 漏判安全·平板 mock 发送「什么是基因家族」 走 qa 流;无 .flow-path-card;无 bioflow 请求 L5-T P0
TC-BIO-E2E-025-D FR-BIO-001 E2E 漏判安全·桌面 mock 发送「什么是基因家族」 走 qa 流;无 .flow-path-card;无 bioflow 请求 L5-D P0
TC-BIO-E2E-026-M FR-BIO-007 E2E 服务器路径登记·移动端 任务待文件 文件卡路径输入行输入合法路径→点登记 登记成功显示登记项;阶段推进 L5-M P1
TC-BIO-E2E-026-T FR-BIO-007 E2E 服务器路径登记·平板 任务待文件 文件卡路径输入行输入合法路径→点登记 登记成功显示登记项;阶段推进 L5-T P1
TC-BIO-E2E-026-D FR-BIO-007 E2E 服务器路径登记·桌面 任务待文件 文件卡路径输入行输入合法路径→点登记 登记成功显示登记项;阶段推进 L5-D P1
TC-BIO-E2E-027-M FR-BIO-010 E2E-02 暂停恢复·移动端 任务暂停中 点恢复 从下一阶段继续执行 L5-M P0
TC-BIO-E2E-027-T FR-BIO-010 E2E-02 暂停恢复·平板 任务暂停中 点恢复 从下一阶段继续执行 L5-T P0
TC-BIO-E2E-027-D FR-BIO-010 E2E-02 暂停恢复·桌面 任务暂停中 点恢复 从下一阶段继续执行 L5-D P0
TC-BIO-E2E-028-M FR-BIO-017 E2E 报告编辑·移动端 报告已打开 就地改文字→保存 文字更新落盘(刷新后仍在);走既有编辑链路 L5-M P1
TC-BIO-E2E-028-T FR-BIO-017 E2E 报告编辑·平板 报告已打开 就地改文字→保存 文字更新落盘(刷新后仍在);走既有编辑链路 L5-T P1
TC-BIO-E2E-028-D FR-BIO-017 E2E 报告编辑·桌面 报告已打开 就地改文字→保存 文字更新落盘(刷新后仍在);走既有编辑链路 L5-D P1
TC-BIO-E2E-029-M FR-BIO-024 E2E 任务面板 DAG·移动端 任务 3 阶段 打开任务详情 纵向连接线渲染;3 节点圆点按状态取色 L5-M P1
TC-BIO-E2E-029-T FR-BIO-024 E2E 任务面板 DAG·平板 任务 3 阶段 打开任务详情 纵向连接线渲染;3 节点圆点按状态取色 L5-T P1
TC-BIO-E2E-029-D FR-BIO-024 E2E 任务面板 DAG·桌面 任务 3 阶段 打开任务详情 纵向连接线渲染;3 节点圆点按状态取色 L5-D P1
TC-BIO-E2E-030-M FR-BIO-022 E2E 档案回看·移动端 归档存在 档案面板打开归档详情 详情显示阶段链/参数/产物/报告 L5-M P1
TC-BIO-E2E-030-T FR-BIO-022 E2E 档案回看·平板 归档存在 档案面板打开归档详情 详情显示阶段链/参数/产物/报告 L5-T P1
TC-BIO-E2E-030-D FR-BIO-022 E2E 档案回看·桌面 归档存在 档案面板打开归档详情 详情显示阶段链/参数/产物/报告 L5-D P1
TC-BIO-E2E-031-M FR-BIO-020 E2E 放弃存档·移动端 存档提示卡出现 点「放弃」 卡片消失;无 POST /api/bioflow/archives;任务保持 done 无副作用 L5-M P1
TC-BIO-E2E-031-T FR-BIO-020 E2E 放弃存档·平板 存档提示卡出现 点「放弃」 卡片消失;无 POST /api/bioflow/archives;任务保持 done 无副作用 L5-T P1
TC-BIO-E2E-031-D FR-BIO-020 E2E 放弃存档·桌面 存档提示卡出现 点「放弃」 卡片消失;无 POST /api/bioflow/archives;任务保持 done 无副作用 L5-D P1
TC-BIO-E2E-032-M FR-BIO-023 E2E 面板复用发起·移动端 归档存在 档案面板→选中→点复用发起→确认 表单预填=归档参数;新任务入生信任务面板 L5-M P1
TC-BIO-E2E-032-T FR-BIO-023 E2E 面板复用发起·平板 归档存在 档案面板→选中→点复用发起→确认 表单预填=归档参数;新任务入生信任务面板 L5-T P1
TC-BIO-E2E-032-D FR-BIO-023 E2E 面板复用发起·桌面 归档存在 档案面板→选中→点复用发起→确认 表单预填=归档参数;新任务入生信任务面板 L5-D P1
TC-BIO-E2E-033-M FR-BIO-010 E2E 自动连续可关闭·移动端 自动连续任务运行中 关闭自动连续开关 下一阶段前出现参数表单卡(切回手动) L5-M P1
TC-BIO-E2E-033-T FR-BIO-010 E2E 自动连续可关闭·平板 自动连续任务运行中 关闭自动连续开关 下一阶段前出现参数表单卡(切回手动) L5-T P1
TC-BIO-E2E-033-D FR-BIO-010 E2E 自动连续可关闭·桌面 自动连续任务运行中 关闭自动连续开关 下一阶段前出现参数表单卡(切回手动) L5-D P1
TC-BIO-E2E-034-M FR-BIO-024 E2E 任务面板删除·移动端 非运行任务存在 面板点删除→确认 发出 DELETE;列表移除;刷新后仍无 L5-M P1
TC-BIO-E2E-034-T FR-BIO-024 E2E 任务面板删除·平板 非运行任务存在 面板点删除→确认 发出 DELETE;列表移除;刷新后仍无 L5-T P1
TC-BIO-E2E-034-D FR-BIO-024 E2E 任务面板删除·桌面 非运行任务存在 面板点删除→确认 发出 DELETE;列表移除;刷新后仍无 L5-D P1
TC-BIO-E2E-035-M FR-BIO-022 E2E 档案删除·移动端 归档存在 档案面板点删除→确认 发出 DELETE;列表移除;刷新后仍无 L5-M P1
TC-BIO-E2E-035-T FR-BIO-022 E2E 档案删除·平板 归档存在 档案面板点删除→确认 发出 DELETE;列表移除;刷新后仍无 L5-T P1
TC-BIO-E2E-035-D FR-BIO-022 E2E 档案删除·桌面 归档存在 档案面板点删除→确认 发出 DELETE;列表移除;刷新后仍无 L5-D P1
TC-BIO-E2E-036-M FR-BIO-007 E2E 聊天窗口指定路径·移动端 任务待文件 在聊天输入合法服务器路径并发送 路径登记成功;文件引导卡更新;阶段推进 L5-M P1
TC-BIO-E2E-036-T FR-BIO-007 E2E 聊天窗口指定路径·平板 任务待文件 在聊天输入合法服务器路径并发送 路径登记成功;文件引导卡更新;阶段推进 L5-T P1
TC-BIO-E2E-036-D FR-BIO-007 E2E 聊天窗口指定路径·桌面 任务待文件 在聊天输入合法服务器路径并发送 路径登记成功;文件引导卡更新;阶段推进 L5-D P1

6.1.18 DEPLOY 三形态部署(L2/L3 断言 + L2s 部署点冒烟)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-DEPLOY-001 FR-BIO-027 只 rag:反代不注册 BIOFLOW_ENABLED 缺省(false)启动 BFF 检查路由表 无 /api/bioflow/* 路由 L2 P0
TC-BIO-DEPLOY-002 FR-BIO-027 只 rag:前端无生信痕迹 只 rag 部署;GET health 404 打开前端 无「生信任务/生信档案」TAB;无生信块分支;Composer 无生信上传分支 L3 P0
TC-BIO-DEPLOY-003 FR-BIO-027 只 rag:零请求 8098 只 rag 部署 打开前端并提问 网络面板无 /api/bioflow/* 请求 L3 P0
TC-BIO-DEPLOY-004 FR-BIO-027 只生信:8098 直连 仅部署生信服务 GET :8098/api/bioflow/health 200;catalog/jobs/chat 全部可用(不经 BFF) L2 P0
TC-BIO-DEPLOY-005 FR-BIO-027 只生信:报告降级下载 HTML 只生信;任务 done 取报告 返回 HTML 直下(Content-Type=text/html;Content-Disposition attachment 或页面内嵌,两态断言其一) L2 P0
TC-BIO-DEPLOY-006 FR-BIO-027 同部署:反代启用 BIOFLOW_ENABLED=true GET http://BFF/api/bioflow/health 200 且响应体=直连响应体 L2 P0
TC-BIO-DEPLOY-007 FR-BIO-027 同部署:前端显形 同部署;health 200 打开前端 生信 TAB 出现;五类卡片/两面板可访问 L3 P0
TC-BIO-DEPLOY-008 FR-BIO-028 BFF 停生信服务仍工作 同部署;停 BFF 直连 8098 跑 mini 任务 任务正常完成(创建/确认/事件) L2s P0
TC-BIO-DEPLOY-009 FR-BIO-028 BFF 重启不影响生信任务 同部署;任务 in-flight 重启 BFF 任务不受影响;8098 进程存活;GET jobs 仍含该任务 L2s P0
TC-BIO-DEPLOY-010 FR-BIO-027 三形态环境变量矩阵 三组配置 fixture 逐组启动 BFF 路由注册与否与 BIOFLOW_ENABLED 严格一致(3/3) L2 P1
TC-BIO-DEPLOY-011 FR-BIO-025 探活超时前端不白屏 health 超时(mock 挂起) 打开前端 页面正常渲染(无生信 TAB);无未捕获异常 L3 P1
TC-BIO-DEPLOY-012 FR-BIO-027 只生信形态 vstore 降级 只生信 跑流程咨询 检索不可用时 planner 走 LLM 直出(标记 llm_only);不 5xx L2 P1

6.1.19 REG 回归与串扰(L3/L4/L5,bioflow 引入不得破坏既有功能)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-REG-001 FR-BIO-001 QA 主流程无串扰 同部署;mock normal 完整跑 E2E-01(QA 五相位) 全相位通过;无 bioflow 请求产生 L5-D P0
TC-BIO-REG-002 FR-BIO-001 检索模式无串扰 mock 检索模式提问 只出来源不出答案块(与既有行为一致) L5-D P0
TC-BIO-REG-003 FR-BIO-001 docgen 全链无串扰 同部署 写文档→编辑→导出 全部走既有 docgen 链路;无 bioflow 拦截 L5-D P0
TC-BIO-REG-004 FR-BIO-001 会话管理无串扰 同部署 新建/切换/删除会话 行为与既有一致 L5-D P1
TC-BIO-REG-005 FR-BIO-001 意图词典改动不打乱 docgen 词典全表 跑 cases_intent.md(docgen 版)30 条 docgen 判定 30/30 与既有表一致 L3 P0
TC-BIO-REG-006 FR-BIO-001 红线文件零改动 git checkout 基线 diff 五文件 modes.js/labels.js/bench.js/qa.js/parser.js 无 diff L3 P0
TC-BIO-REG-007 FR-BIO-011 PipelineCard 零改动 进度卡复用 diff PipelineCard.vue 无 diff;两卡同款视觉 L3 P1
TC-BIO-REG-008 FR-BIO-001 BenchPanel TAB 数更新 同部署 数 TAB 生信 TAB 计入后总数=既有+2;关服务时恢复既有数 L4 P0
TC-BIO-REG-009 FR-BIO-016 doc_artifacts 与生信报告并存 同部署 查看文档工作台 既有 docgen 文档与生信报告同列表可切换;互不覆盖 L5-D P0
TC-BIO-REG-010 FR-BIO-001 首屏性能不劣化 同部署 测首屏 首屏时间与引入前基线差 <500ms L5-D P2
TC-BIO-REG-011 FR-BIO-001 主题切换生信组件适配 同部署 切深/浅 五卡片两面板令牌随主题(--pa-* 自动适配,无硬编码色) L4 P0
TC-BIO-REG-012 FR-BIO-001 i18n 文案走 bioflow.js 前端构建 检索文案键 生信文案全部在 i18n/bioflow.js;labels.js 未动 L3 P1
TC-BIO-REG-013 FR-BIO-001 生信会话与 QA 会话隔离 同部署 两会话并行操作 各自消息/任务状态互不串扰 L5-D P1
TC-BIO-REG-014 FR-BIO-001 既有 E2E 冒烟 6 条 同部署 跑 smoke.spec 三视口 6/6 pass(占位回退失效后走真实分支仍过) L5 P1
TC-BIO-REG-015 FR-BIO-001 QA 上游 402 降级不受影响 mock 402 提问 fallback 证据列表展示与既有一致 L5-D P1

6.1.20 GOLD 金标与发布(L2s 部署点冒烟 + 编译门禁)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-GOLD-001 FR-BIO-030 金标 24 ID 全等 bioflow-gf 镜像;金标输入 docker run identify 输出集合与预期 24 成员 ID 全等;diff 输出为空 L2s P0
TC-BIO-GOLD-002 FR-BIO-030 金标冒烟脚本 镜像与数据就位 bash bioflow_kernel/tests/smoke_golden.sh 退出码 0;stdout 含 PASS L2s P0
TC-BIO-GOLD-003 FR-BIO-030 金标重复可复现 同上 连跑 2 次 两次输出集合一致(确定性) L2s P1
TC-BIO-GOLD-004 FR-BIO-032 18 入口 --help 冒烟 4 镜像 逐条 python -B -m cli.run_* --help 18/18 退出码 0;无 traceback L2s P0
TC-BIO-GOLD-005 FR-BIO-032 compile_bioflow.sh 编译产出 源码树 跑编译脚本(TL 执行后 T 验证) 产出 .so 与明文白名单文件;无编译错误 L2s P0
TC-BIO-GOLD-006 FR-BIO-032 白名单外无明文 编译产物 检查产物 白名单外模块均为 .so(无 .py 明文残留) L2s P1
TC-BIO-GOLD-007 FR-BIO-032 build_all.sh 4 镜像 构建环境 检查 docker images bioflow-gf/bioflow-rnaseq/bioflow-wgs/bioflow-interproscan 四 tag 存在 L2s P0
TC-BIO-GOLD-008 FR-BIO-032 SHA256SUMS 构建产物目录 校验 文件存在且每条 sha256 与产物一致 L2s P0
TC-BIO-GOLD-009 FR-BIO-032 泄露门禁扫描 构建产物 扫描凭据模式 无 ACCESS_KEY/SECRET/密码类命中 L2s P0
TC-BIO-GOLD-010 FR-BIO-032 镜像启动冒烟 4 镜像 docker run --help 版入口 4/4 容器启动并退出码 0 L2s P0
TC-BIO-GOLD-011 FR-BIO-029 资源限制生效验证 镜像 docker run --cpus 2 --memory 4g 跑冒烟 容器内可见限制(/sys/fs/cgroup 或 nproc 断言) L2s P1
TC-BIO-GOLD-012 FR-BIO-029 BIOFLOW_DATA 只读 镜像 挂载 :ro 跑冒烟 容器内写 /bioflow-data 失败(Permission denied) L2s P1
TC-BIO-GOLD-013 FR-BIO-032 rag 侧装配开关 rag 部署树 检查配置文件 BIOFLOW_ENABLED 键存在且默认 false L2s P0
TC-BIO-GOLD-014 FR-BIO-032 生信服务编译白名单 编译产物 检查 main.py/config.py/schemas.py/db.py 明文;业务模块 .so L2s P1
TC-BIO-GOLD-015 FR-BIO-032 内核映射表产物 A1 交付 检查 bioflow_kernel/stage_image_map.json JSON 合法;覆盖基因家族链 18 阶段 L2s P0

6.1.21 P0 冒烟(优先级 P0 快速验证集,TL 放行/验收快速通道)

编号 对应 FR 标题 前置条件 步骤 预期结果 测试层 优先级
TC-BIO-SMOKE-001 FR-BIO-001 P0 冒烟:分流命中 mock 发送「帮我跑水稻 SPL 家族鉴定」 进入生信流(出现路径卡或 bioflow 请求) L5-D P0
TC-BIO-SMOKE-002 FR-BIO-001 P0 冒烟:漏判安全 mock 发送「什么是基因家族」 走 qa;无 bioflow 请求 L5-D P0
TC-BIO-SMOKE-003 FR-BIO-025 P0 冒烟:探活 mock 打开应用(health 200) 生信 TAB 可见 L5-D P0
TC-BIO-SMOKE-004 FR-BIO-002 P0 冒烟:候选路径 mock LLM 读 plan_ready 候选数∈[2,3] 且含阶段序列 L2 P0
TC-BIO-SMOKE-005 FR-BIO-004 P0 冒烟:任务创建 mock POST jobs 201 且 stages 入表 L2 P0
TC-BIO-SMOKE-006 FR-BIO-031 P0 冒烟:状态机 mock docker 3 阶段任务跑通 全部 done;事件序正确 L1 P0
TC-BIO-SMOKE-007 FR-BIO-014 P0 冒烟:事件回放 任务中途 连 events 快照+补齐 L2 P0
TC-BIO-SMOKE-008 FR-BIO-029 P0 冒烟:docker 拼装 mock 拼 identify 命令 含 --rm/--user/-v×3/--cpus/--memory/-e L1 P0
TC-BIO-SMOKE-009 FR-BIO-030 P0 冒烟:金标 镜像就位 金标 diff 输出为空 L2s P0
TC-BIO-SMOKE-010 FR-BIO-028 P0 冒烟:反代开关 BIOFLOW_ENABLED=true GET BFF health 200 L2 P0
TC-BIO-SMOKE-011 FR-BIO-011 P0 冒烟:进度卡流转 mock 事件 前端应用 状态点逐阶段点亮 L4 P0
TC-BIO-SMOKE-012 FR-BIO-012 P0 冒烟:三选一 阶段 failed 检查三按钮 重跑/跳过/改参数重跑出现 L4 P0
TC-BIO-SMOKE-013 FR-BIO-020 P0 冒烟:存档 任务 done POST archives 201;磁盘目录存在 L2 P0
TC-BIO-SMOKE-014 FR-BIO-023 P0 冒烟:复用 归档存在 archives/{id}/run 201;参数=归档值 L2 P0
TC-BIO-SMOKE-015 FR-BIO-016 P0 冒烟:报告登记 任务 done 登记 doc_artifacts 新行 L2 P0
TC-BIO-SMOKE-016 FR-BIO-019 P0 冒烟:图表调整 报告含图 revise 绘图阶段重跑;图更新 L2 P0
TC-BIO-SMOKE-017 FR-BIO-026 P0 冒烟:知识问答 flow_docs 入库 咨询 答案含引用块 L2 P0
TC-BIO-SMOKE-018 FR-BIO-027 P0 冒烟:三形态 三配置 fixture 逐形态启动 3/3 断言通过 L2 P0
TC-BIO-SMOKE-019 FR-BIO-032 P0 冒烟:--help 18 入口 镜像 逐条 --help 18/18 退出码 0 L2s P0
TC-BIO-SMOKE-020 FR-BIO-032 P0 冒烟:SHA256SUMS 产物 校验 全部匹配 L2s P0
TC-BIO-SMOKE-021 FR-BIO-006 P0 冒烟:上传 任务待文件 上传小文件 200;files 列表+1 L2 P0
TC-BIO-SMOKE-022 FR-BIO-007 P0 冒烟:路径登记 合法路径 POST files server_path 200;登记可见 L2 P0
TC-BIO-SMOKE-023 FR-BIO-010 P0 冒烟:暂停恢复 任务 running pause→resume 状态迁移正确 L2 P0
TC-BIO-SMOKE-024 FR-BIO-024 P0 冒烟:面板渲染 任务存在 打开面板 列表+DAG 渲染 L4 P0
TC-BIO-SMOKE-025 FR-BIO-022 P0 冒烟:档案面板 归档存在 打开面板 档案列表渲染 L4 P0

6.2 追溯矩阵(FR-BIO → TC-BIO)

FR TC-BIO(引用即覆盖,≥1 条)
FR-BIO-001 INTENT-001010,022030,040047; API-001,005010,013015,019,020,136; STORE-001,002,022; REG-001006,010,012~015; SMOKE-001,002; E2E-025-M/T/D; ACT-030
FR-BIO-002 INTENT-001010; API-002,021026,114,137,145; STORE-003; PATH-001011,015,016,018020; ACT-001~013; SMOKE-004; E2E-001-M/T/D
FR-BIO-003 API-003,004; RUN-034; PATH-012; INTENT-003
FR-BIO-004 API-027031,107,138,149; STORE-004; PATH-013,014,017; SMOKE-005; E2E-001003-M/T/D
FR-BIO-005 RUN-017,018,032; FILE-001,002,015; E2E-004-M/T/D
FR-BIO-006 API-039041,046054,105,120; STORE-010; FILE-003007,011018,021,022; ACT-034~040; SMOKE-021; E2E-005-M/T/D
FR-BIO-007 API-042045; FILE-008010,019,020; ACT-041~049; SMOKE-022; E2E-026,036-M/T/D
FR-BIO-008 API-056,058,121; RUN-019,020; FORM-001006,013018,021,022; ACT-014~019; E2E-006-M/T/D
FR-BIO-009 API-057,059061,150; STORE-011; FORM-007009,018,019,023,024; ACT-020~026; E2E-006-M/T/D
FR-BIO-010 API-067070,122,147,148; RUN-006,007,021023; STORE-012,013; FORM-010012; PROG-017,018; ACT-027033; SMOKE-023; E2E-013,027,033-M/T/D
FR-BIO-011 API-071076,108,127; RUN-013; STORE-005,007; PROG-001005,019,023,024; JOB-006,016; ACT-094,095; SMOKE-011; E2E-007-M/T/D
FR-BIO-012 API-062066,140; RUN-002005,024,045; STORE-006,014; PROG-006011,020,022; ACT-050057; SMOKE-012; E2E-014~017-M/T/D
FR-BIO-013 PROG-012014; ACT-058062
FR-BIO-014 API-013,017,077083,126,128; SSE-001032; STORE-008,009,020,021; PROG-015,016; SMOKE-007; E2E-018-M/T/D
FR-BIO-015 API-104,124,125; FLOW-005,006
FR-BIO-016 API-123; FLOW-003,004,007; REG-009; SMOKE-015; E2E-008-M/T/D
FR-BIO-017 API-143; E2E-028-M/T/D
FR-BIO-018 E2E-009,024-M/T/D
FR-BIO-019 API-084~086,144; INTENT-033; FLOW-008; SMOKE-016; E2E-021-M/T/D
FR-BIO-020 API-087089,098,129,130; ARCH-001006,011,012; ACT-074~089; SMOKE-013; E2E-010,031-M/T/D
FR-BIO-021 API-131; DB-012; STORE-017; ARCH-007~010; E2E-010-M/T/D
FR-BIO-022 API-090093,141,142; DB-007; STORE-019; PANE-001007,011,012,015; ACT-092,093; SMOKE-025; E2E-030,035-M/T/D
FR-BIO-023 API-011,029,094097,132; INTENT-034039; STORE-015; FORM-020; PANE-008010,016; ACT-070073; SMOKE-014; E2E-019,032-M/T/D
FR-BIO-024 API-032038,112,113; RUN-028,029,044; DB-006,011; STORE-018; PROG-021; JOB-001016; ACT-063~069,090,091; SMOKE-024; E2E-003,011,029,034-M/T/D
FR-BIO-025 API-099,133; STORE-016; JOB-012,013; PANE-013,014; DEPLOY-011; SMOKE-003; E2E-020-M/T/D
FR-BIO-026 API-012; INTENT-045; FLOW-009; SMOKE-017; E2E-022-M/T/D
FR-BIO-027 DEPLOY-001~007,010,012; SMOKE-018; E2E-012,023-M/T/D
FR-BIO-028 API-100103,134,135; DB-001005,008,009; FLOW-001,002; DEPLOY-008,009; SMOKE-010
FR-BIO-029 API-115119; RUN-012,014,016,031,035037; KERN-001~009,024; GOLD-011,012; SMOKE-008
FR-BIO-030 KERN-010,011,014020; GOLD-001003; SMOKE-009
FR-BIO-031 API-016,109111,139,146; RUN-001,008011,025027,030,033,038043,046; DB-010; SMOKE-006
FR-BIO-032 KERN-012,013,021023; GOLD-004010,013~015; SMOKE-019,020

覆盖自核:32/32 FR-BIO 全部有 TC 引用;每个 TC-BIO 均映射至少 1 个 FR(见每行「对应 FR」列);无孤儿 TC。模块计数与规模门禁见 docs/team/report_bioflow_test1.md。

用例修订记录

日期 修订 原因
2026-09-06 TC-BIO-API-021/022 期望 73/18 → 与 stage_image_map.json v2.0.0 权威数据一致(75/21) BUG-R1-02:实现以 A1 交付物为事实源,用例按 dev 旧树冻结属口径过期
2026-09-06 TC-BIO-INTENT-044 期望 bioflow+目标对象 → qa BUG-R1-05:冻结词典无交互式补充规则,实现与词典一致;「换物种重跑」交互式补充转 P7 扩展加固期实现(新 FR 追加后补 TC)