Golang 單元測試和基準測試實例詳解
前言
多人協作的項目裡,要保證代碼的質量,自然離不開單元測試。開發完一個功能後肯定要對所寫的代碼進行測試,測試沒有問題之後再合並到代碼庫供他人使用。如果強行合並到代碼庫可能會影響其他人開發,被上線的話肯定也會導致線上 Bug ,影響用戶使用。
所以,單元測試也是一個很重要的事情。單元測試是指在開發中,對一個函數或模塊的測試。其強調的是對單元進行測試。
Go 單元測試
Go 語言提供瞭單元測試的框架,隻要遵循其規則即可:
測試文件命名:
- 單元測試的代碼文件都必須以 _test.go 結尾,這樣才能被 Go 語言測試工具識別
- 單元測試的文件命名都與被測試函數所在的 go 文件的文件名一樣,然後再加 _test.go。比如 main.go 的測試文件 main_test.go
測試函數命名:
- 單元測試的函數名必須以 Test 開頭,再加上要測試函數名,且必須是公有的。比如main.go中有函數
func add(){}
, 其函數名應為TestAdd
- 測試函數的簽名必須接收一個指向 testing.T 類型的指針,並且不能返回任何值
# main.go func Add(){ // to do something } # main_test.go func TestAdd(t *testing.T) { result := Add() if result == 3 { println("success") } else { println("error") } }
根據以上規則,就可以進行對某測試文件執行命令,進行單元測試:
go test -v ./main_test.go
如果顯示的測試結果有 PASS 標記,說明單元測試通過。
單元測試覆蓋率
函數是否被全面測試,還需要覆蓋率進行檢測。單元測試命令增加 –coverprofile 標記,就可以得到一個單元測試覆蓋文件,且會在控制臺打印出代碼覆蓋率是多少。
go test -v --coverprofile=main.cover ./main_test.go
Go 框架還可以生成 html 文件的覆蓋率報告,這樣就可以對單元測試覆蓋率的結果更清晰,更明白。
go tool cover -html=main.cover -o=main.html
打開 html 文件就可以看到紅色標記是沒有被覆蓋到,綠色是被測試到的。
以上是簡單的功能的單元測試,驗證功能邏輯的正確。但有時候還有性能的要求,這時就可以使用基準測試來評估代碼的性能。
基準測試
基準測試是一項用於測試和評估軟件性能指標的方法,主要測試代碼的性能。基準測試的規則和單元測試的規則是不一樣的:
- 基準測試函數必須以 Benchmark 開頭,且必須是可導出的
- 函數的簽名必須接收一個指向 testing.B 類型的指針,並且不能返回任何值;
- 最後的 for 循環很重要,被測試的代碼要放到循環裡;
- b.N 是基準測試框架提供的,表示循環的次數,因為需要反復調用測試的代碼,才可以評估性能。
func BenchmarkAdd(b *testing.B) { for i := 0; i < b.N; i++ { Add() } }
寫完基準測試,就可以執行命令進行測試:
go test -bench=. ./
使用 go test 命令,再加上 -bench 這個 Flag,它接受一個表達式作為參數,以匹配基準測試的函數,"."表示運行所有基準測試。
BenchmarkAdd-10, 其中的 -10 是運行基準測試時對應的 GOMAXPROCS 的值。基準測試的時間默認是 1 秒,也就是 1 秒調用 1000000000 次、每次調用花費 311 納秒。如果想讓測試運行的時間更長,可以通過 -benchtime 指定,比如 3 秒。
go test -bench=. -benchtime=3s ./
- 重置計時方法
進行基準測試之前,需要進行一些數據準備,如構建測試數據,而這部分準備工作不屬於性能測試計算范圍內所以需要排除在外。通過使用充值計數器 ResetTimer重新計算。也支持使用 StartTimer 和 StopTimer 方法,控制何時開始計時何時結束。
- 內存統計
內存統計主要是統計每次操作分配內存的次數和分配的字節數。使用 ReportAllocs() 方法
func BenchmarkAdd(b *testing.B) { b.ResetTimer() // 重置計時時間 b.ReportAllocs() // 內存統計 for i := 0; i < b.N; i++ { Add() } }
對以上命令執行後可在控制臺上得到結果。多瞭兩個指標。
- 第一個表示:每次操作分配多少字節內存
- 第二個表示:每次操作分配內存的次數
兩個指標沒有統一標準區說明越小越好還是越大越好,主要還是需要根據業務場景來判斷的。
- 並發基準測試
在並發的情況下,Go 也支持基準測試。Go 語言通過 RunParallel 方法運行並發基準測試。創建多個 goroutine 然後將 b.N 分配給這些 goroutine 執行。
func BenchmarkAdd(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { Add() } }) }
單元測試可以保證代碼質量,但其也不是萬能的,還需要 code Review 和人工測試才能更好的保證代碼的質量。
參考資料:https://www.jb51.net/article/260482.htm
以上就是Golang 單元測試和基準測試實例詳解的詳細內容,更多關於Golang 單元測試基準測試的資料請關註WalkonNet其它相關文章!