Files
sanguo_moziplus_v2/docs/design/archive-2.0/test-plan-v2.6.md
T
cfdaily f62004e6a7
CI / lint (pull_request) Successful in 7s
CI / test (pull_request) Successful in 8s
CI / notify-on-failure (pull_request) Successful in 0s
chore(docs): 清理 design 目录重复文件,归档至 archive
- 27 个与 archive/archive-2.0 完全相同的外层文件删除
- spawner-monitor-design.md 外层更新版覆盖 archive 后删除
- test-plan-v2.6.md 外层版覆盖 archive 后删除
- §24 设计文档新增 §8 实验验证章节
- archive 独有文件保留不动
2026-06-13 08:32:28 +08:00

13 KiB
Raw Blame History

v2.6 测试计划

版本: v2.6.0-test-plan 作者: 司马懿(质量总监)🗡️ 日期: 2026-05-17 状态: F1-F5 已评审,F6-F18 待编码


一、测试基础设施

1.1 当前配置

  • 框架: pytest(已有 tests/ 目录,97 个用例全部通过)
  • Fixture: tmp_pathSQLite 临时数据库)、TestClientFastAPI
  • Mock 策略: 目前无 mock,全部用真实 SQLite 内存/临时文件
  • 运行方式: python3 -m pytest tests/ -q

1.2 测试分层

层级 覆盖范围 何时执行
单元测试 每个 F 的内部逻辑 每写完一个 F
集成测试 F1-F14 端到端链路 F14 完成后
E2E 验收 完整系统含前端 F18 完成后

1.3 测试规范

  • 每个 F 必须有对应的 test_*.py,测试文件与模块同名
  • 测试类按功能分组:class TestTaskCRUDclass TestTransitions
  • P0 测试必须有,P1 测试建议有但不强阻塞
  • 测试必须可重复运行(不依赖外部状态、不依赖时序)
  • 新增测试必须在 tests/ 目录下,不放在 src/

二、F1-F5 单元测试评审(已完成)

现有覆盖情况

F 测试文件 用例数 P0 覆盖 评审
F1 骨架 test_main.py 10/10 启动、健康端点、配置、Swagger 通过
F2 黑板 test_blackboard.py 39/39 CRUD、状态机、并发、WAL、事件 通过(附 2 条意见)
F3 多项目 test_registry.py 11/11 创建/删除/归档/持久化/黑板的联动 通过
F4 CLI test_cli.py 14/14 8 子命令 + admin + 错误处理 通过
F5 API test_api.py 23/23 全端点 CRUD + 状态码 + SSE 连接 通过(附 1 条意见)

总计: 97/97 通过,质量合格。

