[Go] 單元測試/性能測試 (go test)


特征

Golang 單元測試對文件名和方法名,參數都有很嚴格的要求。例如:

1、文件名必須以 _test.go 結尾

2、方法名必須是 Test 開頭

3、方法參數必須是 t *testing.Tb *testing.B

命令詳解

go test 是 go 語言自帶的測試工具,其中包含的是兩類,單元測試(即 功能測試) 和 性能測試

通過 go help test 可以看到 go test 的使用說明:

格式:

go test [-c] [-i] [build flags] [packages] [flags for test binary]

參數:

-c : 編譯 go test 成為可執行的二進制文件,但是不運行測試。

-i : 安裝測試包依賴的 package,但是不運行測試。

關於 build flags,調用 go help build,這些是編譯運行過程中需要使用到的參數,一般設置為空

關於 packages,調用 go help packages,這些是關於包的管理,一般設置為空

關於 flags for test binary,調用 go help testflag,這些是 go test 過程中經常使用到的參數:

-test.v : 是否輸出全部的單元測試用例(不管成功或者失敗),默認沒有加上,所以只輸出失敗的單元測試用例

-test.run pattern : 只跑哪些單元測試用例

-test.bench patten : 只跑那些性能測試用例

-test.benchmem : 是否在性能測試的時候輸出內存情況

-test.benchtime t : 性能測試運行的時間,默認是1s

-test.cpuprofile cpu.out : 是否輸出cpu性能分析文件

-test.memprofile mem.out : 是否輸出內存性能分析文件

-test.blockprofile block.out : 是否輸出內部goroutine阻塞的性能分析文件

-test.memprofilerate n : 內存性能分析的時候有一個分配了多少的時候才打點記錄的問題。這個參數就是設置打點的內存分配間隔,也就是 profile 中一個 sample 代表的內存大小。默認是設置為 512 * 1024 的。如果你將它設置為 1,則每分配一個內存塊就會在 profile 中有個打點,那么生成的 profile 的 sample 就會非常多。如果你設置為 0,那就是不做打點了

你可以通過設置 memprofilerate=1 和 GOGC=off 來關閉內存回收,並且對每個內存塊的分配進行觀察

-test.blockprofilerate n : 基本同上,控制的是 goroutine 阻塞時候打點的納秒數。默認不設置就相當於 -test.blockprofilerate=1,每一納秒都打點記錄一下

-test.parallel n : 性能測試的程序並行 cpu 數,默認等於 GOMAXPROCS

-test.timeout t : 如果測試用例運行時間超過 t,則拋出 panic

-test.cpu 1,2,4 : 程序運行在哪些 CPU 上面,使用二進制的 1 所在位代表,和 nginx 的 nginx_worker_cpu_affinity 是一個道理

-test.short : 將那些運行時間較長的測試用例運行時間縮短

示例

單元測試(測試 某個包)

在 golang 的 src 目錄下新建目錄 math,測試目錄結構如下:

ibonacci.go 代碼如下,主要有一個 Fibonacci 函數

package lib

// 斐波那契數列
// 求出第n個數的值
func Fibonacci(n int64) int64 {
    if n < 2 {
        return n
    }
    return Fibonacci(n-1) + Fibonacci(n-2)
}

fibonacci_test.go 就是測試的文件了,golang 需要測試文件一律用 “_test” 結尾,測試的函數都用 Test 開頭,代碼如下:

package lib

import (
    "testing"
)

func TestFibonacci(t *testing.T) {
    r := Fibonacci(10)
    if r != 55 {
        t.Errorf("Fibonacci(10) failed. Got %d, expected 55.", r)
    }
}

使用 go test 測試這個程序

$ go test lib
 ok lib 0.008s

性能測試

結合上面的方法,這里測試一下函數的性能,如果需要進行性能測試,則函數開頭使用 Benchmark 就可以了。

// 性能測試
func BenchmarkFibonacci(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Fibonacci(10)
    }
}

接下來執行這個性能測試:

$ go test -bench=. lib
 PASS
 BenchmarkFibonacci 5000000 436 ns/op
 ok lib 2.608s

其中第二行輸出表示這個函數運行了 5000000 次,平均運行一次的時間是 436ns。

這個性能測試只測試參數為 10 的情況。如果有需要可以測試多個參數:

// 測試參數為5的性能
func BenchmarkFibonacci5(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Fibonacci(5)
    }
}

// 測試參數為20的性能
func BenchmarkFibonacci20(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Fibonacci(20)
    }
}

運行一下:

$ go test -bench=. lib
 PASS
 BenchmarkFibonacci 5000000 357 ns/op
 BenchmarkFibonacci5 100000000 29.5 ns/op
 BenchmarkFibonacci20 50000 44688 ns/op
 ok lib 7.824s

如果性能測試的方法非常多,那需要的時間就會比較久。可以通過 -bench=參數 設置需要運行的性能測試方法:

$ go test -bench=Fibonacci20 lib
 PASS
 BenchmarkFibonacci20 50000 44367 ns/op
 ok lib 2.677s

 

 

測試 某個文件

一定要帶上被測試的原文件,否則會提示找不到包

go test -v  wechat_test.go wechat.go 

測試 某個方法

go test -v -test.run TestRefreshAccessToken

 

 

延伸閱讀:

【Go命令教程】8. go test


免責聲明!

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



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