Go 测试偶尔受执行顺序影响,可以开 shuffle3342Lv1楼主20 天前发布在 Dev#0golangtestingtooling66 次浏览5 条回复有些测试单独跑没事,整包运行却偶发失败,可能是测试之间共享了状态。可以先随机打乱执行顺序: go test -shuffle=on ./... 失败时输出里会带一个 seed,用它可以复现同一顺序: go test -shuffle=1700000000000000000 ./... 环境:Go 1.17+。它适合暴露全局变量、临时文件或环境变量没有清理的问题,但不能代替 -race;排查并发读写时还是要另外跑 go test -race ./...。
HHosuLv119 天前#1复现时最好把 seed、Go 版本和失败的包名一起记下来;测试集合变了以后,同一个 seed 不一定还是原来的排列。定位到共享状态后,可以优先用 t.Cleanup、t.Setenv 和 t.TempDir 收口清理,其中 t.Setenv 不能和并行测试一起用。
NNiroLv119 天前#2想在 CI 里提高撞到顺序问题的概率,可以用独立进程多跑几轮: for i in {1..20}; do go test -count=1 -shuffle=on ./... || break done 环境是 Bash 和 Go 1.17+。-count=1 可以避免测试缓存;保留失败那一轮的完整输出,后面再拿 seed 单独复现。
隔隔壁空白Lv119 天前#3还可以固定 seed 后把并行度降到 1 做个对照: go test -count=1 -shuffle=1700000000000000000 -parallel=1 ./... 环境:Go 1.17+。如果这样仍能复现,更像是串行测试间的状态泄漏;如果消失了,再重点检查调用 t.Parallel() 的测试。注意 -parallel 不限制不同包之间的并发,跨包资源冲突还要配合 go test -p=1 排查。
NNathan03Lv119 天前#4排查时也可以先把 ./... 缩到报错的具体包,不然包之间并发会把线索搅在一起: go test -count=1 -shuffle=1700000000000000000 ./internal/foo 环境:Go 1.17+。如果单包稳定、整仓才抖,再去看跨包共享的端口、临时目录、外部服务这类资源;需要对照时再加 -p=1 跑一轮。
UuitfLv119 天前#5如果怀疑是某个表格测试里的子用例被打乱触发,也可以配合 -run 缩小范围: go test -count=1 -shuffle=1700000000000000000 -run 'TestParser/case_name' ./internal/foo 环境:Go 1.17+。-run 的斜杠能匹配子测试路径,先锁到一小段再改清理逻辑会省点时间。要注意正则写太宽时还是会跑到别的同名子用例,必要时把父测试名也带上。