Skip to content

测试与变更验证

Sub2API 的风险集中在协议兼容、跨实例状态、计费幂等和长连接生命周期。只跑受影响文件的单元测试不足以证明一次改动可以上线。

仓库现有测试层次

层次工具/入口主要验证
Go 单元测试make -C backend test-unitService、Handler、middleware、协议和错误策略
Go 集成测试make -C backend test-integrationPostgreSQL、Redis、migration、Repository、缓存一致性
前端静态检查make test-frontendESLint、vue-tsc、关键 Vitest
前端完整测试pnpm --dir frontend test:run所有 Vitest
构建make buildGo 二进制与 Vue 生产产物
真实环境 E2Ego test -tags=e2e ...已运行实例与真实/测试上游协议

根目录 make test 会运行后端和前端检查。后端 make test 还执行 golangci-lint

单元与集成标签

后端 Makefile 使用 build tags:

bash
make -C backend test-unit
make -C backend test-integration

集成测试的 Repository harness 使用 Testcontainers 启动 PostgreSQL 18 和 Redis 8,自动执行 migration。开发机没有 Docker 时会跳过,CI 中 Docker 不可用则直接失败。

这类测试适合发现:

  • PostgreSQL 三值逻辑、约束和事务问题。
  • Redis Lua、TTL、并发和缓存失效问题。
  • Ent schema 与手写 SQL 不一致。
  • migration 在空库上的最终结构错误。
  • scheduler outbox 与快照不同步。

如果改动包含 SQL、schema、缓存或事务,不能只跑 unit tag。

CI 实际门槛

.github/workflows/backend-ci.yml 当前执行:

  • 固定 Go 版本校验。
  • 后端 unit tests。
  • 后端 integration tests。
  • 前端 lint、typecheck 和关键 Vitest。
  • golangci-lint。

发布前还应本地或独立流水线补生产 build、镜像启动和 smoke test。CI 通过表示代码级门槛通过,不表示真实上游和部署配置已经验证。

按改动选择验证范围

改动最低测试额外验证
Handler/DTO对应 unit + API contract非法输入、权限、错误 envelope
PostgreSQL schema/SQLunit + integration + migration旧数据升级、锁表、回滚兼容
Redis/cacheunit + integration多实例失效、TTL、Redis 故障
调度/账号状态service + repository integrationoutbox、粘性、全部账号不可用
协议转换transform unit非流式、SSE、工具、thinking、图片
WebSocketWS unit/integration重连、帧边界、取消、连接池回收
计费billing unit + DB integrationdedup、余额、订阅、Key quota、并发
支付lifecycle/fulfillment/refund tests重复 Webhook、主动查询、Provider 历史配置
前端页面lint/typecheck/Vitest三种身份、feature flag、浏览器刷新
启动配置config/setup tests + build空库、旧库、丢 data volume、Secret 固定

协议测试矩阵

一个新模型或上游不能只测 200 OK。至少覆盖:

  • /v1/messages/v1/responses/v1/chat/completions 或目标原生入口。
  • 普通 JSON 与流式 SSE。
  • tool use、thinking/reasoning、system prompt 和多轮上下文。
  • 客户端取消、上游超时和流中错误事件。
  • requested model、upstream model、billing model 的记录。
  • 400、401、403、404、429、5xx 对 Account 状态和 failover 的影响。
  • 最大 body、最大 SSE line 和大响应读取限制。

协议测试最好使用录制/构造的确定性上游响应;真实上游 E2E 用于发现供应商行为变化,不能替代可重复单元测试。

计费不变量

每个计费变更都要证明:

  1. 同一个 billing dedup key 只扣一次。
  2. 用户费用和 Account 成本分别正确。
  3. 余额、订阅、API Key quota 和平台 quota 更新一致。
  4. 流式完成、客户端中断和上游错误有明确结算规则。
  5. usage worker 队列满时的 sync/sample/drop 策略符合配置。
  6. 价格缺失不会静默记 0。
  7. 缓存失败不会造成无限放行或重复扣费。

推荐用已知 Token 和固定价格 fixture 断言金额,不用真实模型输出做精确金额测试。

多实例不变量

单进程测试通过后,涉及共享状态的改动还要验证:

  • 两个副本同时获取用户/Account 并发槽位。
  • 一个副本修改 Account/Group,另一个副本何时看到。
  • OAuth refresh lock 只有一个 owner。
  • leader task 不重复执行,锁丢失后可接管。
  • scheduler outbox 消费延迟与全量重建恢复。
  • Settings/Provider Registry 在各副本的生效方式。
  • 滚动升级期间新旧版本能够共享 DB/Redis 数据。

如果测试环境只能运行单副本,必须把多实例风险写入发布检查并安排灰度观察。

Migration 验证

Migration 是向前执行的 SQL 文件,不应只在空数据库上测试:

  1. 从生产前一版本的脱敏 schema/数据快照启动。
  2. 执行 migration 并检查 checksum 记录。
  3. 验证大表 DDL 锁时间和回填速度。
  4. 新旧应用短时并存时,旧版本是否能读新 schema。
  5. migration 失败重试是否安全。
  6. 备份恢复后能否重新启动应用。

涉及列重命名/删除时优先使用 expand → migrate/backfill → contract,多版本分步发布。

前端验证策略

关键 Vitest 当前覆盖 OAuth callback、支付视图、Profile 和 Settings 等高风险页面,但修改其他核心页面时应补进完整 test suite,而不是只依赖现有 critical list。

浏览器验收至少包含:

  • 首次直接打开目标 URL。
  • 登录过期和多请求同时 401。
  • 普通用户尝试访问管理员页面。
  • backend/simple/payment/risk-control 各开关组合。
  • 表单重复提交、网络超时和部分保存失败。
  • 生产 build 后 lazy chunk 加载。

当前 E2E 入口注意事项

后端 Makefile 的 test-e2e 目标引用 ./scripts/e2e-test.sh,但当前仓库没有这个脚本。不要把该目标显示成功当作 E2E 已覆盖;应先补齐脚本或直接运行:

bash
cd backend
BASE_URL=http://localhost:8080 \
CLAUDE_API_KEY='<sub2api-test-key>' \
GEMINI_API_KEY='<sub2api-test-key>' \
go test -tags=e2e -v -timeout=300s ./internal/integration/...

这里的变量是 Sub2API 测试 Key,不应把上游凭证提交到仓库。未设置对应 Key 的用例会跳过,需检查测试输出中的 skip,而不是只看退出码。

发布前最小闭环

text
受影响 unit
  → integration(涉及 DB/Redis 时)
  → 前端 lint/typecheck/test
  → 生产 build
  → migration 演练
  → 单副本 smoke
  → 多实例/真实上游关键链路
  → 灰度指标与回滚验证

最终至少记录:构建版本、配置差异、migration、已运行测试、被跳过测试、smoke Request ID、已知风险和回滚触发条件。

开发流程见开发与定制入口,生产变更流程见变更、升级、备份与恢复

本文档用于帮助你理解、部署和运维 Sub2API。使用前请确认上游服务条款与当地法律要求。