Files
2026-07-22 16:51:23 +08:00

2.3 KiB

测试规范

Go 后端测试约定。

  • 新逻辑配 table-driven 测试,用例含名字、输入、期望值;go test ./... 全绿才算完成。
  • 断言失败时输出 got/want 对比,便于定位。
  • 辅助函数标注 t.Helper(),清理动作用 t.Cleanup()

上传接口边界测试

  • “文件最大 N 字节”与 HTTP 请求体上限不是同一个契约:multipart boundary、 part header 和文件名会额外占空间。路由级 body limit 必须为封装开销留余量, service 再对文件字节数执行精确上限。
  • 新增或修改上传接口时,完整路由测试至少覆盖:恰好 N 字节成功、N+1 返回 413、空文件返回 400、伪造扩展名返回 415。
  • 内容校验深度与威胁模型匹配:管理员向自己租户上传、由上游域名托管的低价值 资源,扩展名白名单 + 魔数嗅探即可,不引入完整解码/结构校验 (2026-07 IdP 图标曾过度实现后精简,见 idp-icon-upload.md)。
  • 临时远端资源使用服务端随机名,测试相同客户端文件名不会复用上游对象;清理接口 只接受该功能生成的不可猜测标识,不能因共享 images/ 前缀删除其他业务资产。

多步远端写入测试

  • 创建 A → 配置 B 这类流程至少覆盖:创建失败、B 失败且 A 回滚成功、B 失败且 A 回滚失败/状态未知。只有确认回滚成功才能返回普通失败。
  • 部分成功响应必须有稳定机器码和关联 ID,前端据此保留已被 A 引用的临时资源; 底层上游错误只进服务端日志,测试断言不会泄露到 HTTP body。

常见坑::memory: SQLite 每个连接是独立库

症状:被测代码里有异步 goroutine 写库(如日志异步落库)时,测试偶发 no such table: xxx

原因:glebarez/sqlite 的 :memory: 数据库按连接隔离;GORM 连接池为新 goroutine 开新连接时,拿到的是一个没跑过 AutoMigrate 的空库。

修复:测试 helper 建库后锁单连接,生产文件库不受影响:

sqlDB, _ := db.DB()
sqlDB.SetMaxOpenConns(1) // :memory: 每连接独立库,异步写复用同一连接

预防:测试涉及「后台 goroutine 写库」时一律加此设置(参照 internal/api/router_test.go 与 internal/service 各测试 helper);异步写路径同时拆出同步内核函数(如 record / Record)供测试直调断言。