最稳妥做法是用 httptest.newunstartedserver 或绑定 localhost:0 启动服务,端口由系统自动分配;数据库用 sqlite 内存模式或 testcontainers-go 临时容器;用 resty/v2 发送结构化请求并校验响应;按 handler 分组+子测试覆盖多场景;用 testify/assert 精准断言错误响应体和 json 格式;时间敏感逻辑需注入可控 time.now。
用 httptest.server 启动真实服务再发请求
集成测试阶段必须启动一个可访问的 http 服务,但不能是生产配置下的全量 server。直接用 httptest.newunstartedserver 或绑定 localhost:0 是最稳妥的做法,端口由系统自动分配,避免冲突。
常见错误是手动写死端口(比如 :8080),CI 环境里多个 job 并行跑就直接报 address already in use;或者用 http.ListenAndServe 启动后没加 defer srv.Close(),导致后续测试无法复用端口。
- 启动后立刻读取
srv.URL,所有请求都基于这个地址构造 - 数据库连接必须可控:SQLite 内存模式(
sqlite3://:memory:)或 testcontainers-go 拉起临时 PostgreSQL 容器 - 每个测试开始前清空表(
TRUNCATE users, posts),别依赖“上一个测试留下的数据”
用 resty/v2 发送结构化请求并校验响应
标准库 net/http 写 API 测试太底层:要自己拼 query、序列化 body、解析 JSON、检查 status code——重复代码多,易出错。改用 resty/v2 后,一行就能发带 header、query、body 的请求,并自动解 JSON 到 struct。
容易踩的坑是把 SetBody 当成万能接口,传 map[string]string 导致字段名大小写不匹配或嵌套丢失。实际应定义明确 struct,让编译器帮你检查字段名和类型。
- 设置全局 client 超时:
resty.New().SetTimeout(5 * time.Second) - 敏感 header(如
Authorization)不要硬编码,从环境变量或 test helper 注入 - 用
resp.StatusCode()和resp.Body()做断言,别只看 err 是否为 nil
按 handler 分组 + 子测试覆盖多场景
一个 TestGetUserHandler 函数里塞十几个 if-else 断言,既难读又难定位失败点。Go 原生 t.Run() 就是为此设计的:每个子测试独立计时、独立失败、独立日志输出。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
典型结构是外层 setup 共享 router 和 DB,内层用 t.Run 区分 “正常用户”、“ID 不存在”、“未授权访问” 等路径。注意子测试之间不能共享可变状态(比如共用一个 map 记录请求次数),否则并发跑会出竞争。
- 子测试名用下划线命名法,如
"returns_404_for_missing_id",方便 grep 定位 - setup 逻辑(如初始化内存 DB)放在
t.Run外,避免每个子测试都重建连接 - 需要清理资源的测试(如创建了临时文件),在子测试末尾用
defer执行
测试失败时快速定位是哪一层崩了
API 测试挂了,你得立刻知道是 handler 逻辑错了、中间件拦截了、DB 查询空了,还是响应格式不对。靠 print 日志效率低,也不适合 CI。
推荐组合:用 testify/assert 替代原生 t.Errorf,它能在失败时自动打印期望值和实际值;对 JSON 响应,用 assert.JSONEq 比较字符串,忽略字段顺序;对错误响应体,先 assert status code,再 assert error message 字段是否存在。
- 别在测试里用
log.Printf打印中间值——CI 日志刷屏且无结构 - HTTP 错误响应体往往带
{"error": "xxx"},断言时别漏掉顶层 key - 时间敏感逻辑(如 token 过期)必须用可注入的
time.Now替换,否则测试结果不稳定
测试最难的不是写断言,而是让每个测试真正隔离:DB 数据、HTTP 状态、时间、随机数、临时文件——这些都要显式控制,而不是指望“它刚好能过”。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










