? ? ? ?在Go中,go test子命令是Go語言包的測試驅(qū)動程序,這些包根據(jù)某些約定組織在一起,在一個包目錄中,以_test.go結(jié)尾的文件不是go build命令編譯的目標,而是go test編譯的目標。在*_test.go文件中,三種函數(shù)需要特殊對待,即功能測試函數(shù)、基準測試函數(shù)和示例函數(shù)。功能測試函數(shù)是以Test前綴命名的函數(shù),用來檢測一些程序邏輯的正確性,go test運行測試函數(shù),并且報告結(jié)果是PASS還是FAIL?;鶞蕼y試函數(shù)的名稱以Benchmark開頭,用來測試某些操作的性能,go test匯報操作的平均執(zhí)行時間。go test工具掃描*_test.go文件來尋找特殊函數(shù),并生成一個臨時的main包來調(diào)用它們,然后編譯和運行,并匯報結(jié)果,最后清空臨時文件。
? ? ? 每一個測試文件都需要導(dǎo)入testing包,這些函數(shù)的函數(shù)簽名格式是這樣的:func TestName (t *testing.T) { //... } ,比如sin函數(shù)就是func TestSin(t *testing.T) {/* ... */},cos函數(shù)就是func TestCos(t *testing.T) {/* ... */}。測試可以讓我們順序地檢查內(nèi)容,如果一個測試套件(test suite)里面有很多測試用例,我們可以選擇性地測試用例來加加測試過程。
? ? ? 命令-v可以輸出包中每個測試用例的名稱和執(zhí)行的時間,命令-run的參數(shù)是一個正則表達式,它可以使得go test只有運行那些測試函數(shù)名稱匹配給定模式的函數(shù)。當(dāng)然,一旦我們使得選擇的測試用例通過之后,在我們提交更改之前,我們必須重新使用不帶開關(guān)的go test來運行一次整個測試套件。當(dāng)調(diào)用t.Errorf輸出的失敗的調(diào)試用例信息沒有包含整個跟蹤棧信息,也不會導(dǎo)致程序宕機或者終止執(zhí)行,這和很多其他語言的測試框架中的斷言不同。測試用例彼此都是獨立的,如果一個測試表中的一個條目造成測試失敗,那么其他條目的測試仍然會繼續(xù)測試,這樣我們就會在一次測試過程中發(fā)現(xiàn)多個失敗的情況,更方便我們進行錯誤的尋找。有的時候,我們需要中止測試,那么我們就可以使用t.Fatal或者t.Fatalf函數(shù)來終止測試。這些函數(shù)的調(diào)用必須和Test函數(shù)在同樣一個goroutine中,而不能在測試用例創(chuàng)建的其他goroutine中。
? ? ? ?測試錯誤信息一般的格式是f(X)=Y, want z,這里f(x)表示需要執(zhí)行的操作和它的輸入,y是實際的輸出結(jié)果,z是期望得到的一個結(jié)果。處于方便,對于f(x)我們會使用Go的語法。在基于表的測試中,輸出x是很重要的,因為一條斷言語句會在不同的輸入情況下執(zhí)行多次,錯誤消息要避免樣板文字和冗余信息。如果x、y、z都比較長,可以輸出準確代表各部分的概要信息。