1. 程式人生 > 其它 >Go test 命令列引數

Go test 命令列引數

轉自:《Go專家程式設計》Go test 命令列引數

前言

go test有非常豐富的引數,一些引數用於控制測試的編譯,另一些引數控制測試的執行。

有關測試覆蓋率、vet和pprof相關的引數先略過,我們在討論相關內容時再詳細介紹。

控制編譯的引數

-args

指示go test把-args後面的引數帶到測試中去。具體的測試函式會跟據此引數來控制測試流程。

-args後面可以附帶多個引數,所有引數都將以字串形式傳入,每個引數做為一個string,並存放到字串切片中。

// TestArgs 用於演示如何解析-args引數
func TestArgs(t *testing.T) {
    if !flag.Parsed() {
        flag.Parse()
    }

    argList := flag.Args() // flag.Args() 返回 -args 後面的所有引數,以切片表示,每個元素代表一個引數
    for _, arg := range argList {
        if arg == "cloud" {
            t.Log("Running in cloud.")
        }else {
            t.Log("Running in other mode.")
        }
    }
}

執行測試時帶入引數:

E:\OpenSource\GitHub\RainbowMango\GoExpertProgrammingSourceCode\GoExpert\src\gotest>go test -run TestArgs -v -args "cloud"
TestMain setup.
=== RUN   TestArgs
--- PASS: TestArgs (0.00s)
    unit_test.go:28: Running in cloud.
PASS
TestMain tear-down.
ok      gotest  0.353s

通過引數-args指定傳遞給測試的引數。

-json

-json 引數用於指示go test將結果輸出轉換成json格式,以方便自動化測試解析使用。

示例如下:

E:\OpenSource\GitHub\RainbowMango\GoExpertProgrammingSourceCode\GoExpert\src\gotest>go test -run TestAdd -json
{"Time":"2019-02-28T15:46:50.3756322+08:00","Action":"output","Package":"gotest","Output":"TestMain setup.\n"}
{"Time":"2019-02-28T15:46:50.4228258+08:00","Action":"run","Package":"gotest","Test":"TestAdd"}
{"Time":"2019-02-28T15:46:50.423809+08:00","Action":"output","Package":"gotest","Test":"TestAdd","Output":"=== RUN   TestAdd\n"}
{"Time":"2019-02-28T15:46:50.423809+08:00","Action":"output","Package":"gotest","Test":"TestAdd","Output":"--- PASS: TestAdd (0.00s)\n"}
{"Time":"2019-02-28T15:46:50.423809+08:00","Action":"pass","Package":"gotest","Test":"TestAdd","Elapsed":0}
{"Time":"2019-02-28T15:46:50.4247922+08:00","Action":"output","Package":"gotest","Output":"PASS\n"}
{"Time":"2019-02-28T15:46:50.4247922+08:00","Action":"output","Package":"gotest","Output":"TestMain tear-down.\n"}
{"Time":"2019-02-28T15:46:50.4257754+08:00","Action":"output","Package":"gotest","Output":"ok  \tgotest\t0.465s\n"}
{"Time":"2019-02-28T15:46:50.4257754+08:00","Action":"pass","Package":"gotest","Elapsed":0.465}

-o <file>

-o 引數指定生成的二進位制可執行程式,並執行測試,測試結束不會刪除該程式。

沒有此引數時,go test生成的二進位制可執行程式存放到臨時目錄,執行結束便刪除。

示例如下:

E:\OpenSource\GitHub\RainbowMango\GoExpertProgrammingSourceCode\GoExpert\src\gotest>go test -run TestAdd -o TestAdd
TestMain setup.
PASS
TestMain tear-down.
ok      gotest  0.439s
E:\OpenSource\GitHub\RainbowMango\GoExpertProgrammingSourceCode\GoExpert\src\gotest>TestAdd
TestMain setup.
PASS
TestMain tear-down.

本例中,使用-o 引數指定生成二進位制檔案"TestAdd"並存放到當前目錄,測試執行結束後,仍然可以直接執行該二進位制程式。

控制測試的引數

-bench regexp

go test預設不執行效能測試,使用-bench引數才可以執行,而且只執行效能測試函式。

其中正則表示式用於篩選所要執行的效能測試。如果要執行所有的效能測試,使用引數"-bench ."或"-bench=."。

此處的正則表示式不是嚴格意義上的正則,而是種包含關係。

比如有如下三個效能測試:

  • func BenchmarkMakeSliceWithoutAlloc(b *testing.B)
  • func BenchmarkMakeSliceWithPreAlloc(b *testing.B)
  • func BenchmarkSetBytes(b *testing.B)

使用引數“-bench=Slice”,那麼前兩個測試因為都包含"Slice",所以都會被執行,第三個測試則不會執行。

對於包含子測試的場景下,匹配是按層匹配的。舉一個包含子測試的例子:

func BenchmarkSub(b *testing.B) {
    b.Run("A=1", benchSub1)
    b.Run("A=2", benchSub2)
    b.Run("B=1", benchSub3)
}

