需显式调用 t.parallel() 启用并行,但必须避免共享状态、使用局部变量、线程安全资源、sync.waitgroup 同步 goroutine、-race 检测竞态、allocsperrun 分析内存分配。
如何用 testing.T.Parallel() 安全地并行运行测试
Go 的测试并行能力不是自动开启的,必须显式调用 t.Parallel() 才会参与并行调度。但直接加这行代码不等于安全——它只表示“允许与其他标记了 Parallel() 的测试并发执行”,不解决数据竞争或共享状态问题。
常见错误现象:fatal error: concurrent map writes 或测试偶尔失败、结果不一致,往往是因为多个并行测试共用了全局变量(如包级 map、sync.Pool 实例)或未隔离的临时文件路径。
- 每个并行测试函数内,应使用局部变量构造独立状态,避免读写包级可变变量
- 若必须复用资源(如数据库连接池),需用
sync.Once初始化,并确保该资源本身线程安全 - 不要在
TestMain中启动全局 goroutine 并假设它对所有并行测试可见——它们可能在任意时刻开始/结束 - 命令行运行时需加
-p参数控制并行数(如go test -p 4),否则默认只用 GOMAXPROCS 个逻辑处理器,未必体现真实并发压力
用 sync.WaitGroup 和 chan 控制测试内的 goroutine 生命周期
测试函数本身是主线程,但你常需要在测试中启动多个 goroutine 模拟并发行为(比如模拟 100 个客户端同时调用某个服务)。这时不能靠 time.Sleep 等待,必须显式同步。
错误做法:启动 goroutine 后直接返回,导致测试提前结束,goroutine 被强制终止;或用 runtime.Gosched() 试图“让出”,完全不可靠。