Go語言中的測試(一)

在計算機編程中冻记,單元測試Unit Testing又稱為模塊測試,是針對程序模塊來進行正確性檢驗的測試工作撼玄。
在Go語言中有幾種方法可以用于單元測試戈咳,基礎測試basic test是指只使用一組參數(shù)和結果來測試一段代碼猜憎;表組測試table test是指使用多組參數(shù)和結果測試一段代碼尉尾。此外蚂子,還可以使用一些方法來模仿mock測試代碼需要使用到的外部資源本缠,例如數(shù)據(jù)庫或者網(wǎng)絡服務器斥扛。

單元測試

testing是Go語言的一個包,它將提供自動化測試的功能丹锹,通過go test命令能夠自動執(zhí)行如下形式的函數(shù):

func TestXxx(*testing.T)

其中Xxx可以是任何字母稀颁、數(shù)字、字符串楣黍,但是第一個字母一定不能是小寫字母匾灶。在這些函數(shù)中,使用Error租漂,Fail或相關方法來返回失敗信號阶女。
要編寫一個新的測試模塊,需要創(chuàng)建一個名稱以_test.go為結尾的文件哩治,該文件包含TestXxx函數(shù)秃踩,最后將該文件放在與被測試的包相同的包目錄中。

第一個單元測試

我們來看一個簡單的例子:

package main

import "fmt"

func main() {
    fmt.Println(Age(-7))
}

func Age(n int) int {
    if n > 0 {
        return n
    }
    n = 0
    return n
}

我們在來寫一下測試文件业筏,注意名稱的定義吞瞪,一定要記得在文件名稱后面加_test.go

package main

import "testing"

func TestFib(t *testing.T) {
    var (
        input = -100
        expected = 0
    )
    actual := Age(input)
    if actual != expected {
        t.Errorf("Fib(%d) = %d, expected is %d.", input, actual, expected)
    }
}

當我們運行之后得到的結果為ok時,那就表明我們的測試是成功的驾孔,函數(shù)也是沒有問題的芍秆。
這就是基礎測試,我們接下來再看一下表組測試翠勉,它是可以提供多組數(shù)據(jù)的測試方式妖啥。

表組測試

我們通過一個判斷一個數(shù)字是否為素數(shù)的例子來看一下表組測試:

package main

import "fmt"

func main() {
    fmt.Println(isPrime(25))
}

func isPrime(value int) bool {
    if value <= 3 {
        return value >= 2
    }
    if value%2 == 0 || value%3 == 0 {
        return false
    }
    for i := 5; i <= value; i += 6 {
        if value%i == 0 || value%(i+2) == 0 {
            return  false
        }
    }
    return true
}

基于以上的程序,我們的測試文件可以這樣來寫:

package main

import "testing"

func TestPrime(t *testing.T) {
    var primeTests = []struct {
        input int
        expected bool
    }{
        {1, false},
        {2, true},
        {3, true},
        {4, false},
        {5, true},
        {6, false},
        {7, false},
    }
    for _, tt := range primeTests {
        actual := isPrime(tt.input)
        if actual != tt.expected {
            t.Errorf("%d %v %v", tt.input, actual, tt.expected)
        }
    }
}

在每一次的測試當中对碌,測試函數(shù)執(zhí)行結束返回荆虱,或者測試函數(shù)調(diào)用FailNowFatalFatalf怀读,SkipNow诉位,SkipSkipf中的任意一個時,這次測試即宣告結束菜枷。

Fail記錄失敗信息苍糠,然后繼續(xù)執(zhí)行后續(xù)用例。
FailNow記錄失敗信息啤誊,所有測試中斷岳瞭。
SkipNow不會記錄失敗的用例信息,然后終止測試蚊锹。
Skip記錄失敗信息瞳筏,中斷后續(xù)測試。
Skipf相比前者多了一個格式化輸出牡昆。

模擬測試

