單元測試函數類型
Test(功能測試)
函數規則:
- 函數名: TestXxxx , 以Test為前綴。Xxxx以大寫字母開頭
- 參數類型: *testing.T
func TestXxxx(t *testing.T){...}
編寫一個簡單的例子,假設有下面一個待測函數:
func add(a, b int) int {
return a + b
}
測試代碼如下:
import "testing"
func TestAdd(t *testing.T) {
cases := []struct {
first int
second int
excepted int
}{
{1, 2, 3},
{1, 2, 4},
}
for _, c := range cases {
result := add(c.first, c.second)
if result != c.excepted {
t.Fatalf("add function failed, first: %d, second:%d, execpted:%d, result:%d", c.first, c.second, c.excepted, result)
}
}
}
執行 go go test -v
結果如下:
=== RUN TestAdd
--- FAIL: TestAdd (0.00s)
example_test.go:30: add function failed, first: 1, second:2, execpted:4, result:3
FAIL
exit status 1
FAIL gotest/gotest 0.006s
第二個測試用例出錯,未能通過單元測試,需要檢查測試數據或者被測試函數是否符合我們的預期。
從上述過程可以看出, TestXxxx 可以理解為功能性測試,其目的在於測試函數的功能性是否正確, 應當編寫盡可能多的測試用例來驗證被測函數的正確性。
Benchmark(基准測試)
函數規則:
- 函數名: BenchmarkXxxx, 以Benchmark為前綴。Xxxx以大寫字母開頭
- 參數類型: *testing.B
func BenchmarkXxx(b *testing.B){...}
性能測試函數如下:
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
add(1, 2)
}
}
執行 go test -bench=. -run=^$
,結果如下:
goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8 2000000000 0.32 ns/op
PASS
ok gotest/gotest 0.667s
測試結果說明:
- -8 表示 8個邏輯cpu個數(下文會解釋)
- 2000000000 表示執行了 2000000000 次
- 0.32 ns/op 每次操作耗時
- 0.667s 是總時長
性能測試函數計時器:
當性能測試函數中有一些額外的初始化操作時,可以通過啟停計時器來屏蔽這些操作對最終性能測試的影響。簡單例子如下:
func BenchmarkAdd(b *testing.B) {
time.Sleep(10 * time.Second)
for i := 0; i < b.N; i++ {
add(1, 2)
}
}
執行命令go test -bench=.
,結果如下:
goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8 1 10004479538 ns/op
PASS
ok gotest/gotest 10.011s
單個測試函數耗時為 10004479538 ns,同時我們也可以看到,這個函數執行一次就已經達到了最大上限時間。
加上時間計數器:
func BenchmarkAdd(b *testing.B) {
b.StopTimer()
time.Sleep(10 * time.Second)
b.StartTimer()
for i := 0; i < b.N; i++ {
add(1, 2)
}
}
測試結果如下:
goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8 2000000000 0.34 ns/op
PASS
ok gotest/gotest 60.751s
單次執行耗時為: 0.34 ns 了。
Tips:
對於 b.N 參數而言, test 命令先會嘗試設置為1,之后執行函數。如果測試函數沒有達到執行上限的話, test 函數會增大,之后再次執行測試函數,如此往復,直到執行時間大於或者等於上限時間為止。 上限時間可以使用 -benchtime
設定
Example(示例測試)
函數規則:
- 函數名: ExampleXxx
- 輸出內容至標准輸出,參數列表沒有限制
示例測試函數如下:
func Println(content string) {
fmt.Println("The output of\nthis example.")
}
func ExamplePrintln() {
Println("The output of\nthis example.")
// Output: The output of
// this example.
}
go test 命令會檢測實際輸出與注釋中的期望輸出是否一致, 一致則測試通過,不一致則測試失敗。
go test 常用參數
- -cpu: 設置測試最大 cpu 邏輯數(也就是 GPM 中 P, 最大並行執行的 gorouting 數量, 默認等於 cpu 核數)
- -count: 設置執行測試函數的次數, 默認為 1
- -run: 執行功能測試函數, 支持正則匹配, 可以選擇測試函數或者測試文件來僅測試單個函數或者單個文件
- -bench: 執行基准測試函數, 支持正在匹配
- -benchtime: 基准測試最大探索時間上限
- -parallel: 設置同一個被測試代碼包中的功能測試函數的最大並發執行數
- -v: 是展示測試過程信息
更多的參數可以參考下文的官方文檔