testing.short()仅返回布尔值,必须配合t.skip()或return才能跳过测试;需在函数开头检查,否则可能已执行耗时操作;子测试中不可单独使用,且不能在goroutine或defer中调用。

testing.Short() 本身不跳过任何测试,必须配合 t.Skip() 或 return 才生效。 它只是一个布尔值开关,由 go test -short 触发,不加这个 flag 时永远返回 false。
为什么 go test -short 后测试还在跑?
常见错误是只写了 if testing.Short() { } 却没在花括号里调用 t.Skip() 或 return。结果 testing.Short() 返回了 true,但后续耗时逻辑照常执行,甚至可能因超时 panic。
- 必须在测试函数**开头**检查,晚了(比如 setup 完再判断)可能已连上数据库或发起 HTTP 请求
-
t.Skip()会立即终止当前测试,但已注册的defer仍会执行——这点常被忽略,可能导致资源清理失败 - 子测试(
t.Run())里不能靠testing.Short()单独控制跳过:它反映的是整个go test进程的状态,不是每个子测试独立可配
t.Skip() 和 t.Skipf() 怎么选?
t.Skip() 接收任意数量 interface{} 参数,简单拼接;t.Skipf() 第一个参数必须是格式化字符串,类似 fmt.Printf(),适合带变量的动态原因。
- 固定原因直接用
t.Skip("requires docker") - 要嵌入环境变量或运行时值,用
t.Skipf("missing %s", os.Getenv("DB_URL")) - 错误写法:
t.Skipf(os.Getenv("REASON"))—— 若REASON含%会 panic;安全写法是t.Skipf("%s", os.Getenv("REASON"))或改用t.Skip() - 两者都必须在测试函数主 goroutine 中调用,不能在
goroutine或defer里,否则 panic
和 -run、-skip、build tag 的关系
它们解决不同层面的问题,别混用:
-
testing.Short()+t.Skip():运行时软控制,适合 CI 快反馈阶段跳过 I/O 密集型测试(如真实 HTTP 调用、大文件生成) -
go test -skip="TestIntegration"(Go 1.22+)或go test -run='^(?!TestE2E)':命令行临时过滤,不改代码,适合调试时绕开个别用例 -
//go:build integration:编译期排除,适合平台强耦合(如仅 Linux 可运行)或需额外依赖(如 CUDA)的测试文件,go test根本不编译它 -
-timeout和-short正交:加-short不会让测试自动变快,没写跳过逻辑的测试照样会被-timeout杀掉
最容易被忽略的一点:跳过逻辑必须放在测试函数最顶部,且不能依赖任何可能失败的 setup——比如先 sql.Open() 再判断 testing.Short(),连接失败时你连跳过的机会都没有。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