測試函式命名規則中,子測試的名字需要以父測試名字做為字首並以"/"連線,上面的例子實際上是包含4個測試:

  • Sub
  • Sub/A=1
  • Sub/A=2
  • Sub/B=1

如果想執行三個子測試,那麼使用引數“-bench Sub”。如果只想執行“Sub/A=1”,則使用引數"-bench Sub/A=1"。如果想執行"Sub/A=1"和“Sub/A=2”,則使用引數"-bench Sub/A="。

-benchtime <t>s

-benchtime指定每個效能測試的執行時間,如果不指定,則使用預設時間1s。

例如,執定每個效能測試執行2s,則引數為:"go test -bench Sub/A=1 -benchtime 2s"。

-cpu 1,2,4

-cpu 引數提供一個CPU個數的列表,提供此列表後,那麼測試將按照這個列表指定的CPU數設定GOMAXPROCS並分別測試。

比如“-cpu 1,2”,那麼每個測試將執行兩次,一次是用1個CPU執行,一次是用2個CPU執行。 例如,使用命令"go test -bench Sub/A=1 -cpu 1,2,3,4" 執行測試:

BenchmarkSub/A=1                    1000           1256835 ns/op
BenchmarkSub/A=1-2                  2000            912109 ns/op
BenchmarkSub/A=1-3                  2000            888671 ns/op
BenchmarkSub/A=1-4                  2000            894531 ns/op

測試結果中測試名後面的-2、-3、-4分別代表執行時GOMAXPROCS的數值。 如果GOMAXPROCS為1,則不顯示。

-count n

-count指定每個測試執行的次數,預設執行一次。

例如,指定測試執行2次:

E:\OpenSource\GitHub\RainbowMango\GoExpertProgrammingSourceCode\GoExpert\src\gotest>go test -bench Sub/A=1 -count 2
TestMain setup.
goos: windows
goarch: amd64
pkg: gotest
BenchmarkSub/A=1-4                  2000            917968 ns/op
BenchmarkSub/A=1-4                  2000            882812 ns/op
PASS
TestMain tear-down.
ok      gotest  10.236s

可以看到結果中也將呈現兩次的測試結果。

如果使用-count指定執行次數的同時還指定了-cpu列表,那麼測試將在每種CPU數量下執行count指定的次數。

注意,示例測試不關心-count和-cpu引數,它總是執行一次。

-failfast

預設情況下,go test將會執行所有匹配到的測試,並最後列印測試結果,無論成功或失敗。

-failfast指定如果有測試出現失敗,則立即停止測試。這在有大量的測試需要執行時,能夠更快的發現問題。

-list regexp

-list 只是列出匹配成功的測試函式,並不真正執行。而且,不會列出子函式。

例如,使用引數"-list Sub"則只會列出包含子測試的三個測試,但不會列出子測試:

E:\OpenSource\GitHub\RainbowMango\GoExpertProgrammingSourceCode\GoExpert\src\gotest>go test -list Sub
TestMain setup.
TestSubParallel
TestSub
BenchmarkSub
TestMain tear-down.
ok      gotest  0.396s

-parallel n

指定測試的最大併發數。

當測試使用t.Parallel()方法將測試轉為併發時,將受到最大併發數的限制,預設情況下最多有GOMAXPROCS個測試併發,其他的測試只能阻塞等待。

-run regexp

跟據正則表示式執行單元測試和示例測試。正則匹配規則與-bench 類似。

-timeout d

預設情況下,測試執行超過10分鐘就會超時而退出。

例時,我們把超時時間設定為1s,由本來需要3s的測試就會因超時而退出:

E:\OpenSource\GitHub\RainbowMango\GoExpertProgrammingSourceCode\GoExpert\src\gotest>go test -timeout=1s
TestMain setup.
panic: test timed out after 1s

設定超時可以按秒、按分和按時:

  • 按秒設定:-timeout xs或-timeout=xs
  • 按分設定:-timeout xm或-timeout=xm
  • 按時設定:-timeout xh或-timeout=xh

-v

預設情況下,測試結果只打印簡單的測試結果,-v 引數可以列印詳細的日誌。

效能測試下,總是列印日誌,因為日誌有時會影響效能結果。

-benchmem

預設情況下,效能測試結果只打印執行次數、每個操作耗時。使用-benchmem則可以列印每個操作分配的位元組數、每個操作分配的物件數。

// 沒有使用-benchmem
BenchmarkMakeSliceWithoutAlloc-4            2000            971191 ns/op

// 使用-benchmem
BenchmarkMakeSliceWithoutAlloc-4            2000            914550 ns/op         4654335 B/op         30 allocs/op

此處,每個操作的含義是放到迴圈中的操作,如下示例所示:

func BenchmarkMakeSliceWithoutAlloc(b *testing.B) {
    for i := 0; i < b.N; i++ {
        gotest.MakeSliceWithoutAlloc() // 一次操作
    }
}

轉自:《Go專家程式設計》Go test 命令列引數