鍍金池/ 教程/ GO/ go test
go install
go clean
go list
go test
go doc與godoc
go build
go fix與go tool fix
go tool pprof
go run
go env
go tool cgo
標(biāo)準(zhǔn)命令詳解
go get
go vet與go tool vet

go test

go test命令用于對(duì)Go語(yǔ)言編寫(xiě)的程序進(jìn)行測(cè)試。這種測(cè)試是以代碼包為單位的。當(dāng)然,這還需要測(cè)試源碼文件的幫助。關(guān)于怎樣編寫(xiě)并寫(xiě)好Go程序測(cè)試代碼,我們會(huì)在本章的第二節(jié)加以詳述。在這里,我們只討論怎樣使用命令啟動(dòng)測(cè)試。

go test命令會(huì)自動(dòng)測(cè)試每一個(gè)指定的代碼包。當(dāng)然,前提是指定的代碼包中存在測(cè)試源碼文件。關(guān)于測(cè)試源碼文件方面的知識(shí),在我的圖書(shū)《Go并發(fā)編程實(shí)戰(zhàn)》中有詳細(xì)介紹。測(cè)試源碼文件是名稱以“_test.go”為后綴的、內(nèi)含若干測(cè)試函數(shù)的源碼文件。測(cè)試函數(shù)一般是以“Test”為名稱前綴并有一個(gè)類型為“testing.T”的參數(shù)聲明的函數(shù).

現(xiàn)在,我們來(lái)測(cè)試goc2p項(xiàng)目中的幾個(gè)代碼包。在使用go test命令時(shí)指定代碼包的方式與其他命令無(wú)異——使用代碼包導(dǎo)入路徑。如果需要測(cè)試多個(gè)代碼包,則需要在它們的導(dǎo)入路徑之間加入空格以示分隔。示例如下:

hc@ubt:~$ go test basic cnet/ctcp pkgtool
ok      basic   0.012s
ok      cnet/ctcp   2.014s
ok      pkgtool 0.014s

go test命令在執(zhí)行完所有的代碼包中的測(cè)試文件之后,會(huì)以代碼包為單位打印出測(cè)試概要信息。在上面的示例中,對(duì)應(yīng)三個(gè)代碼包的三行信息的第一列都是“ok”。這說(shuō)明它們都通過(guò)了測(cè)試。每行的第三列顯示運(yùn)行相應(yīng)測(cè)試所用的時(shí)間,以秒為單位。我們還可以在代碼包目錄下運(yùn)行不加任何參數(shù)的運(yùn)行go test命令。其作用和結(jié)果與上面的示例是一樣的。

另外,我們還可以指定測(cè)試源碼文件來(lái)進(jìn)行測(cè)試。這樣的話,go test命令只會(huì)執(zhí)行指定文件中的測(cè)試,像這樣:

    hc@ubt:~/golang/goc2p/src/pkgtool$ go test envir_test.go
# command-line-arguments
./envir_test.go:25: undefined: GetGoroot
./envir_test.go:40: undefined: GetAllGopath
./envir_test.go:81: undefined: GetSrcDirs
./envir_test.go:83: undefined: GetAllGopath
./envir_test.go:90: undefined: GetGoroot
FAIL    command-line-arguments [build failed]

我們看到,與指定源碼文件進(jìn)行編譯或運(yùn)行一樣,命令程序會(huì)為指定的源碼文件生成一個(gè)虛擬代碼包——“command-line-arguments”。但是,測(cè)試并沒(méi)有通過(guò)。但其原因并不是測(cè)試失敗,而是編譯失敗。對(duì)于運(yùn)行這次測(cè)試的命令程序來(lái)說(shuō),測(cè)試源碼文件envir_test.go是屬于代碼包“command-line-arguments”的。并且,這個(gè)測(cè)試源碼文件中使用了庫(kù)源碼文件envir.go中的函數(shù)。但是,它卻沒(méi)有顯示導(dǎo)入這個(gè)庫(kù)源碼文件所屬的代碼包。這顯然會(huì)引起編譯錯(cuò)誤。如果想解決這個(gè)問(wèn)題,我們還需要在執(zhí)行命令時(shí)加入這個(gè)測(cè)試源碼文件所測(cè)試的那個(gè)源碼文件。示例如下:

hc@ubt:~/golang/goc2p/src/pkgtool$ go test envir_test.go envir.go
ok      command-line-arguments  0.010s

現(xiàn)在,我們故意使代碼包pkgtool中的某個(gè)測(cè)試失敗?,F(xiàn)在我們?cè)賮?lái)運(yùn)行測(cè)試:

