t.Run用于在单个测试函数中划分独立子测试,提升失败定位精度与输出可读性,支持嵌套分组、独立计时和失败标记。

为什么测试里要用 t.Run
因为单个测试函数里混着多个逻辑分支时,t.Run 能让失败定位更准、输出更清晰。不加它,一旦某个断言失败,整个测试就中断,后面用例根本跑不到;加了它,每个子测试独立运行、独立计时、独立标记失败,还能嵌套分组。
t.Run 的基本写法和参数含义
签名是 func (t *T) Run(name string, f func(t *T)) bool,第一个参数是子测试名(建议用可读字符串,别用变量拼接),第二个是实际执行的函数。注意:这个函数必须接收且只接收一个 *testing.T 参数,不能多也不能少。
func TestCalculate(t *testing.T) {
t.Run("positive numbers", func(t *testing.T) {
got := Add(2, 3)
if got != 5 {
t.Errorf("expected 5, got %d", got)
}
})
t.Run("negative numbers", func(t *testing.T) {
got := Add(-1, -2)
if got != -3 {
t.Errorf("expected -3, got %d", got)
}
})
}
- 子测试名里别含空格或斜杠(某些 IDE 或
go test -run过滤会出问题) - 子测试内部不能再调
t.Fatal—— 它会让当前子测试立刻终止,但不影响其他子测试运行 - 如果想让某个子测试跳过,用
t.Skip(),不是return
嵌套 t.Run 和表格驱动测试怎么配合
最常用场景就是表格驱动测试(table-driven tests)。外层 t.Run 按用例分组,内层按输入组合展开,结构干净,错误信息带上下文。
传媒企业网站系统使用热腾CMS(RTCMS),根据网站板块定制的栏目,如果修改栏目,需要修改模板相应的标签。站点内容均可在后台网站基本设置中添加。全站可生成HTML,安装默认动态浏览。并可以独立设置SEO标题、关键字、描述信息。源码包中带有少量测试数据,安装时可选择演示安装或全新安装。如果全新安装,后台内容充实后,首页才能完全显示出来。(全新安装后可以删除演示数据用到的图片,目录在https://
func TestParseURL(t *testing.T) {
tests := []struct {
name string
input string
wantHost string
wantErr bool
}{
{"empty string", "", "", true},
{"valid http", "http://example.com", "example.com", false},
{"valid https", "https://api.test:8080/path", "api.test", false},
}
for _, tt := range tests {
tt := tt // 必须复制,否则闭包里用的是循环末尾的值
t.Run(tt.name, func(t *testing.T) {
u, err := url.Parse(tt.input)
if (err != nil) != tt.wantErr {
t.Fatalf("Parse() error = %v, wantErr %v", err, tt.wantErr)
}
if !tt.wantErr && u.Host != tt.wantHost {
t.Errorf("Parse().Host = %v, want %v", u.Host, tt.wantHost)
}
})
}
}
- 循环变量
tt必须显式重声明(tt := tt),否则所有子测试共享同一个地址,结果全错 - 子测试名尽量体现输入特征,比如
"https with port"比"case 2"有用得多 - 不要在子测试里用
t.Parallel()后再操作共享资源(如全局 map、文件句柄),容易竞态
常见报错和调试陷阱
最常遇到的是 test executed panic: runtime error: invalid memory address or nil pointer dereference,往往是因为子测试里用了未初始化的依赖对象,或者外层 setup 逻辑没在每个子测试里重做。
立即学习“go语言免费学习笔记(深入)”;
-
t.Run不自动继承外层的t.Setenv或t.Cleanup—— 如果子测试需要环境变量或清理动作,得自己调 - 用
go test -run=TestFoo/positive可以只跑匹配子测试名的部分,但名字里有正则特殊字符(如.、[)要转义 - 子测试里调
t.Log输出的内容,只有该子测试失败时才一并打印;成功时默认不显示,避免日志刷屏









