跳转到主要内容

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 期次)

域期必测纯函数/场景(首批)
authP1scrypt 往返(已有)、JWT 双格式(已有)、refresh 轮换状态机(签发→轮换→旧 token 拒→过期拒→改密全撤销)、注册送积分+邀请返佣、限流窗口边界 —— P1 已落地(service 11 场景 + repo sqlmock 7 + jwtsecret 3 + main_test 装配 4 + integration 全链/C8 互操作;限流 4 场景见 gateway 包)
creditsP1CAS 扣款成功/余额不足 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 落地
taskP2Mock 规则拆解(场次切分/人名提取/景别轮转——preprocess.js 逐规则移植对拍)、parser.parseSplit 宽容解析(60 镜上限/img 1200 字)、LLM 拆解失败回退链 —— P2 执行中(2026-10-18 立项)
generationP2ratio→尺寸映射、videoCost(secs)、providers 三响应形态分发、轮询状态词判定、Mock SVG/WAV 字节头 —— P2 执行中
exportP2导出积分×段数、export_tasks 全链(期次随 TECH 域包表 P2,v1.3 对齐)
director/fusion/workbenchP3双表通路 _tbl 路由(Go videoSmart 显式表参数,P2 期初定型)、队列 recoverQueue、审片双入口
billing-adminP4充值到账+两级返佣、提现 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 改角色拒→项目共享→成员可见~28P3(组织面 P4)Go httptest 或真库 curl 链
verify_v17.js企业看板/trend/双排行;writers 排序+主页;showcase 发布/撤下;全站搜索;剧本库新字段;素材夹+10GB 容量+assign;非 owner 建组拒;错密码改邮箱拒~20P4同上
verify_eval.jsevaluations/config;txt 上传;GBK 非法字节回退不崩;深度评估 stage 推进轮询;报告下载含逐集证据~6P3同上(stage 推进用 pollUntil)
verify_lib.jsgenres 配置;种子幂等回填;五维筛选;详情目录;rating/new 排序;管理端 CRUD+用户端 404~9P3同上
新增(脚本空白,各期验收补)登录/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,已落地)

档内容时长
–fastbuild+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 落地引入。