QMTV 测试规划(Go 版,P0 底册)
回答移植需求②"基于现有项目先写单元测试——移植现有测试(如果有),或另写"。现状实测:冻结版零单测,仅 4 个 API 冒烟脚本(verify_*.js)覆盖 60/239 端点。结论:以 TDD 另写为主(pms 范式),verify 断言移植为集成冒烟底册,e2e 骨架按 pms 约定立。
1. 分层测试范式(对齐 pms backend)
| 层 | 手段 | 纪律 |
|---|---|---|
| repo 层 | sqlmock(DATA-DOG/go-sqlmock);newMockDB 4 行 helper 就地定义,无共享 testutil | 断言 SQL 形状 + ExpectationsWereMet;结尾必校验 |
| service 层 | 手写 fake repo(map 内存副本);关键纪律=fake 忠实 gorp 语义(Insert 后 version=原值+1 等回写行为必须模拟,防掩盖差一缺陷) | 纯函数尽量抽出独立测(计费/解析器/提示词组装) |
| handler 层 | 不测(薄层,零业务逻辑——域包四文件铁律保证) | 装配冒烟在 main_test.go |
| 守卫 | cmd/server 三件(not_null/pointer_field/status_table),schema 六原则机器守卫 | 负样本演练留档 TECH.md §9 |
| 集成冒烟 | //go:build integration 标签真库用例(对齐 pms test/smoke_test.go;MySQL 不可用自动 skip)+ verify 移植断言 | dev-up 环境跑 |
| 全局 | go test ./... -race -count=1 纯 mock 不连外部服务 | CI 缺省档卡点 |
2. 分域单测规划(先红后绿,TDD 顺序=P 期次)
| 域 | 期 | 必测纯函数/场景(首批) |
|---|---|---|
| auth | P1 | scrypt 往返(已有)、JWT 双格式(已有)、refresh 轮换状态机(签发→轮换→旧 token 拒→过期拒→改密全撤销)、注册送积分+邀请返佣、限流窗口边界 —— P1 已落地(service 11 场景 + repo sqlmock 7 + jwtsecret 3 + main_test 装配 4 + integration 全链/C8 互操作;限流 4 场景见 gateway 包) |
| credits | P1 | CAS 扣款成功/余额不足 402/版本冲突重试/退款 refunded 防重/balance_after 台账一致性/COSTS×settings 双层计费价 —— P1 已落地(billing 6 + repo sqlmock 6 + service fake 6 + integration 并发不超扣/台账对账/零台账);差异收口(PRD v1.3):CAS 谓词仅 credits>=? 下无版本冲突路径,RunWithRetry 定稿不引入;退款防重=credits.Refund 唯一口(F9),P2 W7 落地 |
| task | P2 | Mock 规则拆解(场次切分/人名提取/景别轮转——preprocess.js 逐规则移植对拍)、parser.parseSplit 宽容解析(60 镜上限/img 1200 字)、LLM 拆解失败回退链 —— P2 执行中(2026-10-18 立项) |
| generation | P2 | ratio→尺寸映射、videoCost(secs)、providers 三响应形态分发、轮询状态词判定、Mock SVG/WAV 字节头 —— P2 执行中 |
| export | P2 | 导出积分×段数、export_tasks 全链(期次随 TECH 域包表 P2,v1.3 对齐) |
| director/fusion/workbench | P3 | 双表通路 _tbl 路由(Go videoSmart 显式表参数,P2 期初定型)、队列 recoverQueue、审片双入口 |
| billing-admin | P4 | 充值到账+两级返佣、提现 7 态状态机、白名单键过滤(credit-settings PUT) |
3. verify_*.js 断言移植矩阵(约 60 端点 → Go 集成冒烟)
现有脚本逐断言移植为 Go 集成测试(integration 标签,dev-up 环境执行;脚本本身保留在冻结区不动)。「可测期次」= 该端点 Go 实现落地期。端点数为约数(唯一路径口径):分项 ~28+~20+~6+~9 含同端点多场景重复计数,去重后约 60。
| 源脚本 | 断言场景 | 端点数 | 可测期次 | Go 冒烟形态 |
|---|---|---|---|---|
| verify_v14.js | 火花 join/me/阶梯;工作台三工具+列表;经典审片+回读;导演项目→分镜→导演审片+资产队列挂起;组织申请→审批→邀请→加入→非 owner 改角色拒→项目共享→成员可见 | ~28 | P3(组织面 P4) | Go httptest 或真库 curl 链 |
| verify_v17.js | 企业看板/trend/双排行;writers 排序+主页;showcase 发布/撤下;全站搜索;剧本库新字段;素材夹+10GB 容量+assign;非 owner 建组拒;错密码改邮箱拒 | ~20 | P4 | 同上 |
| verify_eval.js | evaluations/config;txt 上传;GBK 非法字节回退不崩;深度评估 stage 推进轮询;报告下载含逐集证据 | ~6 | P3 | 同上(stage 推进用 pollUntil) |
| verify_lib.js | genres 配置;种子幂等回填;五维筛选;详情目录;rating/new 排序;管理端 CRUD+用户端 404 | ~9 | P3 | 同上 |
| 新增(脚本空白,各期验收补) | 登录/refresh 真轮换/改密;扣款 402/退款防重;拆解 v2 双引擎+回退;视频 v2 按秒计费;SSE 五类事件(Go 侧 client 断言帧格式);4 个 ZIP 端点结构;充值→审核→返佣→提现全链;模型接入 18 端点 | ~179 | 随 P1~P4 | 每期验收新增集成用例 |
4. E2E 约定骨架(正式版 P5,按 pms docs/test 三文档体系)
- 初始世界:独立库
qmtv_e2e(dev-up 变体建库导 full+seed);账号矩阵=seed 三账号+按需 API 注册;业务单据不进种子,一律 API 造数(防绕过状态机)。 - 外部 API 零真实调用(用户指令 2026-10-17,instructions.txt):e2e/集成测试局限在本系统内,外部 API 调用会引起费用——全部 mock。LLM/图像/视频供应商一律走 Mock 通道(测试环境不配 model_endpoints 的 api_key,或显式 provider_routing=mock);网络出口断言(providers 适配层的真实 HTTP 调用)用 httptest 本地假服务器验证协议形状,绝不打真实供应商;CI 环境保持零 Key(
llm.isAvailable()==false全站 Mock 路径),真实供应商连通性只允许人工在管理后台用「测试连接」单次验证。 - 确定性:时间用相对量;金额固定值;禁按自增 id 断言(qmtv 全字符串 ID 天然满足)。
- 隔离:
e2e-reset(DROP/CREATE+导入)/e2e-seed(快恢复);失败不自愈必须 reset;连跑两轮间隔 reset。 - 明令禁止:禁 sleep 等事件链(一律 pollUntil,超时 20s——评估 stage 推进/视频轮询场景);禁 retry;5xx 直接抛响应体。
- 场景登记:
docs/test/e2e-qmtv-场景清单.md行格式对齐 pms(场景ID E2E-XXX-NN|FSD 功能 ID|主干路径|关键断言|现状);缺陷修复覆盖优先并入现有场景加断言。 - Playwright 引入与否:P5 决策——前端冻结的前提下,API-first 断言册已覆盖回归需求;截图册(操作手册配图)可单独用 Playwright 走真 UI,不与断言册共用一行代码。(二十六期已落地:前端演进后 Playwright 双配置入位——断言册 11 用例〔auth 4/dashboard/generation 2/credits/admin/nav/spark;含 setup 册 14〕 + 截图管线,约定见 docs/test/e2e-测试约定.md;本条 P5「前端冻结」前提已随 TS 演进裁决失效,双配置即终态。二十七期勘误:二十五/二十六期宣称「13 用例」系计数漂移,11 为亲数权威口径。)
5. CI 闸门(scripts/ci.sh,已落地)
| 档 | 内容 | 时长 |
|---|---|---|
| –fast | build+vet+check_consistency+冻结契约守卫(frozen_contract_check)+守卫三件 | <1min |
| 缺省 | +全量 go test -race -count=1 | ~2min |
| –with-env | +dev-up+healthz+登录真断言+refresh 轮换断言(新旧 RT 不同/旧复刷 401)+query token 兜底 | +1min |
| –e2e | =–with-env 全部 + e2e 环境(qmtv_e2e/:3301/frontend/dist 托管)+ Playwright 断言册——显式 opt-in,浏览器二进制不进日常闸门(二十六期第四档) | +2min |
JUnit 双断言(场景总数≠期望也阻断)随 P5 e2e 落地引入。