评审意见(F1-F5

BUG-1 [P1] /api/daemon/status 端点重复注册

  • 位置: main.py 第 99-111 行直接定义了 daemon_status 端点,同时 daemon_routes.py 也定义了同名路由
  • 现象: pytest 输出 Duplicate Operation ID daemon_status warning
  • 修复: 删除 main.py 中的 /api/daemon/status 端点定义,统一由 daemon_routes.py 提供
  • 影响: 不影响功能,但 Swagger 文档会混乱

OBS-1 [P2] operations.py_conn() 每次操作都新建连接

  • 位置: operations.py 全文,每次方法调用 self._conn()sqlite3.connect()
  • 现状: 单次操作用完即关,连接不池化
  • 评估: v2.6 阶段可接受(SQLite WAL + busy_timeout 足够),但如果后续 F6 ticker 30s 轮询 + 多项目并发,建议 F6 阶段引入连接池或 per-thread 连接复用
  • 行动: 不阻塞当前进度,F6 编码时再评估性能

OBS-2 [P2] queries.pyblocked_tasks_with_deps()pending_dispatchable() 存在 SQL 注入风险

  • 位置: queries.py 第 52 行和第 71 行,使用 f-string 拼接 SQL
  • 现象: f"SELECT ... WHERE id IN ({','.join('?' * len(deps))})" — 虽然 deps 来自数据库的 depends_on 字段(不是用户输入),且用了参数化占位符,但 f-string 拼接 SQL 是坏习惯
  • 评估: 当前实际安全(因为值都来自参数化 ?),但风格不好
  • 行动: 不阻塞,但后续统一改为纯参数化写法

三、F6-F18 测试计划(逐模块)

F6 Daemon Ticker — test_ticker.py

# 测试用例 P0 验证点
T1 tick 循环正常运行 30s 间隔(测试中加速),不阻塞 event loop
T2 scan_tasks 检测 pending pending → 触发调度
T3 依赖推进 blocked → pending(依赖 done 后)
T4 events 写入 每次 tick 写 daemon_tick 事件
T5 多项目轮询 tick 遍历所有 active 项目
T6 tick 异常不中断 P1 单次 tick 抛异常 → 下次 tick 继续
T7 手动 tick 端点 P1 POST /api/daemon/tick 触发即时 tick

F7 Inbox JSONL Watcher — test_inbox.py

# 测试用例 P0 验证点
T1 写入+消费 Agent 写 JSONL → 1s 内 Daemon 读取并处理
T2 truncate 消费后清空文件
T3 并发写入 多 Agent 同时写不同行
T4 损坏行恢复 P1 非法 JSON 行跳过不崩溃
T5 空文件处理 P1 空文件不触发处理

F8 健康检查 — test_health.py

# 测试用例 P0 验证点
T1 正常场景 有变更 → 无告警
T2 僵尸检测 连续 N tick 无变更 → observation 写入
T3 恢复场景 僵尸后有变更 → 告警解除
T4 多项目独立检测 P1 项目 A 僵尸不影响项目 B

F9 Agent 调度器 — test_dispatcher.py

# 测试用例 P0 验证点
T1 三级决策树 Daemon task → Full task → Sub task 正确分流
T2 调度不阻塞 spawn 用 asyncio.create_subprocess_exec
T3 队列满拒绝 active agent 数达上限 → 不调度
T4 任务优先级排序 P1 高优先级先调度

F9 Agent Spawner — test_spawner.py

# 测试用例 P0 验证点
T1 spawn 成功 子进程启动 + session 注册
T2 超时处理 超时后 kill + task_attempt 记录
T3 spawn 失败 命令不存在 → task_attempt 记录 spawn_failed
T4 session 清理 P1 子进程结束后 session 归档

F10 ActiveAgentCounter — test_counter.py

# 测试用例 P0 验证点
T1 全局上限 max_global=5 时第 6 个 acquire 失败
T2 per-agent 串行 同一 agent 第二个 acquire 排队
T3 release 恢复 release 后等待中的 acquire 成功
T4 并发竞争 P1 多 agent 同时 acquire 不超限

F11 Bootstrap 拼装 — test_bootstrap.py

# 测试用例 P0 验证点
T1 各 role 拼装 不同 role 得到不同 L0-L3 四层
T2 token 估算 拼装结果 < 4096 tokens
T3 缺失组件降级 P1 某层文件不存在 → 跳过不崩溃
T4 模板变量替换 P1 {{task_id}} 等占位符正确替换

F12 审查流水线 — test_review_flow.py

# 测试用例 P0 验证点
T1 4 级分流 high/standard/low/research 正确路由
T2 confidence 计算 分值在 0-1 区间,阈值逻辑正确
T3 升级到庞统 confidence < 阈值 → 升级
T4 审查通过 → done verdict=approved → 状态变 done
T5 审查拒绝 → 重新执行 P1 verdict=rejected → 回到 working

F13 Guardrail — test_guardrail.py

# 测试用例 P0 验证点
T1 L1 assert 通过 合规产出 → 放行
T2 L1 assert 失败 不合规产出 → 拦截
T3 L2 subagent 触发 高风险 → 二次确认
T4 配置加载 P1 guardrails.yaml 正确解析
T5 误杀恢复 P1 L2 确认通过 → 放行

F14 反驳权 — test_rebuttal.py

# 测试用例 P0 验证点
T1 反驳触发 review rejected → 反驳协商开始
T2 轮次计数 round 递增正确
T3 超轮次升级 超过 max_rounds → 庞统裁决
T4 结果写入 最终裁决写入 reviews 表

F15 经验沉淀 — test_experience.py

# 测试用例 P0 验证点
T1 一级蒸馏 任务完成 → experiences 表写入
T2 tag 匹配 相似 tag 的经验可被查询到
T3 二级触发 P1 N 条同类经验 → Skill 草稿生成
T4 过期清理 P1 deprecated 经验不被查询

F16 Skill 体系 — test_skill_loader.py

# 测试用例 P0 验证点
T1 加载 + 验证 四要素完整才加载
T2 per-project 覆盖 项目级 Skill 覆盖全局 Skill
T3 缺要素拒绝 P1 缺少 name/description/triggers/actions → 拒绝
T4 版本管理 P1 同名 Skill 版本号正确比较

F17 SSE + Hook — test_sse.py / test_hooks.py

# 测试用例 P0 验证点
T1 SSE 连接 客户端连接 → 收到初始事件
T2 SSE 4 级推送 task/agent/daemon/system 四级
T3 断线重连 P1 断线后重连 → 收到后续事件
T4 降级轮询 P1 SSE 不可用 → 轮询兜底
T5 Hook 触发 3 个触发点正确执行
T6 Hook 过滤 P1 条件不满足 → 不触发

F18 前端 Dashboard — test_frontend.pyE2E

# 测试用例 P0 验证点
T1 页面渲染 5 个页面均可加载
T2 API 集成 页面操作 → API 调用正确
T3 SSE 实时更新 后端事件 → 前端 UI 更新
T4 项目切换 切换项目 → 数据刷新

四、集成测试计划(F14 完成后)

端到端链路测试

用户提需求 → 庞统规划 → 任务写入黑板 → Agent 执行 → 
Guardrail 检查 → 审查流水线 → 反驳协商 → 完成 → 经验沉淀
# 场景 关键验证
I1 正常流程(happy path 全链路无阻断,最终 done
I2 依赖链 A→B→CA done 后 B 自动 pendingB done 后 C 自动 pending
I3 审查拒绝 → 反驳 → 通过 review rejected → rebuttal → verdict 翻转
I4 审查拒绝 → 反驳 → 超轮次 → 庞统裁决 max_rounds 后升级
I5 Guardrail 拦截 → L2 确认 → 放行 L1 fail → L2 confirm → proceed
I6 Agent 僵尸检测 无 heartbeat → observation → reclaim
I7 多项目并行 项目 A/B 同时运行,互不干扰
I8 失败重试 failed → pendingretry_count +1)→ 再次执行

集成测试基础设施

# conftest.py 需要的 fixture
@pytest.fixture
def full_stack(tmp_path):
    """完整系统:FastAPI + Ticker + Dispatcher + Spawner(mock)"""
    ...

@pytest.fixture
def mock_spawner():
    """Mock spawner,模拟 Agent 执行"""
    ...

五、E2E 验收场景(F18 完成后)

# 场景 验收标准
E1 创建项目 → 提交任务 → 查看任务板 Dashboard 实时更新
E2 全局监控页 所有项目状态汇总、活跃 Agent 数、最近事件
E3 产物仓库页 任务产出物可浏览、可下载
E4 系统配置页 运行时配置可查看、Skill 列表可管理
E5 AI 简报页 项目级 AI 总结可生成
E6 SSE 实时 所有页面操作后 SSE 实时反映

六、测试通过标准

每个 F 的单元测试通过标准

  1. 全部 P0 用例通过(硬性要求)
  2. P1 用例通过率 ≥ 80%(可协商)
  3. 无 crash / 无未捕获异常
  4. 测试可重复运行(跑 3 次结果一致)

集成测试通过标准

  1. I1-I8 全部场景通过
  2. 无死锁、无资源泄漏
  3. 并发测试无数据竞争

E2E 验收标准

  1. E1-E6 全部场景通过
  2. 前端无 console error
  3. SSE 延迟 < 2s

七、进度追踪

F 测试计划 用例设计 编码 执行 评审
F1 10 10/10 通过
F2 39 39/39 通过(附 2 条意见)
F3 11 11/11 通过
F4 14 14/14 通过
F5 23 23/23 通过(附 1 条意见)
F6 本文档 待设计
F7 本文档 待设计
F8 本文档 待设计
F9 本文档 待设计
F10 本文档 待设计
F11 本文档 本文档
F12 本文档 待设计
F13 本文档 待设计
F14 本文档 待设计
F15 本文档 待设计
F16 本文档 待设计
F17 本文档 待设计
F18 本文档 待设计