13.7 Go 中的單元測試和基準測試

首先所有的包都應該有一定的必要文檔,然後同樣重要的是對包的測試。

在第 3 章中提到了 Go 的測試工具 gotest, 我們已經在 9.8 節中使用過了。這裏我們會用更多的例子進行詳細說明。

名爲 testing 的包被專門用來進行自動化測試,日誌和錯誤報告。並且還包含一些基準測試函數的功能。

備註:gotest 是 Unix bash 腳本,所以在 Windows 下你需要配置 MINGW 環境(參見 2.5 節);在 Windows 環境下把所有的 pkg/linux_amd64 替換成 pkg/windows。

對一個包做(單元)測試,需要寫一些可以頻繁(每次更新後)執行的小塊測試單元來檢查代碼的正確性。於是我們必須寫一些 Go 源文件來測試代碼。測試程序必須屬於被測試的包,並且文件名滿足這種形式 *_test.go,所以測試代碼和包中的業務代碼是分開的。

_test 程序不會被普通的 Go 編譯器編譯,所以當放應用部署到生產環境時它們不會被部署;只有 gotest 會編譯所有的程序:普通程序和測試程序。

測試文件中必須導入 "testing" 包,並寫一些名字以 TestZzz 打頭的全局函數,這裏的 Zzz 是被測試函數的字母描述,如 TestFmtInterface,TestPayEmployees 等。

測試函數必須有這種形式的頭部:

func TestAbcde(t *testing.T)

T 是傳給測試函數的結構類型,用來管理測試狀態,支持格式化測試日誌,如 t.Log,t.Error,t.ErrorF 等。在函數的結尾把輸出跟想要的結果對比,如果不等就打印一個錯誤。成功的測試則直接返回。

用下面這些函數來通知測試失敗:

1)func (t *T) Fail()

    標記測試函數爲失敗,然後繼續執行(剩下的測試)。

2)func (t *T) FailNow()

    標記測試函數爲失敗並中止執行;文件中別的測試也被略過,繼續執行下一個文件。

3)func (t *T) Log(args ...interface{})

    args 被用默認的格式格式化並打印到錯誤日誌中。

4)func (t *T) Fatal(args ...interface{})

    結合 先執行 3),然後執行 2)的效果。

運行 go test 來編譯測試程序,並執行程序中所有的 TestZZZ 函數。如果所有的測試都通過會打印出 PASS。

gotest 可以接收一個或多個函數程序作爲參數,並指定一些選項。

結合 --chatty 或 -v 選項,每個執行的測試函數以及測試狀態會被打印。

例如:

go test fmt_test.go --chatty
=== RUN fmt.TestFlagParser
--- PASS: fmt.TestFlagParser
=== RUN fmt.TestArrayPrinter
--- PASS: fmt.TestArrayPrinter
...

testing 包中有一些類型和函數可以用來做簡單的基準測試;測試代碼中必須包含以 BenchmarkZzz 打頭的函數並接收一個 *testing.B 類型的參數,比如:

func BenchmarkReverse(b *testing.B) {
    ...
}

命令 go test –test.bench=.* 會運行所有的基準測試函數;代碼中的函數會被調用 N 次(N是非常大的數,如 N = 1000000),並展示 N 的值和函數執行的平均時間,單位爲 ns(納秒,ns/op)。如果是用 testing.Benchmark 調用這些函數,直接運行程序即可。

具體可以參見 14.16 節中用 goroutines 運行基準測試的例子以及練習 13.4:string_reverse_test.go

鏈接

results matching ""

    No results matching ""