golang進階(七)——go語言的幾種測試方法

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

前言

用了go的測試架構,再想下junit的,雖然已經Junit5,那醜陋程度還是依然。

java出來的時候,還沒有很多軟體工程的概念,語言先出來了,因此需要通過不同的外掛程式慢慢補。

go就很幸運,出來的時候很多軟體工程的概念已經基本定了下來,可以加到語言特性之中,go的測試就簡便很多,不愧是為工程而生的語言

需要測試的程式

我們需要測試的程式檔案叫做utils.go,裡面有個字串反轉的方法Reverse,代碼相對簡單,這裡就不贅述了

func Reverse(s string) string {    r := []rune(s)    for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {        r[i], r[j] = r[j], r[i]    }    return string(r)}

單元測試

go的testing包可以基於包進測試,意思是執行go test預設單位是包範圍,go test可以自動執行當前包下面的所有func TestXxx(*testing.T)格式的測試方法,Xxx可以是任意字母,但最好和你需要測試方法一一對應。

建立一個測試的檔案,要以_test.go作為檔案名稱的結尾,最好和需要測試的檔案一一對應,可以一目瞭然,這些test檔案在程式構建的時候是不會一起打包到最終執行檔案或者庫中的。

我們建立utlis_test.go檔案:

func TestReverse(t *testing.T) {    if testing.Short() {        t.Skip("skipping test in short mode.")    }    cases := []struct {        in, want string    }{        {"Hello, world", "dlrow ,olleH"},        {"Hello, 世界", "界世 ,olleH"},        {"", ""},    }    for _, c := range cases {        got := Reverse(c.in)        if got != c.want {            t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)        }    }}

第一個if表示如果有-short參數,將會跳過這個測試,後面的代碼相對就很容易看懂了,判斷下輸出輸入是否一致,以上測試方法通過go test命令可以直接運行

樣本驗證

還有一種可以當做測試的方法就是使用樣本驗證程式,做一個樣本在go語言也非常簡單,告別寫點樣本程式就得寫好多main方法的時代吧,格式要以Example開頭,執行go test的時候會自動執行這些樣本,要注意一點的是,Example之後需要跟已定義的變數,否則vet會報錯。

還有一點注意的是,會自動trim,而忽略前後的空格比較。

func ExampleReverse() {    fmt.Println(Reverse("Hello, 世界"))    // Output: 界世 ,olleH}

可以驗證輸出是否與想要的一致,還有一些情況下,比如多線程的情況下,輸出順序是隨機的,這點go也考慮到了,

func ExampleReverse() {    fmt.Println(Reverse("Hello, world"))    fmt.Println(Reverse("Hello, 世界"))    // Unordered Output: 界世 ,olleH    // dlrow ,olleH  // AA}

Unordered Output來表示無序輸出

基準測試

基準測試以Benchmark為首碼,必須要執行b.N次,這樣的測試才有對照性,b.N的值是系統根據實際情況去調整的,從而保證測試的穩定性。

b.ResetTimer()之前的處理不會放到執行時間裡,也不會輸出到報告中,所以可以在之前做一些不計劃作為測試報告的操作

基準測試並不會預設執行,他需要增加-bench參數,例如go test -bench .

func BenchmarkReverse(b *testing.B) {    b.ResetTimer()    for i := 0; i < b.N; i++ {        Reverse("s string")    }}

基準測試也可以開啟並行測試,需要執行b.RunParallel(func(pb *testing.PB)方法,預設會以邏輯CPU個數來進行並行測試。

個人意見唯寫並行測試就ok了,如果想非並行可以指定cpu數量為1,例如go test -bench . -cpu 1

func BenchmarkReverseParallel(b *testing.B) {    b.RunParallel(func(pb *testing.PB) {        for pb.Next() {            Reverse("s string")        }    })}

子測試和子基準測試

還可以通過TB的Run方法開啟子測試和子基準測試,主要是可以共用公用的設定和資源清除的管理

每個子測試都有一個唯一的名字,以父測試用/隔開來唯一表示,啟動並執行時候使用-run regexp指定測試和-bench regexp來指定基準測試,.表示所有。

還有一個特點就是所有子測試完成,父測試才算完成,而且所有測試都是並行的,這樣可以把一些需要同步完成的操作來進行分組測試。

func TestTeardownParallel(t *testing.T) {    // This Run will not return until the parallel tests finish.    t.Run("group", func(t *testing.T) {        t.Run("Test1", parallelTest1)        t.Run("Test2", parallelTest2)        t.Run("Test3", parallelTest3)    })    // <tear-down code>}

Main測試

還有一個可以做一些初始化的地方就是main測試了,代碼也相對簡單。

要注意的testmain是在主協程啟動並執行,m.Run()開始運行時,其他測試才會執行

func TestMain(m *testing.M) {    fmt.Println("init")    os.Exit(m.Run())}

附帶揭露一下滴滴的jsoniter

為了kpi連基準測試都要作弊嗎?

可見自己會寫基準測試很重要,不會被人忽悠瘸了

來看我的基準測試

type ColorGroup struct {    ID     int    Name   string    Colors []string}var group = ColorGroup{    ID:     1,    Name:   "Reds",    Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},}func BenchmarkStdJson(b *testing.B) {    b.RunParallel(func(pb *testing.PB) {        for pb.Next() {            b, err := json.Marshal(group)            if err != nil {                fmt.Println(b)            }        }    })}func BenchmarkIterJson(b *testing.B) {    b.RunParallel(func(pb *testing.PB) {        for pb.Next() {            b, err := jsoniter.Marshal(group)            if err != nil {                fmt.Println(b)            }        }    })}

測試結果:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.