Golang Testing單元測試指南


基礎

可以通過 go test -h 查看幫助信息。

其基本形式是:

go test [build/test flags] [packages] [build/test flags & test binary flags] 

執行 go test 命令,它會在 *_test.go 中尋找 test 測試benchmark 基准 和 examples 示例 函數。測試函數必須以 TestXXX 的函數名出現(XXX 為以非小寫字母開頭),基准函數必須以 BenchmarkXXX 的函數名出現,示例函數必須以 ExampleXXX 的形式。三種函數類似下面的簽名形式:

// test 測試函數 func TestXXX(t *testing.T) { ... } // benchmark 基准函數 func BenchmarkXXX(b *testing.B) { ... } // examples 示例函數,其相關命名方式可以查看第一篇文章 func ExamplePrintln() { Println("The output of\nthis example.") // Output: The output of // this example. } 或 func ExamplePerm() { for _, value := range Perm(4) { fmt.Println(value) } // Unordered output: 4 // 2 // 1 // 3 // 0 } 

更多請查看 go help testfunc

go test 命令還會忽略 testdata 目錄,該目錄用來保存測試需要用到的輔助數據。

go test 有兩種運行模式:

1、本地目錄模式,在沒有包參數(例如 go test 或 go test -v)調用時發生。在此模式下,go test 編譯當前目錄中找到的包和測試,然后運行測試二進制文件。在這種模式下,caching 是禁用的。在包測試完成后,go test 打印一個概要行,顯示測試狀態、包名和運行時間。

2、包列表模式,在使用顯示包參數調用 go test 時發生(例如 go test mathgo test ./... 甚至是 go test .)。在此模式下,go 測試編譯並測試在命令上列出的每個包。如果一個包測試通過,go test 只打印最終的 ok 總結行。如果一個包測試失敗,go test 將輸出完整的測試輸出。如果使用 -bench 或 -v 標志,則 go test 會輸出完整的輸出,甚至是通過包測試,以顯示所請求的基准測試結果或詳細日志記錄。

下面詳細說明下 go test 的具體用法,flag 的作用及一些相關例子。需要說明的是:一些 flag 支持 go test 命令和編譯后的二進制測試文件。它們都能識別加 -test. 前綴的 flag,如 go test -test.v,但編譯后的二進制文件必須加前綴 ./sum.test -test.bench=.

有以下測試文件 sum.go:

package sum func Sum(a, b int) int { return a + b } 

sum_test.go 內容:

package sum import ( "flag" "fmt" "testing" "time" ) var print bool func init() { flag.BoolVar(&print, "p", false, "print test log") flag.Parse() } func TestSum(t *testing.T) { val := Sum(1, 2) if print { fmt.Println("sum=", val) } } // -bench 基准測試 func BenchmarkSum(b *testing.B) { for i := 0; i < b.N; i++ { Sum(i, i+1) } } // -timeout 測試 func TestSumLongTime(t *testing.T) { time.Sleep(time.Second * 2) Sum(1, 2) } // 子測試 func TestSumSubTest(t *testing.T) { t.Run("1+2", func(t *testing.T) { val := Sum(1, 2) t.Log("1+2=", val) }) t.Run("2+3", func(t *testing.T) { val := Sum(2, 3) t.Log("2+3=", val) }) } // 子測試,無具體子測試 func TestSumSubTest2(t *testing.T) { val := Sum(2, 3) t.Log("no subtest=", val) } // 並發測試 func TestSumParallel(t *testing.T) { t.Parallel() Sum(1, 2) } func TestSumParallel2(t *testing.T) { t.Parallel() Sum(1, 2) } 

test flag

以下 flag 可以跟被 go test 命令使用:

  • -args:傳遞命令行參數,該標志會將 -args 之后的參數作為命令行參數傳遞,最好作為最后一個標志。
  $ go test -args -p=true 
  • -c:編譯測試二進制文件為 [pkg].test,不運行測試。
  $ go test -c && ./sum.test -p=true 
  • -exec xprog:使用 xprog 運行測試,行為同 go run 一樣,查看 go help run
  • -i:安裝與測試相關的包,不運行測試。
  $ go test -i 
  • -o file:編譯測試二進制文件並指定文件,同時運行測試。
  go test -o filename 

test/binary flag

