其實以前對於測試本身一直比較弱,不論是python的仍是go的,關於測試這塊並無很是注重,此次就好好整理一下關於go的測試python
Go程序主要包含三類測試: 功能測試(test)、基準測試(benchmark,也稱性能測試)以及示例測試併發
這裏提一下,示例測試其實也是一種功能測試,只不過它更關注程序打印出來的內容app
通常狀況下:一個測試賽源碼文件只會針對某個命令源碼文件, 或庫源碼文件作測試,因此咱們應該把它們放在同一個代碼包內函數
測試源碼文件的主名稱應該以被測試源碼文件的主名稱爲前導, 而且必須以「_test」爲後綴,如被測試的源碼文件名是demo.go 那麼測試源碼文件名是demo_test.go性能
Go 語言對測試函數的名稱和簽名都有哪些規定?單元測試
關於go test 命令的主要流程是:測試
go test 命令在開始運行時會先作一些準備工做,好比,肯定內部須要用到的命令,檢查咱們指定的代碼包或源碼文件的有效性,以及判斷咱們基於的標記是否合法等等spa
在準備工做完成後,go test 命令會針對每一個測試代碼包依次進行構建,執行包中符合要求的測試函數,清理臨時文件,打印測試結果。日誌
這裏的依次:表示對每一個測試代碼包,go test 命令會串行的執行測試流程中的每一個步驟。可是爲了加快測試速度,它一般會併發地對多個被測試代碼包進行功能測試。只不過最後打印測試結果的時候code
會按照咱們給定的順序逐個進行,讓咱們感受是在串行的執行測試
因爲併發測試會讓性能測試的結果存在誤差,因此性能測試通常都是串行進行的
go test -v 能夠看到測試中更詳細的日誌信息
若是想要某個測試在執行的過程當中當即失敗,能夠在該函數中調用:t.FailNow方法
怎麼解釋性能測試的測試結果?
這個仍是很是重要的,以前並無去細緻的瞭解
這裏有一段代碼,併爲之寫了一個性能測試代碼內容以下:
package demo54 import "math" func GetPrimes(max int) []int { if max <= 1 { return []int{} } marks := make([]bool, max) var count int squareRoot := int(math.Sqrt(float64(max))) for i := 2; i <= squareRoot; i++ { if marks[i] == false { for j := i * i; j < max; j += i { if marks[j] == false { marks[j] = true count++ } } } } primes := make([]int, 0, max-count) for i := 2; i < max; i++ { if marks[i] == false { primes = append(primes, i) } } return primes }
性能測試的代碼爲:
package demo54 import "testing" func BenchmarkGetPrimes(b *testing.B) { for i:=0;i<b.N;i ++ { GetPrimes(1000) } }
下面是測試命令和結果
zhaofan@zhaofandeMacBook-Pro ~/go_project go test -bench=. -run=^$ 36/demo54 goos: darwin goarch: amd64 pkg: 36/demo54 BenchmarkGetPrimes-4 500000 2728 ns/op PASS ok 36/demo54 1.407s
這裏對這個命令進行解釋:
第一個標記-bench=. 只有有了這個標記命令纔會進行性能測試,該標記. 代表須要執行任意名稱的性能測試函數,固然這裏仍是要符合Go程序測試的基本規則的
第二個標記及值是-run=^$ 這個標記用於代表須要執行哪些功能測試函數,這一樣是以函數名稱爲依據的 該標記的值^$ 意味着只執行名稱爲空的功能測試函數,其實就是不執行任何功能測試函數
結果中:BenchmarkGetPrimes-4 被稱爲單個性能測試的名稱,表示命令執行了性能測試函數BenchmarkGetPrimes 而且當時全部最大的P 數量爲4 最大P 數量至關於能夠同時運行goroutine的邏輯CPU的最大個數。這裏的CPU能夠被稱爲CPU核心,但他並等同於計算機中真正的CPU核心
go test -cpu 能夠設置最大P數量的列表
關於測試代碼的解釋:
func BenchmarkGetPrimes(b *testing.B) { for i:=0;i<b.N;i ++ { GetPrimes(1000) } }
這裏在一個會循環迭代b.N次方的循環中調用了GetPrimes函數,並傳遞的參數爲1000, go test 命令會先嚐試把b.N 設置爲1,
而後執行測試函數
若是測試的函數執行時間沒有超過上限, 此傷心啊默認爲1秒,那麼命令就會改大b.N的值,而後再次執行測試函數,如此往復,知道這個時間大於或等於上限爲止。
當某次執行的時間大於或等於上限時, 咱們就說這事命令這次對該測試函數的最後一次執行,這時b.N的值就會包含在測試結果中,也就是上述測試結果中的500000
結果中:2728 ns/op 代表單次執行GetPrimes函數的平均耗時爲2728納秒。 這其實就是最後一次執行測試函數的時間,除以被測函數的執行測試得出的結果