Go 語言推薦測試檔案和源代碼檔案放在同一目錄下,測試檔案以 _test.go calc.go calc.go Add Mul calc_test.go
結尾。比如,目前 package 有
一個檔案,我們想測試
中的
和
函數,那麼應該建立
作為測試檔案。
example/
|--calc.go
|--calc_test.go
假如
calc.go
的代碼如下:
1 package main
2
3 func Add(a int, b int) int {
4 return a + b
5 }
6
7 func Mul(a int, b int) int {
8 return a * b
9 }
那麼
calc_test.go
中的測試用例可以這麼寫:
1 package main
2
3 import "testing"
4
5 func TestAdd(t *testing.T) {
6 if ans := Add(1, 2); ans != 3 {
7 t.Errorf("1 + 2 expected be 3, but %d got", ans)
8 }
9
10 if ans := Add(-10, -20); ans != -30 {
11 t.Errorf("-10 + -20 expected be -30, but %d got", ans)
12 }
13 }
- 測試用例名稱一般命名為
加上待測試的方法名。Test
- 測試用的參數有且隻有一個,在這裡是
。t *testing.T
運作
go test
,該 package 下所有的測試用例都會被執行。
$ go test
ok example 0.009s
或
go test -v
,
-v
參數會顯示每個用例的測試結果
$ go test -v
=== RUN TestAdd
--- PASS: TestAdd (0.00s)
=== RUN TestMul
--- PASS: TestMul (0.00s)
PASS
ok example 0.007s
如果隻想運作其中的一個用例,例如
TestAdd
,可以用
-run
參數指定,該參數支援通配符
*
,和部分正規表達式,例如
^
、
$
1 $ go test -run TestAdd -v
2 === RUN TestAdd
3 --- PASS: TestAdd (0.00s)
4 PASS
5 ok example 0.007s
遇到如下報錯的解決方法
原因:
從提示:
build failed可以看出是
建構失敗,go test與其他的指定源碼檔案進行編譯或運作的指令程式一樣(參考:
go run
和
go build
),會為指定的源碼檔案生成一個虛拟代碼包——“command-line-arguments”,對于運作這次測試的指令程式來說,測試源碼檔案
getinfo_test.go
是屬于代碼包“command-line-arguments”的,可是它引用了其他包中的資料并不屬于代碼包“command-line-arguments”,編譯不通過,錯誤自然發生了。
解決方法:
知道了原因之後,解決的方法就出來了,執行指令時加入這個測試檔案需要引用的源碼檔案,在指令行後方的檔案都會被加載到
command-line-arguments
中進行編譯,示例如下:
單元測試覆寫率
- cover:檢視單元測試的覆寫率
- coverprofile:指定輸出檔案
示例:
生成html格式的覆寫率報告
指令:
go tool cover -html=cover.out -o coverage.html
HTML檔案内容:
go test指令的使用
go test做性能測試
除了可以做功能邏輯的測試(上面講的單元測試),go test還可以做性能測試
壓測檔案的規則:
- 檔案名規則和單元測試一樣
- 壓力測試函數必須遵循如下格式,其中XXX可以是任意字母數字的組合,但是首字母不能是小寫字母,注意琪參數是 testing.B,單元測試參數是 testing.T
func BenchmarkXXX(b *testing.B) { … }
- go test不會預設執行壓力測試的函數,如果要執行壓力測試需要帶上參數-bench,文法:-bench=檔案路徑名,例如go test -test.bench=.
表示測試目前目錄下全部的壓力測試函數
- 壓力測試函數在壓力測試用例中,有一個屬性 testing.B.N,它表示的是進行壓力測試的次數。可以通過 b.N = 1234 來設定壓力次數
如 webbench_test.go 壓力測試函數
1 package math
2
3 import (
4 "testing"
5 )
6
7 func Benchmark_Division(b *testing.B) {
8 for i := 0; i < b.N; i++ { //use b.N for looping
9 Division(4, 5)
10 }
11 }
12
13 func Benchmark_TimeConsumingFunction(b *testing.B) {
14 b.StopTimer() //調用該函數停止壓力測試的時間計數
15
16 //做一些初始化的工作,例如讀取檔案資料,資料庫連接配接之類的,
17 //這樣這些時間不影響我們測試函數本身的性能
18
19 b.StartTimer() //重新開始時間
20
21 b.N=1234 //自定義執行1234次
22
23 for i := 0; i < b.N; i++ {
24 Division(4, 5)
25 }
26 }
執行如下指令 go test -v ./webbench_test.go ./division.go -bench=".*" 隻顯示壓力測試,因為兩個檔案有依賴是以需要放到一起編譯執行
其中 -bench=".*" 表示 執行所有壓力測試函數
結果如下:
$ go test -v ./webbench_test.go ./division.go -bench=".*"
goos: linux
goarch: amd64
Benchmark_Division-8 2000000000 0.74 ns/op
Benchmark_TimeConsumingFunction-8 1234 0.96 ns/op
PASS
ok command-line-arguments 1.558s
上面資訊說明Benchmark_Division預設執行了2000000000次,
而Benchmark_TimeConsumingFunction通過設定 b.N=1234 執行不同次數;
每次的執行平均時間分别是0.74納秒和0.96納秒,總運作時間1.558秒