首頁 >後端開發 >Golang >golang testing 測試方法

golang testing 測試方法

WBOY
WBOY原創
2023-05-13 12:16:071624瀏覽

Go語言是一門快速、安全、簡單的程式語言,同時也支援測試非常友善。在Golang開發測試時,能夠提高程式碼的品質和準確性,使得開發者在進行專案開發時更容易的迭代。

本文將會介紹Golang中的測試方法,包括單元測試、基準測試、效能測試以及邊界測試。我們會分享常見的測試用例和測試技巧,幫助讀者更好的了解Golang測試方法和技能,提高開發的效率和品質。

一、單元測試

1、測試案例基礎架構

測試案例的基礎架構是:

func TestFunctionName(t *testing.T) {
    // testing function
}

TestFunctionName是測試方法名,必須以Test開頭,後面的FunctionName可以任意命名。 testing.T是一個測試上下文,用來調度測試存取方法和記錄測試的狀態。在測試過程中可以利用它來報告失敗和錯誤,將測試結果輸出到控制台。

例如程式碼:

package main

import "testing"

func Sum(x int, y int) int {
    return x + y
}

func TestSum(t *testing.T) {
    got := Sum(1, 2)
    want := 3

    if got != want {
        t.Errorf("Sum(1,2) = %d; want %d", got, want)
    }
}

當程式執行時,若輸出結果和預期不一致,則會輸出報錯訊息,例如:

--- FAIL: TestSum (0.00s)
    main_test.go:11: Sum(1,2) = 4; want 3
FAIL
exit status 1
FAIL        command-line-arguments  0.005s

2、測試案例命名和組織

Golang的測試方法命名必須以Test為前綴,這樣可以讓測試框架自動識別它們,並在執行go test 命令時執行它們。同時為了避免和其他同名測試方法衝突,測試方法的命名應保證唯一性。

為了更好的組織測試案例,可以在測試案例的前面添加一些可識別的標識,例如:

  • TestXxx、BenchmarkXxx、ExampleXxx 在瀏覽器中運行範例時執行對應的函數,以Xxx 為函數名,Xxx 前面的部分不能是Test、Benchmark、Example、Output、Input 或Error,且第一個字母不能是小寫字母[a-z]
  • TestXxxShort 在go test指令中只會執行該測試方法。例如:TestParseShort()
  • TestXxxParallel 可以並行運行,可以使用t.Parallel()在測試中提高效率。例如:TestFooParallel()

3、測試用例的目標和實作

透過單元測試,可以對Golang程式碼進行品質和準確性的驗證,包括:

  • 函數是否回傳預期結果
  • 是否符合執行時間處理邏輯
  • 是否能夠處理預期以外的情況

例如程式碼:

// Add 两个整数x和y
func Add(x, y int) int {
    return x + y
}

對應的測試程式碼:

func TestAdd(t *testing.T) {
    cases := []struct {
        in1, in2, want int
    }{
        {1, 2, 3},
        {0, 0, 0},
        {-1, 1, 0},
    }
    for _, c := range cases {
        got := Add(c.in1, c.in2)
        if got != c.want {
            t.Errorf("Add(%d, %d) == %d, want %d", c.in1, c.in2, got, c.want)
        }
    }
}

Go的測試框架允許我們建立具有控制結構的測試案例,例如循環、分支和異常錯誤處理。在測試程式碼中,透過將輸入參數傳遞給函數並比較函數輸出值和預期值,然後驗證程式碼是否按照設計預期運行。

二、基準測試

Golang基準測試用於比較程式碼在不同情況下的效能差異。基準測試會多次執行程式碼,並比較運行時間。如果有速度差異,則可以確定哪些實現方式會更快。

基準測試的基本架構是:

func BenchmarkFunctionName(b *testing.B) {
    // Testing code
}

其中,BenchmarkFunctionName表示基準測試方法名,必須以Benchmark開頭,後面的FunctionName可任意命名。 testing.B則是測試上下文,用來控制測試的狀態和迭代。在基準測試過程中,可以利用它來控制測試運行次數、偵測偵測停止時可能出現的錯誤等問題。

例如程式碼:

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(1, 2)
    }
}

當程式執行時,輸出結果如下:

BenchmarkAdd-4        2000000000             0.29 ns/op
PASS
ok      _/Users/test/main    1.028s

其中,

    ##「BenchmarkAdd」 表示基準測試的名稱
  • “4” 表示測試函數並行執行的goroutine數目
  • “2000000000” 表示testing.B.Run執行的總的迭代次數,Go語言內部自適應均衡每次迭代的次數
  • 「0.29 ns/op」 表示平均每次迭代所需的時間為0.29 奈秒。
三、效能測試

效能測試用於測試程式在長時間的運行過程中的表現。例如:

func TestPerfAdd(t *testing.T) {
    for i := 0; i < 100000; i++ {
        Add(1, 2)
    }
}

其中,測試循環運行函數100000次,來測試它在長時間運行時的效能問題。非常適合用於測試程式在記憶體洩漏、檔案句柄洩漏或其他資源洩漏方面表現的好壞。

四、邊界測試

邊界測試用於測試程式碼處理邊界條件的情況,例如:

func TestBubbleSort(t *testing.T) {
    tests := []struct {
        name string
        in   []int
        want []int
    }{
        {"Sorted", []int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}},
        {"Reverse", []int{5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5}},
        {"FewElement", []int{5, 3}, []int{3, 5}},
        {"Duplicate", []int{5, 3, 5, 2, 2}, []int{2, 2, 3, 5, 5}},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            BubbleSort(tt.in)
            if !reflect.DeepEqual(tt.in, tt.want) {
                t.Errorf("test case %s expects %v but actual is %v",
                    tt.name, tt.want, tt.in)
            }
        })
    }
}

邊界測試可以檢查程式在處理邊緣條件時是否符合預期,例如:

    處理一些不正常的輸入(例如負數、0、極大/小值)
  • 讓程式處於最快或最慢的處理情況下(例如資料大小為0或最大值)
  • 為函數的各種參數設定上下限並測試函數的反應
總結

#

在測試Golang的程式碼時,應考慮測試用例的多樣性,從而能夠為程式的各個部分提供有用的、全面的測試。 Golang測試框架支援單元測試、基準測試、效能測試和邊界測試,我們可以根據實際需求進行選擇。不僅如此,我們還需要遵循一些測試最佳實踐,例如規範測試方法命名、合理分配測試任務、提取重複的測試邏輯並使測試更容易快速運行。相信掌握了這些測試技能後,讀者在進行Golang開發時能夠更深入地進行程式碼測試,並提高開發的測試效率和程式碼品質。

以上是golang testing 測試方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn