Go1.17 新特性:testing 包的相关变化
阅读本文大概需要 4 分钟。
大家好,我是 polarisxu。
今天介绍下 Go1.17 中的特性:testing 包的一些变化。先看 Release Notes 关于 testing 变化的描述:
Added a new testing flag -shuffle which controls the execution order of tests and benchmarks.
The new T.Setenv and B.Setenv methods support setting an environment variable for the duration of the test or benchmark.
关于 shuffle 这个 flag,1.17 还未发布时,我就写过文章介绍:Go1.17这个新特性竟然是6年前提出来的。关于它的作用,记住关键一点:我们写测试时,测试之间别相互依赖,应该是独立的。
本文着重介绍另外一个特性:T.Setenv 和 B.Setenv。
从名字可以看出,这是设置环境变量用的。T 是单元测试,而 B 是基准测试。
你可能会说,os 包不是有 Setenv 吗?
os.Setenv
会影响当前进程的环境变量,而 T.Setenv 和 B.Setenv 只会影响当前测试函数的环境变量,不会对其他测试函数造成影响。通过它们,可以做到每个测试有自己的独立的环境变量。
Go 源码中,有不少测试文件使用了这个新功能,比如:
func TestImportVendor(t *testing.T) {
testenv.MustHaveGoBuild(t) // really must just have source
t.Setenv("GO111MODULE", "off")
ctxt := Default
wd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
ctxt.GOPATH = filepath.Join(wd, "testing/demo")
p, err := ctxt.Import("c/d", filepath.Join(ctxt.GOPATH, "src/a/b"), 0)
if err != nil {
t.Fatalf("cannot find vendored c/d from testdata src/a/b directory: %v", err)
}
want := "a/vendor/c/d"
if p.ImportPath != want {
t.Fatalf("Import succeeded but found %q, want %q", p.ImportPath, want)
}
}
具体源码:https://github.com/golang/go/blob/891547e2d4bc2a23973e2c9f972ce69b2b48478e/src/go/build/build_test.go#L556。
如果你项目中的测试依赖环境变量,可以考虑使用这个新的函数。
注意:在 Parallel 测试中不能使用 Setenv。
我是 polarisxu,北大硕士毕业,曾在 360 等知名互联网公司工作,10多年技术研发与架构经验!2012 年接触 Go 语言并创建了 Go 语言中文网!著有《Go语言编程之旅》、开源图书《Go语言标准库》等。
坚持输出技术(包括 Go、Rust 等技术)、职场心得和创业感悟!欢迎关注「polarisxu」一起成长!也欢迎加我微信好友交流:gopherstudio