以下標志同時支持測試二進制文件和 go test 命令。

  • -bench regexp:通過正則表達式執行基准測試,默認不執行基准測試。可以使用 -bench .-bench=.執行所有基准測試。
  $ go test -bench=.
  $ go test -c
  $ ./sum.test -test.bench=.
  • -benchtime t:每個基准測試運行足夠迭代消耗的時間,time.Duration(如 -benchtime 1h30s),默認 1s。
  $ go test -bench=. -benchtime 0.1s $ ./sum.test -test.bench=. -test.benchtime=1s 
  • -count n:運行每個測試和基准測試的次數(默認 1),如果 -cpu 指定了,則每個 GOMAXPROCS 值執行 n 次,Examples 總是運行一次。
  $ go test -bench=. -count=2 $ ./sum.test -test.bench=. -test.count=2 
  • -cover:開啟覆蓋分析,開啟覆蓋分析可能會在編譯或測試失敗時,代碼行數不對。
  $ go test -bench=. -cover 
  • -covermode set,count,atomic:覆蓋分析的模式,默認是 set,如果設置 -race,將會變為 atomic。
    • set,bool,這個語句運行嗎?
    • count,int,該語句運行多少次?
    • atomic,int,數量,在多線程正確使用,但是耗資源的。
  • -coverpkg pkg1,pkg2,pkg3:指定分析哪個包,默認值只分析被測試的包,包為導入的路徑。
  # sum -> $GOPATH/src/test/sum $ go test -coverpkg test/sum 
  • -cpu 1,2,4:指定測試或基准測試的 GOMAXPROCS 值。默認為 GOMAXPROCS 的當前值。
  • -list regexp:列出與正則表達式匹配的測試、基准測試或 Examples。只列出頂級測試(不列出子測試),不運行測試。
  $ go test -list Sum 
  • -parallel n:允許並行執行通過調用 t.Parallel 的測試函數的最大次數。默認值為 GOMAXPROCS 的值。-parallel 僅適用於單個二進制測試文件,但go test命令可以通過指定 -p 並行測試不同的包。查看 go help build
  $ go test -run=TestSumParallel -parallel=2 
  • -run regexp:只運行與正則表達式匹配的測試和Examples。我們可以通過 / 來指定測試子函數。go test Foo/A=,會先去匹配並執行 Foo 函數,再查找子函數。
  $ go test -v -run TestSumSubTest/1+ 
  • -short:縮短長時間運行的測試的測試時間。默認關閉。
  $ go test -short 
  • -timeout d:如果二進制測試文件執行時間過長,panic。默認10分鍾(10m)。
  $ go test -run TestSumLongTime -timeout 1s 
  • -v:詳細輸出,運行期間所有測試的日志。
  $ go test -v 

analyze flag

以下測試適用於 go test 和測試二進制文件:

  • -benchmem:打印用於基准的內存分配統計數據。
  $ go test -bench=. -benchmem
  $ ./sum.test -test.bench -test.benchmem
  • -blockprofile block.out:當所有的測試都完成時,在指定的文件中寫入一個 goroutine 阻塞概要文件。指定 -c,將寫入測試二進制文件。
  $ go test -v -cpuprofile=prof.out $ go tool pprof prof.out 
  • -blockprofilerate n:goroutine 阻塞時候打點的納秒數。默認不設置就相當於 -test.blockprofilerate=1,每一納秒都打點記錄一下。
  • -coverprofile cover.out:在所有測試通過后,將覆蓋概要文件寫到文件中。設置過 -cover。
  • -cpuprofile cpu.out:在退出之前,將一個 CPU 概要文件寫入指定的文件。
  • -memprofile mem.out:在所有測試通過后,將內存概要文件寫到文件中。
  • -memprofilerate n:開啟更精確的內存配置。如果為 1,將會記錄所有內存分配到 profile。
  $ go test -memprofile mem.out -memprofilerate 1 $ go tool pprof mem.out 
  • -mutexprofile mutex.out:當所有的測試都完成時,在指定的文件中寫入一個互斥鎖爭用概要文件。指定 -c,將寫入測試二進制文件。
  • -mutexprofilefraction n:樣本 1 在 n 個堆棧中,goroutines 持有 a,爭用互斥鎖。
  • -outputdir directory:在指定的目錄中放置輸出文件,默認情況下,go test 正在運行的目錄。
  • -trace trace.out:在退出之前,將執行跟蹤寫入指定文件。


免責聲明!

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



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