应使用 testify/assert/require 替代手写 if got != want { t.Errorf(...) },可省70%样板代码并提供上下文diff;但需先安装依赖、正确导入、区分assert(继续执行)与require(panic终止)、注意类型敏感性、浮点用InDelta、结构体含未导出字段用JSONEq、JSON响应优先用JSONEq而非Equal、自定义断言函数必加t.Helper()。

直接用 testify/assert 替代手写 if got != want { t.Errorf(...) },能省掉 70% 的样板代码,错误信息也自带上下文和 diff;但必须先装依赖、拆开求值、分清 assert 和 require 的控制流语义,否则测试会静默失败或崩溃。
安装与导入不能跳过
Go 没有内置断言,testify/assert 不是标准库。没装就 import 会导致 go test 报 cannot find package "github.com/stretchr/testify/assert"。
- 执行
go get github.com/stretchr/testify/assert(推荐加@latest锁版本) - 确保
go.mod里出现该依赖,CI 环境才不会构建失败 - 别只 import
assert却漏了require——需要提前终止时得额外 importgithub.com/stretchr/testify/require
assert.Equal 不是万能的,类型和结构要小心
assert.Equal 底层用 reflect.DeepEqual,对 Go 类型系统很敏感,容易误报或漏报。
-
int和int64直接比会失败,改用assert.EqualValues或显式转换 -
[]int(nil)和[]int{}默认判为不等,想通过就得先require.Len(t, slice, 0)再校验内容 - 浮点数必须用
assert.InDelta(t, got, want, 1e-9),Equal会因精度差异直接挂 - 结构体含未导出字段时,
Equal无法访问,得用assert.JSONEq序列化后比字符串
assert 和 require 不是风格选择,是控制流设计
用错一个,整个测试逻辑可能失效:前者记录错误继续跑,后者 panic 并终止函数。
立即学习“go语言免费学习笔记(深入)”;
- 前置条件(如 JSON 解析成功、DB 连接非 nil)必须用
require.NoError(t, err),否则后续assert.Equal可能 panic - 业务结果校验(如返回用户 Name 字段是否为 "Alice")适合用
assert.Equal,即使某一项错,也能看到其他字段是否符合预期 - 别在
defer里调require.Xxx——panic 会被 recover 拦住,断言失效 - mock 行为验证要用
require.True(t, mockObj.AssertExpectations(t)),否则没调用也不会报错
JSON 响应别用 assert.Equal 硬比字符串
API 返回体字段顺序、空格、float 小数位稍有变动,assert.Equal 就失败,但业务其实没坏。
- 一律改用
assert.JSONEq(t, expectedJSON, string(body)),它解析后按语义比较,忽略格式细节 - 输入非法 JSON 会 panic,所以先
require.NoError(t, json.Unmarshal(body, &dummy))做合法性兜底 - 响应含时间戳或 UUID 时,不能靠 JSONEq 自动处理,得先
strings.ReplaceAll或正则抹除再喂给JSONEq - 如果接口要求严格字面量一致(比如签名计算),反而该回退到
assert.Equal+strings.TrimSpace
最常被忽略的是 t.Helper() ——只要把断言封装成自定义函数,就必须加这一行,否则失败堆栈指向 testify 源码,而不是你写的测试用例那行。


