針對模擬網(wǎng)絡訪問姚炕,標準庫提供了一個httptest包,可以模擬HTTP的網(wǎng)絡調(diào)用丢烘,下面我們還是通過例子來看一下:

import (
    "encoding/json"
    "net/http"
)

func Routes() {
    http.HandleFunc("/sendjson", SendJSON)
}

func SendJSON(rw http.ResponseWriter, r *http.Request) {
    u := struct {
        Name string
    }{
        Name: "Alice",
    }
    rw.Header().Set("Content-Type", "application/json")
    rw.WriteHeader(http.StatusOK)
    json.NewEncoder(rw).Encode(u)
}

現(xiàn)在我們對這API服務進行測試:

func init() {
    request.Routes()
}

func TestSendJSON(t *testing.T) {
    req, err := http.NewRequest(http.MethodGet, "/sendjson", nil)
    if err != nil {
        t.Fatal("Creating request failed.")
    }
    
    rw := httptest.NewRecorder()
    http.DefaultServeMux.ServeHTTP(rw, req)
    
    log.Println("code: ", rw.Code)
    
    log.Println("body: ", rw.Body.String())
}
測試覆蓋率

盡可能模擬更多的場景來測試代碼的不同情況钻心,但是有時候的確也有忘記測試的代碼,這時候就需要涉及到測試覆蓋率的概念來進行參考了铅协。
我們在對測試覆蓋率進行測試的時候,需要在執(zhí)行go test的時候多添加一個參數(shù)-coverprofile摊沉,完整的命令就是:

go test -v -coverprofile=c.out

-coverprofile是指定生成的覆蓋率文件狐史,在我們的例子中是c.out

$ go test -v -coverprofile=c.out
=== RUN   TestPrime
--- PASS: TestPrime (0.00s)
PASS
coverage: 66.7% of statements
ok      _/home/hdc/goProgramming/testing1       0.001s

我們可以看到覆蓋率為66.7%说墨。說明并沒有完全覆蓋骏全,那么我們該如何查看還有哪些代碼沒有被測試到呢?這時就需要使用測試覆蓋率文件c.out了尼斧。生成報告使用的工具是:

go tool cover -html=c.out -o=tag.html

這樣就可以生成一個名字為tag.htmlHTML格式的測試覆蓋率報告了姜贡。但一定要注意文件存放的路徑,因為路徑如果不滿足條件的話是無法生成的棺棵。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末楼咳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子烛恤,更是在濱河造成了極大的恐慌母怜,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缚柏,死亡現(xiàn)場離奇詭異苹熏,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門轨域,熙熙樓的掌柜王于貴愁眉苦臉地迎上來袱耽,“玉大人,你說我怎么就攤上這事干发≈炀蓿” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵铐然,是天一觀的道長蔬崩。 經(jīng)常有香客問我,道長搀暑,這世上最難降的妖魔是什么沥阳? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮自点,結果婚禮上桐罕,老公的妹妹穿的比我還像新娘。我一直安慰自己桂敛,他們只是感情好功炮,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著术唬,像睡著了一般薪伏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上粗仓,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天嫁怀,我揣著相機與錄音,去河邊找鬼借浊。 笑死塘淑,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蚂斤。 我是一名探鬼主播存捺,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼曙蒸!你這毒婦竟也來了捌治?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤纽窟,失蹤者是張志新(化名)和其女友劉穎具滴,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體师倔,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡构韵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年周蹭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疲恢。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡凶朗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出显拳,到底是詐尸還是另有隱情棚愤,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布杂数,位于F島的核電站宛畦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏揍移。R本人自食惡果不足惜次和,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望那伐。 院中可真熱鬧踏施,春花似錦、人聲如沸罕邀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诉探。三九已至日熬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肾胯,已是汗流浹背竖席。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阳液,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓揣炕,卻偏偏與公主長得像帘皿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子畸陡,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容