特征
Golang 單元測試對文件名和方法名,參數都有很嚴格的要求。例如:
1、文件名必須以 _test.go 結尾
2、方法名必須是 Test 開頭
3、方法參數必須是 t *testing.T 或 b *testing.B
命令詳解
go test 是 go 語言自帶的測試工具,其中包含的是兩類,單元測試(即 功能測試) 和 性能測試
通過 go help test
可以看到 go test 的使用說明:
格式:
go test [-c] [-i] [build flags] [packages] [flags for test binary]
參數:
-c : 編譯 go test 成為可執行的二進制文件,但是不運行測試。
-i : 安裝測試包依賴的 package,但是不運行測試。
關於 build flags,調用 go help build
,這些是編譯運行過程中需要使用到的參數,一般設置為空
關於 packages,調用 go help packages
,這些是關於包的管理,一般設置為空
關於 flags for test binary,調用 go help testflag
,這些是 go test 過程中經常使用到的參數:
-test.v : 是否輸出全部的單元測試用例(不管成功或者失敗),默認沒有加上,所以只輸出失敗的單元測試用例
-test.run pattern : 只跑哪些單元測試用例
-test.bench patten : 只跑那些性能測試用例
-test.benchmem : 是否在性能測試的時候輸出內存情況
-test.benchtime t : 性能測試運行的時間,默認是1s
-test.cpuprofile cpu.out : 是否輸出cpu性能分析文件
-test.memprofile mem.out : 是否輸出內存性能分析文件
-test.blockprofile block.out : 是否輸出內部goroutine阻塞的性能分析文件
-test.memprofilerate n : 內存性能分析的時候有一個分配了多少的時候才打點記錄的問題。這個參數就是設置打點的內存分配間隔,也就是 profile 中一個 sample 代表的內存大小。默認是設置為 512 * 1024 的。如果你將它設置為 1,則每分配一個內存塊就會在 profile 中有個打點,那么生成的 profile 的 sample 就會非常多。如果你設置為 0,那就是不做打點了
你可以通過設置 memprofilerate=1 和 GOGC=off 來關閉內存回收,並且對每個內存塊的分配進行觀察
-test.blockprofilerate n : 基本同上,控制的是 goroutine 阻塞時候打點的納秒數。默認不設置就相當於 -test.blockprofilerate=1,每一納秒都打點記錄一下
-test.parallel n : 性能測試的程序並行 cpu 數,默認等於 GOMAXPROCS
-test.timeout t : 如果測試用例運行時間超過 t,則拋出 panic
-test.cpu 1,2,4 : 程序運行在哪些 CPU 上面,使用二進制的 1 所在位代表,和 nginx 的 nginx_worker_cpu_affinity 是一個道理
-test.short : 將那些運行時間較長的測試用例運行時間縮短
示例
單元測試(測試 某個包)
在 golang 的 src 目錄下新建目錄 math,測試目錄結構如下:
ibonacci.go 代碼如下,主要有一個 Fibonacci 函數
package lib // 斐波那契數列 // 求出第n個數的值 func Fibonacci(n int64) int64 { if n < 2 { return n } return Fibonacci(n-1) + Fibonacci(n-2) }
fibonacci_test.go 就是測試的文件了,golang 需要測試文件一律用 “_test” 結尾,測試的函數都用 Test 開頭,代碼如下:
package lib import ( "testing" ) func TestFibonacci(t *testing.T) { r := Fibonacci(10) if r != 55 { t.Errorf("Fibonacci(10) failed. Got %d, expected 55.", r) } }
使用 go test 測試這個程序
$ go test lib ok lib 0.008s
性能測試
結合上面的方法,這里測試一下函數的性能,如果需要進行性能測試,則函數開頭使用 Benchmark 就可以了。
// 性能測試 func BenchmarkFibonacci(b *testing.B) { for i := 0; i < b.N; i++ { Fibonacci(10) } }
接下來執行這個性能測試:
$ go test -bench=. lib PASS BenchmarkFibonacci 5000000 436 ns/op ok lib 2.608s
其中第二行輸出表示這個函數運行了 5000000 次,平均運行一次的時間是 436ns。
這個性能測試只測試參數為 10 的情況。如果有需要可以測試多個參數:
// 測試參數為5的性能 func BenchmarkFibonacci5(b *testing.B) { for i := 0; i < b.N; i++ { Fibonacci(5) } } // 測試參數為20的性能 func BenchmarkFibonacci20(b *testing.B) { for i := 0; i < b.N; i++ { Fibonacci(20) } }
運行一下:
$ go test -bench=. lib PASS BenchmarkFibonacci 5000000 357 ns/op BenchmarkFibonacci5 100000000 29.5 ns/op BenchmarkFibonacci20 50000 44688 ns/op ok lib 7.824s
如果性能測試的方法非常多,那需要的時間就會比較久。可以通過 -bench=參數
設置需要運行的性能測試方法:
$ go test -bench=Fibonacci20 lib PASS BenchmarkFibonacci20 50000 44367 ns/op ok lib 2.677s
測試 某個文件
一定要帶上被測試的原文件,否則會提示找不到包
go test -v wechat_test.go wechat.go
測試 某個方法
go test -v -test.run TestRefreshAccessToken
延伸閱讀: