testing.short()仅在go test -short时返回true,需在每个测试函数开头显式判断并调用t.skip()才能跳过,否则无效;它不自动识别耗时、不作用于testmain或defer,也不影响未检查的测试。

testing.Short() 不会自动跳过任何测试,必须在每个测试函数里显式判断并调用 t.Skip() 或提前 return,否则加了 -short 也照跑不误。
testing.Short() 到底返回什么、什么时候生效
testing.Short() 是一个纯函数,只看命令行是否带 -short 参数:启动时没加,它永远返回 false;加了就返回 true。它不感知测试耗时、不自动识别“慢”,也不影响其他测试函数——只对当前函数有效。
常见错误是把它当全局开关,比如在 TestMain 里查,或放在 defer 里判断。这两种写法都无效:TestMain 没有 *testing.T,defer 执行太晚,DB 连接、HTTP server 启动可能已经失败了。
- 必须写在测试函数最开头(
func TestXxx(t *testing.T)进入后第一件事) - CI 脚本里常用
go test -short -timeout=30s ./...,但 timeout 不会触发testing.Short(),只是防止卡死 - 如果测试没检查
testing.Short(),哪怕你加了-short,它照样执行完整逻辑
t.Skip() 和 return 的区别:defer 是否执行
调用 t.Skip() 会立刻终止当前测试函数,标记为 SKIP,但已注册的 defer 仍会运行;而 return 是普通退出,defer 同样执行——两者在这点上行为一致。
关键差异在于语义和日志:t.Skip("reason") 会在测试输出里明确写 “skipped: reason”,方便 CI 日志归类;return 则静默退出,无记录。
- 推荐用
t.Skip(),尤其涉及资源清理(如t.Cleanup())时,它更清晰表达“有意跳过” - 不要写
if testing.Short() { t.Skip() }再加defer做清理——清理逻辑应放在t.Skip()之前,或用t.Cleanup()统一管理 - 切勿在 goroutine 中调用
t.Skip(),会 panic:testing: t.Skip now forbidden
哪些测试该加 testing.Short() 判断
不是所有耗时测试都适合用 testing.Short(),重点是那些「本地开发/CI 快速反馈阶段可安全省略,且不影响核心逻辑验证」的场景。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
典型包括:
- 真实 HTTP 请求(不用
httptest.Server替代的) - 数据库写入/查询(非内存 SQLite 或 mock)
- 大文件生成或读取(>1MB、耗时 >500ms)
- 调用外部 CLI 工具(如
git、curl) - 依赖环境变量但未设默认 fallback 的集成路径
反例:单元测试里一个 time.Sleep(10ms) 就加 testing.Short() —— 这属于测试设计问题,不该靠短模式掩盖。
和 build tag、-run/-skip 的配合关系
testing.Short() 是运行时动态控制,和编译期的 //go:build integration、命令行的 -run=TestFoo 完全正交。它们可以共存,但职责不同:
-
//go:build integration:文件级隔离,go test默认不编译该文件,彻底排除 -
-run/-skip(Go 1.22+):临时调试用,匹配测试名,不改代码 -
testing.Short()+t.Skip():逻辑级控制,同一份代码在不同模式下行为不同,适合 CI 分阶段执行
实际项目中常见组合:go test -tags=integration -short —— 表示“只跑 integration 标签的文件,且其中符合短模式的测试跳过”。这时候,testing.Short() 依然只在被选中的测试函数里起作用。
最容易被忽略的一点:短模式不是兜底方案。如果某个测试漏掉了 testing.Short() 判断,又恰好做了阻塞操作(比如没设超时的 http.Get),它就会拖慢整个 go test -short 流程,甚至触发 -timeout 被 kill —— 这种情况不会报错,只会显示 “killed by signal: interrupt”,排查起来非常隐蔽。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










