Go 語言單元測試
go 語言發展非常迅速,大家對go語言程式設計也比較熟悉了,但很多同學對於go語言的測試不太熟悉,最近準備三篇關於Go語言的測試文章來介紹Go語言的測試相關內容。
單元測試框架
go語言提供了編寫go語言的自動化測試框架testing.T,testing.B等,我們通過go test
命令就可以來啟動測試。我們編寫測試方法的格式如下:
func TestXxx(*testing.T)
注意這裡的方法名TestXxx
中第一個X是大寫,這是一種推薦的規範。測試方法名在實際方法名Xxx
前加Test
標明這是測試Xxx
的方法。
另外,我們推薦將測試檔案取名xxx_test.go
這樣的格式,其中xxx
go test
命令時將包含該檔案。
單元測試編寫規範
單元測試通常都是通過一組用例資料,作為方法的引數傳入,檢查輸出是否與預期的返回值相同。這種思路也適用於Go語言,只不過在實現形式上推薦採用更為優雅的方式。
假設我們有一個非常簡單的helper.go
, 實現兩個整數相加輸出結果的功能,實現程式碼如下:
package helper
func Add(a, b int) int {
return a + b
}
我們可以寫如下的測試程式碼:
package helper
import (
"testing"
)
func TestAdd(t *testing.T) {
var param1 = 1
var param2 = 1
var result = 2
r := Add(param1, param2)
if r != result {
if r != result {
t.Errorf("error: expecte %d, but got %d", result, r)
}
}
}
這個程式碼這樣寫並沒有什麼大的問題,如果考慮其擴充套件性,比如增加新的測試場景(程式碼在不斷迭代優化中),程式碼的可讀性就會變得越來越差,如何有效確保擴充套件性的前提下不降低可讀性呢?推薦如下方式:
package helper
import (
"testing"
)
func TestAdd(t *testing.T) {
tests := []struct {
param1 int
param2 int
result int
}{
{
param1: 1,
param2: 1,
result: 2,
},
}
for _, test := range tests {
r := Add(test.param1, test.param2)
if r != test.result {
t.Errorf("error: expecte %d, but got %d", test.result, r)
}
}
}
這種方式下,測試程式碼更加簡潔,在增加新的測試場景的情況下,也不會降低可讀性,這種設計在Kubernetes及阿里Pouch等開源專案中都有此類實踐,大家可以關注。
特殊功能開關
指定執行的方式
可以通過go test -run xxx
的形式來指定執行的方法,注意這裡的run
引數是正則匹配的,如下所示:
bogon:helper $ go test -v
=== RUN TestAdd
--- PASS: TestAdd (0.00s)
=== RUN TestExp
--- PASS: TestExp (0.00s)
PASS
ok demo/helper 0.005s
bogon:helper $ go test -run TestAdd -v
=== RUN TestAdd
--- PASS: TestAdd (0.00s)
PASS
ok demo/helper 0.005s
bogon:helper $ go test -run TestExp -v
=== RUN TestExp
--- PASS: TestExp (0.00s)
PASS
ok demo/helper 0.005s
獲取測試覆蓋率
go 提供了獲取單元測試覆蓋率引數,執行如下命令:
go test -v -coverprofile cover.out
go tool cover -html=cover.out -o cover.html
我們開啟cover.html就可以獲得單元測試覆蓋率資訊,如下所示:
限制同時執行的執行緒數
go語言有一個GOMAXPROCS變數,可以指定執行Go程式碼的作業系統執行緒數。如果執行時不加該引數,則就是當前所設定的GOMAXPROCS值。
bogon:helper $ go test -cpu 1
PASS
ok demo/helper 0.005s
總結
Go語言是一個嚴禁且高效的開發語言,在單元測試方面,提供了很多好的工程實踐,這些思想可以在其他語言中採用,這一篇是一個開始,後續會介紹Go語言測試的Benchmark部分,主要是針對性能相關部分的內容。