溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Golang單元測(cè)試中的技巧是什么

發(fā)布時(shí)間:2023-03-13 14:18:22 來源:億速云 閱讀:107 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“Golang單元測(cè)試中的技巧是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Golang單元測(cè)試中的技巧是什么”吧!

    打樁測(cè)試

    當(dāng)我們?cè)诰帉憜卧獪y(cè)試的時(shí)候,有時(shí)我們非常想 mock 掉其中一個(gè)方法,但是這個(gè)方法又沒有接口去定義和實(shí)現(xiàn)(無法用 github.com/golang/mock 來實(shí)現(xiàn)),這時(shí)就可以嘗試看看我們的打樁黑科技。

    代碼

    這里我們使用 github.com/agiledragon/gomonkey 來實(shí)現(xiàn)。

    實(shí)際中,經(jīng)常在代碼中會(huì)遇到一些隨機(jī)值的情況,比如驗(yàn)證碼。為了方便測(cè)試,我們會(huì)想要 mock 掉隨機(jī)值方法,讓每次產(chǎn)生的值固定方便后續(xù)的測(cè)試。

    package main
    
    import (
      "fmt"
      "testing"
    
      "github.com/agiledragon/gomonkey/v2"
      "go-demo/m/unit-test/other/rand"
    )
    
    func init() {
      gomonkey.ApplyFunc(rand.Number, func() int { return 666 })
    }
    
    func TestRand(t *testing.T) {
      fmt.Println(rand.Number())
    }

    其中 rand.Number() 是我們?cè)诹硪粋€(gè)包中實(shí)現(xiàn)的方法。我們使用 gomonkey.ApplyFunc 相當(dāng)于直接替換了原有方法的實(shí)現(xiàn),強(qiáng)制返回了 mock 的數(shù)據(jù) 666。

    注意事項(xiàng)

    • 使用 gomonkey 時(shí),注意一定要使用 -gcflags=all=-l 來禁止內(nèi)聯(lián)優(yōu)化,否則容易導(dǎo)致打樁不生效。如:go test -gcflags=all=-l -v

    • 在 Mac 的 M1 下打樁不生效,可以使用環(huán)境變量 GOARCH=amd64 來進(jìn)行測(cè)試,只不過這樣就無法進(jìn)行斷點(diǎn)調(diào)試。https://github.com/agiledragon/gomonkey/issues/77

    • 畢竟是黑科技,實(shí)際使用環(huán)境對(duì)于測(cè)試還是有影響的。

    壓測(cè)

    這里的壓測(cè)通常不是對(duì)接口的壓測(cè),而是對(duì)于某些方法的壓測(cè)。Golang 提供 非常好用的 b *testing.B 來專門進(jìn)行壓測(cè)。

    代碼

    非常容易上手,讓我們直接來看代碼

    var numbers = []int{
      100,
      1000,
      77777,
      666666,
    }
    
    func BenchmarkPrimeNumbers(b *testing.B) {
      for _, v := range numbers {
        b.Run(fmt.Sprintf("calc_num_%d", v), func(b *testing.B) {
          for i := 0; i < b.N; i++ {
            primeNumbers(v)
          }
        })
      }
    }

    使用

    使用 -bench=. 即可

    ? go test -bench=. b_test.go
    goos: darwin
    goarch: arm64
    BenchmarkPrimeNumbers/calc_num_100-8             3391329               348.9 ns/op
    BenchmarkPrimeNumbers/calc_num_1000-8             293733              3979 ns/op
    BenchmarkPrimeNumbers/calc_num_77777-8               730           1619089 ns/op
    BenchmarkPrimeNumbers/calc_num_666666-8               42          28509805 ns/op
    PASS
    ok      command-line-arguments  5.846s

    可以看到次數(shù)和耗時(shí),這樣的數(shù)據(jù)經(jīng)常會(huì)被貼在開源項(xiàng)目README的性能比較板塊中。

    測(cè)試覆蓋率

    單元測(cè)試當(dāng)然少不了覆蓋率咯,看著高高的覆蓋率才有成就感對(duì)不對(duì)?

    我們可以使用 -cover 參數(shù)來統(tǒng)計(jì)單元測(cè)試的代碼覆蓋率

    ? go test -cover .           
    ok      go-demo/m/unit-test/service     0.879s  coverage: 70.0% of statements

    還可以生成 profile 然后通過可視化網(wǎng)頁查看分析

    ? go test ./... -coverprofile=cover.out
    ok      go-demo/m/unit-test/service     0.108s  coverage: 70.0% of statements
    ? go tool cover -html=cover.out

    當(dāng)然,如果你和我一樣使用 goland 進(jìn)行開發(fā),可以直接在界面上點(diǎn)擊單元測(cè)試,就可以快速進(jìn)行覆蓋率測(cè)試,并且展示也很方便,很快能看到有哪些代碼沒有被測(cè)試覆蓋。

    Golang單元測(cè)試中的技巧是什么

    Golang單元測(cè)試中的技巧是什么

    表格驅(qū)動(dòng)測(cè)試

    TDT 的提出也算是給單元測(cè)試提供了一條不錯(cuò)的思路。主要的形式就是將測(cè)試的數(shù)據(jù)做成類似表格,然后測(cè)試的時(shí)候遍歷所有的數(shù)據(jù)來進(jìn)行測(cè)試,測(cè)試代碼不動(dòng),只需要增加測(cè)試數(shù)據(jù)就可以了。go 很多官方庫用了這樣的寫法來做測(cè)試。

    package main
    
    import (
        "testing"
    )
    
    func TestAdd(t *testing.T) {
        tests := []struct {
            a, b, expected int
        }{
            {1, 2, 3},
            {0, 0, 0},
            {-1, 1, 0},
            {-1, -1, -2},
        }
    
        for _, test := range tests {
            result := Add(test.a, test.b)
            if result != test.expected {
                t.Errorf("Add(%d, %d) = %d; expected %d", test.a, test.b, result, test.expected)
            }
        }
    }
    
    func Add(a, b int) int {
        return a + b
    }

    我們可以通過 github.com/cweill/gotests 來幫助我們快速生成想要的表格驅(qū)動(dòng)測(cè)試代碼

    感謝各位的閱讀,以上就是“Golang單元測(cè)試中的技巧是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Golang單元測(cè)試中的技巧是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI