Files
DevFlow/docs/02-架构设计/专项设计/后续批次测试用例设计-2026-07-01.md
绝尘 6833792de2 新增: 后续批次测试用例设计 + 批次规划同步worktree方案
- 测试用例:8大类共70+用例(迁移/Repo/拆解/worktree/并行/仲裁/模板/CI/审批/拆分/端到端/边界)

- 批次同步:数据层+worktree+并行(12项)/仲裁+冲突UI+编译检查(10项)/模板+节点(10项)/Git-CI+DockerNode(6项)/审批政策+小程序+收尾(8项)

- INDEX注册两份设计文档
2026-07-01 21:30:58 +08:00

12 KiB
Raw Blame History

后续批次测试用例设计 — 2026-07-01

覆盖:多Agent并行执行 / Git worktree 隔离 / 仲裁合并 / 模板系统 / Git-CI / 审批政策 关联:多Agent并行执行与仲裁合并设计-2026-07-01.md


一、测试分层

层级 范围 工具
单元测试 纯函数/数据结构/repo CRUD #[test] Rust / vitest TS
集成测试 跨模块协作(dispatch+merge+worktree) #[tokio::test]
端到端 用户发消息→Plan→并行→合并→展示 手动 + 日志验证

二、数据层与并行执行 测试用例

2.1 V36 迁移

ID 场景 预期
MIG-01 新库空跑 V36 3 新表 + 2 列 ALTER 成功,ai_plans 为空
MIG-02 老库(有数据)跑 V36 ai_messages/ai_tool_executions 加 subtask_id 列(NULL),原有数据不动
MIG-03 V36 幂等(重跑) 不崩溃,版本号已写入直接跳过
MIG-04 老库 ai_messages 有 100 条数据 subtask_id 全部为 NULL,查询不报错

2.2 Repo CRUD

ID 场景 预期
REPO-01 PlanRepo.insert + get 写入后能按 id 读回,字段完整
REPO-02 PlanRepo.update_status planning→executing→done 状态流转正确
REPO-03 SubTaskRepo.insert + list_by_plan 按 plan_id 查子任务,layer 排序正确
REPO-04 SubTaskRepo.update_status pending→running→done 流转
REPO-05 ConflictRepo.insert + list_pending 按 plan_id 查 resolution=pending 的冲突
REPO-06 ConflictRepo.resolve 更新 resolution + resolved_by + resolved_at
REPO-07 SubTaskRepo 查 branch=NULL 非 Git 工程的 SubTask branch 为 NULL,查询正常

2.3 Coordinator 拆解

ID 场景 输入 预期
DEC-01 读+写意图 "先 read 文件再修改" 2 SubTask(read→write),write deps=[read]
DEC-02 纯读意图 "分析现有代码结构" 1 SubTask(read),无 deps
DEC-03 纯写意图 "implement new feature" 1 SubTask(write),无 deps
DEC-04 兜底意图 "你好" 1 SubTask(default)
DEC-05 人设分配 "review this code" SubTask persona=reviewer
DEC-06 Plan 非空 任意非空输入 plan.tasks.len() >= 1

2.4 Git worktree 隔离

ID 场景 预期
WT-01 worktree 创建 .devflow/wt/{plan_id}/A 目录存在,git branch subtask/{plan_id}/A 存在
WT-02 worktree 内 write_file 写入落到 worktree 目录,主目录文件不变
WT-03 同层并行隔离 SubTask A 写 main.rs,SubTask B 读 main.rs → B 读到的是 fork 基点内容,非 A 的改动
WT-04 worktree commit SubTask 完成后 git add+commit,分支有新 commit
WT-05 worktree 清理 Plan 完成后 .devflow/wt/{plan_id}/ 目录被移除
WT-06 非 Git 工程降级 无 .git 的工程 → branch=NULL,走串行,不崩溃
WT-07 worktree 创建失败 磁盘满/权限不足 → 降级串行,日志告警

2.5 并行调度

ID 场景 预期
PAR-01 线性链(2层×1任务) Layer0 done → Layer1 启动,总耗时≈串行
PAR-02 并行层(1层×3任务) 3 SubTask 并发执行,总耗时≈最慢的一个
PAR-03 钻石依赖 A→{B,C}→D,B/C 并行,D 等 B+C 都 done
PAR-04 层间隔离 Layer1 的 SubTask 能读到 Layer0 merge 后的改动
PAR-05 单 SubTask 失败 标记 error,不中断同层其他 SubTask
PAR-06 全部 SubTask 失败 Plan.status=error
PAR-07 SubTask 超时(120s) 标记 error,其他 SubTask 不受影响

2.6 Token 预算池

ID 场景 预期
TOK-01 预算充足 try_reserve(10k) → true,consumed+=10k
TOK-02 预算超限 consumed=98k,total=100k,try_reserve(5k) → false
TOK-03 并发 reserve 2 个 SubTask 同时 reserve(CAS 竞争)
TOK-04 超限降级串行 预算用完 → 剩余 SubTask 串行执行(不拒绝)

2.7 事件协议

ID 场景 预期
EVT-01 AiPlanCreated 前端 PlanProgress 立即展示 DAG 层结构
EVT-02 AiSubTaskStatusChanged 节点状态从 pending→running→done 更新
EVT-03 AiMergeCompleted(无冲突) 合并输出展示,无冲突徽章
EVT-04 AiMergeCompleted(有冲突) 冲突徽章出现
EVT-05 AiConflictResolved 冲突徽章消失
EVT-06 事件双写 emit 和 publish_event 都触发

三、仲裁合并与冲突 测试用例

3.1 Git merge 冲突检测

ID 场景 预期
MRG-01 无冲突合并 A 改 file1,B 改 file2 → merge-tree 无冲突 → git merge 成功
MRG-02 同文件冲突 A 改 main.rs 第10行,B 改 main.rs 第10行 → conflict markers 出现
MRG-03 同文件不冲突区 A 改 main.rs 第10行,B 改 main.rs 第50行 → git 自动合并成功
MRG-04 跨层同文件 Layer0 改 main.rs,merge 到 plan;Layer1 改 main.rs → 基于已含 Layer0 的版本,无冲突
MRG-05 三方合并预检 git merge-tree 返回非空冲突列表 → 不执行 merge,标记 conflict

3.2 编译检查(semantic 冲突)

ID 场景 预期
CMP-01 合并后编译通过 cargo check exit 0 → 无 semantic 冲突
CMP-02 合并后编译失败 A 删函数 foo(),B 在调 foo() → cargo check 失败 → conflict_type=semantic
CMP-03 前端项目 tsc --noEmit 失败 → semantic 冲突
CMP-04 无构建工具的工程 跳过编译检查(无 cargo/tsc) → 不阻塞 merge

3.3 Reviewer 仲裁

ID 场景 预期
ARB-01 Reviewer 推荐 A diff_a 更完整 → resolution=a,resolved_by=reviewer
ARB-02 Reviewer 推荐 merged 两者各有价值 → resolution=merged,给出合并方案
ARB-03 Reviewer 无法判断 两者等价 → resolution=pending,留给用户
ARB-04 Reviewer 超时 LLM 调用超时 → 自动降级为 pending

3.4 冲突解决闭环

ID 场景 预期
RSV-01 用户选接受 A resolution=a,文件应用 A 的改动,B 的改动丢弃
RSV-02 用户选手动 resolution=manual,用户在 worktree 手动编辑后 commit
RSV-03 全部冲突解决 Plan.status 从 merging→done
RSV-04 前端徽章更新 AiConflictResolved 事件 → 冲突徽章消失

3.5 合并产出落回主对话

ID 场景 预期
OUT-01 无冲突合并 主对话新增 1 条 assistant 消息(merged_output)
OUT-02 有冲突合并 主对话新增 1 条 + 冲突徽章
OUT-03 展开查看子 Agent 轨迹 点击展开 → 从 ai_messages WHERE subtask_id=? 加载,按 SubTask 分组
OUT-04 折叠状态默认 新消息默认折叠,只显示摘要

3.6 命令互斥锁

ID 场景 预期
LCK-01 同目录 npm install 并发 第二个等第一个完成才执行(不并行)
LCK-02 不同目录 npm install 并行执行(锁 key 含目录)
LCK-03 cargo + npm 同目录 不互斥(锁 key 含命令名)

四、模板系统 测试用例

4.1 YAML 模板加载

ID 场景 预期
TPL-01 合法 YAML 加载 DagDef 结构完整,nodes/edges/conditions 正确解析
TPL-02 缺必填字段 nodes 为空 → 报错"模板节点不能为空"
TPL-03 依赖闭环 A→B→A → 报错"依赖存在环"
TPL-04 未知节点类型 node.type="UnknownNode" → 报错"未知节点类型"
TPL-05 内置模板加载 3 个内置模板(代码审查/bug修复/功能开发)全部加载成功
TPL-06 自定义模板 CRUD 创建→读取→更新→删除,持久化到 DB

4.2 SubflowNode

ID 场景 预期
SUB-01 嵌套子工作流执行 SubflowNode 加载子模板 → 递归执行 → 返回子工作流结果
SUB-02 子工作流审批 子工作流内的 HumanNode 审批 → 挂起 → 恢复
SUB-03 嵌套深度限制 超过 MAX_PLAN_DEPTH → 报错

4.3 新节点

ID 场景 预期
NODE-01 GitNode 创建分支 branch_name 存在,git branch 列表可见
NODE-02 GitNode commit 工作区改动已提交,git log 有新记录
NODE-03 HTTPNode GET 请求成功,返回 body 存入 NodeOutput
NODE-04 HTTPNode 超时 30s 超时 → 返回错误,不阻塞
NODE-05 NotifyNode 桌面通知 系统通知弹出
NODE-06 NotifyNode Webhook POST 到飞书/钉钉,HTTP 200

五、Git/CI 集成 测试用例

ID 场景 预期
CI-01 DockerNode 构建成功 docker run cargo build → exit 0 → 构建产物存在
CI-02 DockerNode 构建失败 docker run cargo build → exit !=0 → 返回 stderr
CI-03 PR 创建 GitNode push → API 创建 PR → PR URL 返回
CI-04 CI 状态读取 调 API → 返回 check 结果(passed/failed/pending)
CI-05 全链路 模板→分支→代码→commit→push→PR→CI→结果回显,全流程不中断
CI-06 CI 失败时 前端 CI 面板显示红色,日志可查看

六、审批政策 测试用例

ID 场景 预期
POL-01 coder+Low → auto 匹配规则 → 自动执行
POL-02 coder+High → approve 匹配规则 → 走审批
POL-03 reviewer+任意 → auto reviewer 只读工具,全部自动
POL-04 无匹配规则 降级到 auto_exec_mode 三档(向后兼容)
POL-05 策略热加载 修改策略 → 下次工具调用立即生效(不重启)
POL-06 策略冲突检测 同一 Persona+Node+Risk 有多条规则 → 优先级最高的生效

七、God 文件拆分 测试用例

ID 场景 预期
REF-01 agentic/mod.rs 拆分 拆出 compress/title/knowledge_inject 后,原文件<800 行,cargo check 通过
REF-02 context.rs 拆分 拆出 sanitize/budget/compress 后,原文件<800 行,所有 context 测试通过
REF-03 MessageList.vue 拆分 拆出 StreamRenderer/ToolCardGroup/EmptyState,vue-tsc 通过
REF-04 ChatInput.vue 拆分 拆出 MentionPopover/EnrichmentPanel,vue-tsc 通过
REF-05 拆分后行为不变 原有所有单元测试/集成测试全绿

八、端到端手动测试

ID 场景 步骤 预期
E2E-01 简单并行任务 发"先读取 main.rs 再修改 utils.rs" PlanProgress 展示 2 层,Layer0 读,Layer1 写,最终合并输出
E2E-02 并行同文件冲突 发"同时重构 auth.rs 的两个函数" 2 SubTask 并行改同文件 → 冲突徽章 → 用户选择 → 最终输出
E2E-03 取消并行任务 发消息→Plan 执行中→点停止 所有 SubTask 停止,worktree 清理,Plan.status=error
E2E-04 切换会话后台执行 发消息→切换到另一个会话 原 Plan 后台继续,PlanProgress 在原会话保留
E2E-05 非 Git 工程 在无 .git 的项目中发并行任务 降级串行执行,正常完成
E2E-06 模板驱动全链路 选"功能开发"模板→AI 执行 从模板加载工作流→创建分支→写代码→测试→PR
E2E-07 长对话不崩溃 50+ 轮对话后发并行任务 token 预算池正常,不 OOM,PlanProgress 正常展示

九、边界与异常

ID 场景 预期
EDGE-01 空 Plan decompose 返回空 Plan → 不启动 dispatch,主对话正常回复(退单 Agent)
EDGE-02 全部 SubTask 超时 Plan.status=error,前端展示超时提示,worktree 清理
EDGE-03 Git 不可用 git 命令失败 → 降级串行,日志告警,不崩溃
EDGE-04 DB 写入失败 PlanRepo.insert 失败 → 降级不落库,内存态执行,日志告警
EDGE-05 worktree 磁盘满 创建失败 → 降级串行
EDGE-06 token 预算=0 设置项 df-ai-plan-token-budget=0 → 不限制(等价无限)
EDGE-07 冲突解决时会话删除 resolve_conflict IPC 到达时会话已删 → 忽略,清理 conflict 记录