golang 單元測試框架實踐


一、簡介

日常開發中, 測試是不能缺少的,每次手動測試非常費時費力,通過單元測試可以達到一次實現多次利用;

單元測試主要是通過模擬業務中的參數,調用我們的函數,然后獲取執行結果,再判斷結果是否符合規則;同時還可以對某一個方法進行性能分析

在Go 標准庫中有一個叫做 testing 的測試框架, 可以用於單元測試和性能測試. 它是和命令 go test 集成使用的,測試文件是以后綴 _test.go 命名的, 通常和被測試的文件放在同一個包中.

規則:

  • 單元測試代碼的go文件必須以_test.go結尾,Go語言測試工具只認符合這個規則的文件
  • 單元測試的函數名必須以Test開頭,是可導出公開的函數。備注:函數名最好是Test+要測試的方法函數名
  • 測試函數的簽名必須接收一個指向testing.T類型的指針作為參數,並且該測試函數不能返回任何值

二、實驗環境

單元測試我們大部分情況下無需增加或修改業務代碼,只需增加單元測試代碼即可,在這個實驗過程中,我們簡單編寫一個簡單的業務代碼,用來模擬項目中的業務代碼;然后再添加單元測試代碼進行測試。

2.1 編寫被測試的代碼

我們找一個空文件夾,新建一個main.go文件,在文件中將一下代碼復制進去並保存

package main

func Sum(count int) int {
	count--
	return count
}

2.2 編寫單元測試代碼

接着我們繼續在當前文件夾下新建單元測試代碼,按照簡介中的規則,我們需要新建一個名為main_test.go的文件,然后在文件中編寫測試代碼,示例代碼如下

package main

import (
	"testing"
)

//單元測試
func TestSum(t *testing.T) {
	//准備參數
	param := 10
	//執行函數
	ret := Sum(param)
	//判斷結果是否符合預期
	if ret != 9 {
		t.Error("Sum result failed")
	}
}

//性能測試
func BenchmarkSum(b *testing.B) {
	//准備參數
	param := 10
	//執行函數
	for i := 0; i < b.N; i++ {
		Sum(param)
	}
}

三、單元測試使用

3.1 普通測試

普通測試主要是驗證返回的結果是否符合預期,執行的命令如下所示

go test -v  main_test.go  main.go

命令執行后,返回的結果如下所示
image

從上圖中可以看到,單元測試提示測試通過,說明我們程序符合預期

3.2 性能測試

性能測試主要是通過多次調用程序,總耗時來分析程序的性能,類似於AB壓力測試,執行命令如下所示

go test -v -bench="BenchmarkSum$"  --run=none main_test.go  main.go

命令中的-bench="BenchmarkSum$"參數代表要窒息哪一個方法,執行結果如下所示
image

在上圖中可以看到程序被調用了1000000000次,平均耗時0.254ns

3.3 性能分析

性能分析主要是查看方法中具體的瓶頸,比如A方法調用了C、B、D多個方法,具體耗時在什么位置,我們可以在上一條性能測試的命令中加入-cpuprofile cpu.out參數(文章附錄有多種分析指標類型)加入到性能測試中的具體信息保存

go test -v -bench="BenchmarkSum$"  --run=none  -cpuprofile cpu.out  main_test.go  main.go

image
通過go 自帶工具分析保存的文件

go tool pprof cpu.out

命令執行之后返回信息如下圖所示
image

通過第三方工具視圖分析

apt install graphviz  && go tool pprof -http=":" cpu.out

命令執行之后,會返回一個localhost域名加隨機端口的網址,打開網址之后,能看到如下信息,因為我測試的方法比較簡單

image

四、附錄

各參數含義翻譯

-blockprofile block.out

將goroutine阻塞配置文件寫入指定文件
當所有測試完成時。
按照-c的方式編寫測試二進制文件。

-blockprofilerate n

控制細節提供的goroutine阻塞配置文件
調用運行時。SetBlockProfileRate與n。
參見" go doc run . setblockprofilerate "
剖析器的目標是平均每個阻塞事件采樣一次
n納秒的程序花費被阻塞。默認情況下,
如果以及。塊配置文件沒有設置這個標志,所有的阻塞事件
,相當於-test.blockprofilerate=1。

-coverprofile cover.out

在所有測試通過后,向文件寫入覆蓋率配置文件。
設置覆蓋。

-cpuprofile cpu.out

退出前將CPU配置文件寫入指定文件。
按照-c的方式編寫測試二進制文件。

-memprofile mem.out

通過所有測試后,將分配配置文件寫入該文件。
按照-c的方式編寫測試二進制文件。

-memprofilerate n

啟用更精確(和昂貴)的內存分配配置文件
設置runtime.MemProfileRate。參見" go doc run . memprofilerate "。
要配置所有內存分配,使用-test.memprofilerate=1。

-mutexprofile mutex.out

將互斥鎖爭用配置文件寫入指定文件
當所有測試完成時。
按照-c的方式編寫測試二進制文件。

-mutexprofilefraction n

樣本1在n堆棧的蹤跡goroutines持有a
爭用互斥鎖。

作者:湯青松

日期:2020-08-11


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM