go語言單元測試和基准測試


Go test工具

Go語言中測試依賴go test命令。
go test命令是一個按照一定約定和組織的測試代碼的驅動程序。在包目錄內,所有以_test.go為后綴名的源代碼文件都是go test 測試的一部分,不會被go build編譯到最終的可執行文件中。

 測試函數類型
在*_test.go文件中有三種類型的函數:單元測試函數基准測試函數示例函數

類型  格式     作用
測試函數 函數名綴為Test 測試程序的一些邏輯行為是否正確
基准函數 函數名前綴為Benchmark 測試函數的內存占用和運行效率的性能數據
示例函數 函數名前綴為Example

為文檔提高示例文檔


測試規則
測試規則主要為文件命名放置規則:

  • 測試源文件名應是_test結尾的go文件,例如:add_test.go;
  • 測試代碼和業務代碼是分開的,但兩者應該位於同一包下;
  • 測試源文件所在的包應該位於$GOPATH/src目錄下;
  • 測試文件必須導入"testing"包;

 

測試函數

每個測試函數必須導入testing包,測試函數的基本格式如下:

func TestName(t *testing.T){
	//...
}

測試函數的名字必須以Test開頭,可選的后綴名必須以大寫字母開頭,舉幾個例子:

func TestAdd(t *testing.T){...}
func TestSum(t *testing.T){...}
func TestLog(t *testing.T){...}

其中參數t用於報告測試失敗和附加的日志信息。testing.T擁有的方法如下:

func (c *T)Error(args ...interface{})
func (c *T)Errorf(format string,args ...interface{})
func (c *T)Fail()
func (c *T)Failnow()
func (c *T)Failed()bool
func (c *T)Fatal(args ...interface{})
func (c *T)Fatal(format string ,args ...interface{})
func (c *T)Log()(args ...interface{})
func (c *T)Logf(format string ,args ...interface{})
func (c *T)Name() string
func (c *T)Paralled()
func (c *T)Run(name string,f func(t *T)) bool
func (c *T)Skip(args ...interface{})
func (c *T)SkipNow()
func (c *T)Skipf(format string ,args ...interface{})
func (c *T)Skipped() bool

go test參數

-bench [正則表達式]:僅運行與正則表達式匹配的基准,默認情況下,不運行基准測試。如果要運行所有的基准測試函數,使用-bench .或者-bench=.。
-benchtime [時間]:表示運行多長時間的基准測試,默認值為1秒。例如:-benchtime 1h30s。
-count n:運行每個測試和基准多少次,默認為1,如果設置了-cpu,則為每個GOMAXPROCS運行n次,例子函數總是運行一次。
-cover:啟用覆蓋率分析,由於覆蓋率通過在編譯之前注釋源代碼來工作,因此啟用覆蓋率的編譯和測試失敗,可能會出現報告與原始文件行號不對應的情況。
-covermode set,count,atomic:為正在測試的包設置覆蓋率分析模式,除非啟用-race,否則默認為set,在這種情況下它是原子的。
set,布爾值,表示這句聲明是否有效
count,int類型,這句聲明運行多少次
atomic,int類型,在多線程測試中使用,原子操作。
-coverpkg pattern1,pattern2,pattern3:將每個測試中的覆蓋率分析應用於模式匹配的包,默認情況下,每個測試僅分析正在測試的包。
-cpu 1,2,4:指定應為其執行測試或基准測試的GOMAXPROCS的值的列表,默認值是GOMAXPROCS的當前值。
-failfast:表示在第一次測試失敗后不要開始新的測試。
-list [正則表達式]:只是列出與正則表達式匹配的測試、基准測試或例子,不會運行任何測試。
-parallel n:表示運行的最大測試數,默認情況下,它設置為GOMAXPROCS的值。
-run [正則表達式]:僅僅運行與正則表達式匹配的那些測試和例子,匹配時可能父項也會運行,例如:-run = X/Y,匹配運行所有與X匹配的測試的結果,即使沒有匹配到子測試。
-timeout [時間]:如果測試文件運行的時間超過設置的時間,就會出現panic。如果設置的時間為0,則表示timeout不可用。默認是10分鍾。
-v:會打印詳細的測試結果,即使是在測試成功的情況。

單元測試

1.在src目錄下創建mytest目錄,創建兩個文件Add.go和Add_test.go文件;
Add.go:

package main


func addNum(n int) (result int) {
	for i := 0; i <= n; i++ {
		result = result + i
	}
	return
}

Add_test.go:

package main

import (
	"testing"
)

//單元測試函數
func TestAddNum(t *testing.T) {
	if addNum(100) != 5050 {
		t.Fatal("addNum error!")
	}
}

2.進入src目錄下的mytest目錄下,執行go test命令
3.返回結果

PASS
ok mytest 0.056s

加入基准測試

1.修改Add_test.go:

package main

import (
	"testing"
)

//單元測試函數
func TestAddNum(t *testing.T) {
	if addNum(100) != 5050 {
		t.Fatal("addNum error!")
	}
}
//基准測試函數
func BenchmarkAddNum(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if addNum(100) != 5050 {
			b.Fatal("addNum")
		}
	}
} 

2.執行go test -bench=.
3.返回結果

goos: windows
goarch: amd64
pkg: MyDemo/mytest
BenchmarkAddNum-4 20000000 74.3 ns/op
PASS
ok mytest 1.615s

顯示執行addNum函數花費的平均時間是1.615s,執行了20000000次,每74.3ns的速度運行一次循環。

特殊功能

指定基准測試函數:通過-bench可以指定只測試哪個基准函數,如果沒有指定,則測試所有基准函數。

go test  -bench=.    測試所有基准函數
go test  -bench=Alloc  指定只測試Benchmark_Alloc() 基准函數

自定義測試時間:通過-benchtime參數可以自定義測試時間。(基准測試原理:基准測試框架對一個測試用例的默認測試時間是 1 秒。開始測試時,當以 Benchmark 開頭的基准測試用例函數返回時還不到 1 秒,那么 testing.B 中的 N 值將按 1、2、5、10、20、50……遞增,同時以遞增后的值重新調用基准測試用例函數。)

go test -v -bench=. -benchtime=5s

測試內存:基准測試可以對一段代碼可能存在的內存分配進行統計:通過-benchmem參數以顯示內存分配情況。

go test  -bench=.  -benchmem
返回信息字段:
Benchmarkxxx-4 格式為基准測試函數名-GOMAXPROCS,后面的-4代表測試函數運行時對應的CPU核數 1 表示執行的次數 xx ns/op 表示每次的執行時間 xx B/op 表示每次執行分配的總字節數(內存消耗) xx allocs/op 表示每次執行發生了多少次內存分配

 


免責聲明!

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



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