Go1-17 新特性:testing 包的相關變化

大家好,我是 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 語言標準庫》等。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/j7KTvXwmqly1_dklMNf_qw