hc@ubt:~$ go test basic cnet/ctcp pkgtool
ok      basic   0.010s
ok      cnet/ctcp       2.015s
--- FAIL: TestGetSrcDirs (0.00 seconds)
        envir_test.go:85: Error: The src dir '/usr/local/go/src/pkg' is incorrect.
FAIL
FAIL    pkgtool 0.009s

我們通過(guò)以上示例中的概要信息獲知,測(cè)試源碼文件中envir_test.go的測(cè)試函數(shù)TestGetSrcDirs中的測(cè)試失敗了。在包含測(cè)試失敗的測(cè)試源碼文件名的那一行信息中,緊跟測(cè)試源碼文件名的用冒號(hào)分隔的數(shù)字是錯(cuò)誤信息所處的行號(hào),在行號(hào)后面用冒號(hào)分隔的是錯(cuò)誤信息。這個(gè)錯(cuò)誤信息的內(nèi)容是用戶自行編寫(xiě)的。另外,概要信息的最后一行以“FAIL”為前綴。這表明針對(duì)代碼包pkgtool的測(cè)試未通過(guò)。未通過(guò)的原因在前面的信息中已有描述。

一般情況下,我們會(huì)把測(cè)試源碼文件與被測(cè)試的源碼文件放在同一個(gè)代碼包中。并且,這些源碼文件中聲明的包名也都是相同的。除此之外我們還有一種選擇,那就是測(cè)試源碼文件中聲明的包名可以是所屬包名再加“_test”后綴。我們把這種測(cè)試源碼文件叫做包外測(cè)試源碼文件。不過(guò),包外測(cè)試源碼文件存在一個(gè)弊端,那就是在它們的測(cè)試函數(shù)中無(wú)法測(cè)試被測(cè)源碼文件中的包級(jí)私有的程序?qū)嶓w,比如包級(jí)私有的變量、函數(shù)和結(jié)構(gòu)體類型。這是因?yàn)檫@兩者的所屬代碼包是不相同的。所以,我們一般很少會(huì)編寫(xiě)包外測(cè)試源碼文件。

關(guān)于標(biāo)記

go test命令的標(biāo)記處理部分是龐大且繁雜的,以至于使Go語(yǔ)言的開(kāi)發(fā)者們不得不把這一部分的邏輯從go test命令程序主體中分離出來(lái)并建立單獨(dú)的源碼文件。因?yàn)?code>go test命令中包含了編譯動(dòng)作,所以它可以接受可用于go build命令的所有標(biāo)記。另外,它還有很多特有的標(biāo)記。這些標(biāo)記的用于控制命令本身的動(dòng)作,有的用于控制和設(shè)置測(cè)試的過(guò)程和環(huán)境,還有的用于生成更詳細(xì)的測(cè)試結(jié)果和統(tǒng)計(jì)信息。

可用于go test命令的幾個(gè)比較常用的標(biāo)記是-c、-i-o。這兩個(gè)就是用于控制go test命令本身的動(dòng)作的標(biāo)記。詳見(jiàn)下表。

表0-6 go test命令的標(biāo)記說(shuō)明

標(biāo)記名稱 標(biāo)記描述
-c 生成用于運(yùn)行測(cè)試的可執(zhí)行文件,但不執(zhí)行它。這個(gè)可執(zhí)行文件會(huì)被命名為“pkg.test”,其中的“pkg”即為被測(cè)試代碼包的導(dǎo)入路徑的最后一個(gè)元素的名稱。
-i 安裝/重新安裝運(yùn)行測(cè)試所需的依賴包,但不編譯和運(yùn)行測(cè)試代碼。
-o 指定用于運(yùn)行測(cè)試的可執(zhí)行文件的名稱。追加該標(biāo)記不會(huì)影響測(cè)試代碼的運(yùn)行,除非同時(shí)追加了標(biāo)記-c-i。

上述這幾個(gè)標(biāo)記可以搭配使用。搭配使用的目的可以是讓go test命令既安裝依賴包又編譯測(cè)試代碼,但不運(yùn)行測(cè)試。也就是說(shuō),讓命令程序跑一遍運(yùn)行測(cè)試之前的所有流程。這可以測(cè)試一下測(cè)試過(guò)程。注意,在加入-c標(biāo)記后,命令程序會(huì)把用于運(yùn)行測(cè)試的可執(zhí)行文件存放到當(dāng)前目錄下。

除此之外,go test命令還有很多功效各異的標(biāo)記。但是由于這些標(biāo)記的復(fù)雜性,我們需要結(jié)合測(cè)試源碼文件進(jìn)行詳細(xì)的講解。所以我們?cè)谶@里略過(guò)不講。如果讀者想了解相關(guān)詳情,請(qǐng)參看《Go并發(fā)編程實(shí)戰(zhàn)》的第5章。