PRD-SAMPLE 测试用例
状态:Draft | Frozen(待定) · 本页与 测试用例-MD 严格 1:1,不压缩 · 一条用例=一个原子验证点
| 标记 | 含义 |
|---|---|
| P0 | 阻断级,不过则不通过 |
| 真Key | 打真实上游,证"真能用" |
| 抓包 | 假上游,只证"字段对",不证能用 |
| BLOCKED | 未实现,非通过非跳过 |
0 全局约定
- 工作目录 / 命令前缀:所有命令在
deepseek-claude-setup/目录下跑(cwd 固定)。 <真key>等占位:真实凭据通过环境变量DEEPSEEK_API_KEY传入,禁止写进文件或日志。- 环境隔离:每条用例建临时配置目录、部署 proxy bundle、随机端口起网关,不碰真实 ~/.deepseek-claude(代码依据 provider-smoke.js:21,137-140)。
- 两类证据:
真Key=打真实上游证"真能用";抓包=假上游恒回固定值只证"字段对",不证能用。 - 门禁句(必写):发「PRD-SAMPLE 通过」必须全部真 Key 阻断用例(TC-003、TC-013)全绿;capture-only 不发通过。
- 失败统一五类:preflight / gateway / provider / client / cleanup(按失败最早环节归唯一一类;cleanup 一票否决)。
0.5 测试阶段编排
| 阶段 | 测什么点 | 包含用例 | 门禁 |
|---|---|---|---|
| 阶段0 资格地基(不费Key) | 底层 patcher/restore 边界 | TC-001… | 不过 → 全流程停 |
| 阶段1 连通(先证明能连) | gateway 直连 + 客户端最简连通 | TC-003… | 全过 → 进阶段2,否则停 |
| 阶段2 能力(简单任务测开关/切换) | 思考/强度/工具/换模型 | TC-008… | 全过 → 进阶段3 |
| 阶段3 复杂长链路 | 明确长任务 TASK-LONG-TODO(各客户端各一) | TC-013、TC-014 | 全过 → 通过 |
| 贯穿·安全 | 配置不被改/不泄密/清理 | TC-020… | 任一不过 → 对应用例一票否决 |
模块 B · 真 Key 基础连通
TC-003
网关健康接口在真实 Key 下返回正确 provider 与 model(只验这一个原子点)
1用例身份与前提
- 所属模块/阶段
- 模块 B 真 Key 基础连通 / 阶段1 连通
- 优先级
- P0 阻断
- 证据类型
- 真Key
前置条件
- Node ≥16,仓库可跑 npm
- 有效 DeepSeek Key 已
export DEEPSEEK_API_KEY=<真key> - 本机 22000-22999 端口段无占用(provider-smoke.js:21 随机取该段)
- 无其它进程在写 ~/.deepseek-claude
2如何执行
测试数据(精确字面值)
- 完整命令:
DEEPSEEK_API_KEY=<真key> PROVIDER_SMOKE_PROVIDER=deepseek npm run smoke:provider(cwd:deepseek-claude-setup/) - 隐含默认:model=
deepseek-v4-pro(provider-smoke.js:94 → provider.models[0],deepseek.js:41);thinking=enabled(provider-smoke.js:101-102);effort=high(provider-smoke.js:108 写死)
测试步骤
- 动作:执行上述命令stdout 出现
-- live provider smoke: DeepSeek (deepseek-v4-pro) --(provider-smoke.js:114) - 动作:脚本建临时配置目录、部署 proxy bundle、随机端口起网关网关 ≤60s 起来,
proxyManager.getHealth()返回 health 对象(provider-smoke.js:103-117) - 动作:脚本执行
assertOk('gateway health', health.provider==='deepseek' && health.model==='deepseek-v4-pro')(provider-smoke.js:118)health.provider严格 ==="deepseek"且health.model严格 ==="deepseek-v4-pro" - 动作:观察该断言 stdout打印一行
OK gateway health(provider-smoke.js:78),未抛错退出
3如何判定
通过标准
步骤3布尔为 true 且步骤4打印
OK gateway health,进程未因此 exit 1失败判定与归类
- 打印
gateway health failed: <JSON>→ provider/model 不符 → gateway(附 redact health JSON) - exit 2 → 缺 Key(前置2未满足)
- 网关 60s 未起 → gateway(启动超时)
后置/清理
脚本 finally
proxyManager.stop() + fs.rmSync(tmp)(provider-smoke.js:137-140)证据产物
smoke 全量 stdout(含 OK 行)+ 退出码
代码依据:provider-smoke.js:94,101-118;deepseek.js:41
模块 D · 真 Key Codex 闭环(复杂长链路)
TC-013
真实 Codex 经网关打真实 DeepSeek,在 20 轮内完成 TASK-LONG-TODO 并自测自修到 ALL TESTS PASS
1用例身份与前提
- 所属模块/阶段
- 模块 D 真 Key Codex 闭环 / 阶段3 复杂长链路
- 优先级
- P0
- 证据类型
- 真Key
前置条件
- 阶段1、阶段2 全过
- 有效
DEEPSEEK_API_KEY,可执行codexCLI(preflight 通过)
2如何执行
测试数据(精确字面值)
- 任务名称:TASK-LONG-TODO —— 从零实现"待办 CLI 工具 + 自带测试 + 自跑自修复"
- 任务类型:真实多步骤编程 agent 任务(看懂需求→写多文件→自运行测试→读报错→自修复→直到通过)
- 覆盖周期:约 3~20 个工具轮、约 5~15 分钟
- 轮数规则(写死):一轮 = 网关日志一条
RESPONSES_DONE(runner grep 计数);最少 3 轮、最多 20 轮封顶;超 20 轮未收敛 = 失败,归类 client(模型未在时限收敛),与接入失败分开(不评模型质量)
每一轮发什么 / 期望什么(逐轮写死):
| 轮次 | 发给模型的内容 | 期望结果(可观测) |
|---|---|---|
| 第 1 轮 | 首轮 verbatim prompt 全文(见下) | 模型发起写文件工具调用,创建 todo.js |
| 第 2 轮 | (agent 自驱,无新增人输入;上下文延续) | 模型创建 test.js,内含 ≥3 处 assert 且有一处同时读 todo.js+todo.json |
| 第 3 轮 | (agent 自驱)执行 node test.js | 模型实际跑测试,stdout 可见测试结果 |
| 第 4~N 轮(若测试未过) | (agent 自驱)按报错改代码后重跑 | 每轮改 1 处后重跑,逐步收敛 |
| 最后一轮 | (agent 自驱)最终运行 | stdout 含精确行 ALL TESTS PASS |
首轮 verbatim prompt(一字不差,照抄发送):
在当前目录用 Node.js 完成一个命令行待办工具,下面要求全部做完:
1. 写 todo.js,可执行 CLI,支持三个子命令:
- node todo.js add "<内容>":追加一条待办到当前目录 todo.json
(todo.json 是 JSON 数组,每条形如 {"id":1,"text":"写文档","done":false})
- node todo.js list:按 id 升序打印全部待办,每行格式:
未完成 -> [ ] 1 写文档
已完成 -> [x] 2 修bug
- node todo.js done <id>:把该 id 的待办 done 改为 true
2. 写 test.js,不依赖任何第三方库,只用 Node 内置 assert,覆盖:
- add 两条后 list 输出恰好两行且按 id 升序
- done 第 1 条后,该条在 list 里变成 [x]
- 必须有一个用例同时读取 todo.js 和 todo.json 两个文件内容后再做断言
- 全部断言通过后,最后一行精确打印一行:ALL TESTS PASS
3. 运行 node test.js;若失败,修改代码重试,直到看到 ALL TESTS PASS 为止。
测试步骤
- 动作:执行
DEEPSEEK_API_KEY=<真key> CLIENT_E2E_PROVIDER=deepseek CLIENT_E2E_TARGETS=codex-tool CLIENT_E2E_LONG=1 npm run e2e:clientsrunner 追加 codex-long case,临时 workspace 起隔离 Codex,把首轮 prompt 原文发给模型 - 动作:等模型多轮执行网关日志出现 ≥3 次
RESPONSES_DONE且 ≤20 次 - 动作:等结束或 900000ms 超时15 分钟内结束,未超时
- 动作:runner 读临时 workspace存在
todo.js/test.js/todo.json,模型自跑node test.js输出含精确行ALL TESTS PASS - 动作:runner 独立复跑
node test.js(模型猜不到会复跑)复跑退出码 0 且 stdout 含ALL TESTS PASS - 动作:grep 本次网关日志切片不含本次
RESPONSES_FAILED
3如何判定
通过标准
步骤2轮数∈[3,20] 且 步骤3未超时 且 步骤4产物齐+模型
ALL TESTS PASS 且 步骤5独立复跑也 ALL TESTS PASS 且 步骤6无 RESPONSES_FAILED失败判定与归类
- 超20轮/超时/独立复跑不过 → client(模型未收敛或谎报)
- 三文件缺但有 ALL TESTS PASS 文本 → client(echo 作弊,被步骤5抓出)
- 有
RESPONSES_FAILED→ gateway/provider(发出点 proxy/clients/codex-responses.js:229) claude-long等 target runner 未实现 → BLOCKED-待实现,不得标 PASS/SKIPPED
后置/清理
随 run 末尾删除临时根目录
证据产物
报告 + redact 日志切片(含 RESPONSES_DONE 计数)+ 临时 workspace 三文件快照(不含 key)
代码依据:client-e2e.js:242,256;轮信号 RESPONSES_DONE 见 proxy/clients/codex-responses.js:229;任务定义见本用例测试数据
TC-014
真实 Claude Code 经网关打真实 DeepSeek,在 20 轮内完成 TASK-LONG-TODO 并自测自修到 ALL TESTS PASS
1用例身份与前提
- 所属模块/阶段
- 模块 D 真 Key Codex 闭环 / 阶段3 复杂长链路
- 优先级
- P0
- 证据类型
- BLOCKED(target
claude-longrunner 未实现,非通过非跳过)
前置条件
- 阶段1、阶段2 全过
- 有效
DEEPSEEK_API_KEY,可执行claudeCLI(preflight 通过)
2如何执行
测试数据(精确字面值)
- 任务名称:TASK-LONG-TODO —— 与 TC-013 同题,换 Claude Code 客户端跑以便横向对比
- 当前状态:
client-e2e.js暂未实现claude-longtarget 的多轮 runner,无法执行该用例 - 首轮 verbatim prompt:同 TC-013 原文(一字不差,照抄发送)
测试步骤
- 动作:执行
DEEPSEEK_API_KEY=<真key> CLIENT_E2E_PROVIDER=deepseek CLIENT_E2E_TARGETS=claude-tool CLIENT_E2E_LONG=1 npm run e2e:clientsrunner 报claude-longtarget 未实现并标 BLOCKED,不进入多轮 - 动作:检查报告该 case 状态状态记为
BLOCKED-待实现,未伪装 PASS 或 SKIPPED
3如何判定
通过标准
该 target runner 实现并补齐后,转用 TC-013 同口径标准评估;当前状态合法值仅为 BLOCKED
失败判定与归类
claude-longtarget runner 未实现 → BLOCKED-待实现(不得标 PASS/SKIPPED)- 若被标成 PASS 或 SKIPPED 掩盖未实现 → 视为认证作弊,门禁拦截
后置/清理
无产物生成;无临时目录需清理
证据产物
报告中该 case 的 BLOCKED 状态行 + 未实现原因
代码依据:client-e2e.js:242,256(target 分发未覆盖 claude-long 分支)
别家怎么减
本家(DeepSeek)最全样板;别家同 N 条结构按真实 capabilities 人工减/换。
| 别家差异(依据 provider 定义 文件:行) | 受影响用例及如何减/换 |
|---|---|
智谱 BigModel capabilities.thinking=false(zai.js:38) | TC-003 删去 thinking=enabled 断言;改为断言请求体 mustNotHave thinking 字段 |
Kimi capabilities.effort=false(kimi.js:35) | TC-003 删 effort=high 默认值校验;其余 provider/model 断言保留 |
| 某 provider 未提供 Codex 客户端路径(runtime-config.js path=null) | TC-013 对应 codex-long 标 SKIPPED;若 runner 未实现则标 BLOCKED,不得 PASS |
标准化实质:结构、13 字段、命令骨架、判定口径对所有家一致;别家在本家这套上按其真实 capabilities 人工减/换字段断言(参照断言库规则,非自动框架)。
本页给人查阅,全部内容来自 测试用例-MD(每条带代码依据 文件:行),仅翻译排版、未增删事实。一条用例=一个原子验证点,13 字段,每步动作配预期。