go testing 包的介紹和使用

golang 標準庫 testing 包爲 Go 代碼支持了自動化測試。使用 go test 命令來執行。git

介紹

函數測試定義:github

func TestXxx(*testing.T)

這個 TestXxx 函數式放在一個文件尾部名 _test.go 中。golang

一個簡單的測試:併發

func TestAbs(t *testing.T) {
    got := Abs(-1)
    if got != 1 {
        t.Errorf("Abs(-1) = %d; want 1", got)
    }
}

Benchmarks

函數定義:函數

func BenchmarkXxx(*testing.B)

測試基準經過 go test -bench 來執行。測試

  • -cover 命令行參數,顯示覆蓋率信息

一個簡單的基準測試:插件

func BenchmarkHello(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fmt.Sprintf("hello")
    }
}

BenchmarkHello    10000000    282 ns/op

基準函數經過執行 b.N 次。例如上面 10000000 次每一個執行時間在 282 ns。命令行

Subtests and Sub-benchmarks(子測試與子基準)

這種子測試能夠實現表驅動基準測試和建立分層測試。也能夠提供通用的 setup 和 teardown 方法。線程

func TestFoo(t *testing.T) {
    // <setup code>
    t.Run("A=1", func(t *testing.T) { ... })
    t.Run("A=2", func(t *testing.T) { ... })
    t.Run("B=1", func(t *testing.T) { ... })
    // <tear-down code>
}

Main

有時測試必須爲測試代碼添加額外的 setup 和 teardown 在測試以前和以後。也有時必須控制那些代碼在主線程執行,去支持其餘狀況。代碼定義:日誌

func TestMain(m *testing.M)

當執行測試時會調用 TestMain,而不是直接運行測試。這時能夠在 m.Run 的先後調用 setup 和 teardown 方法。

func TestMain(m *testing.M) {
    // call flag.Parse() here if TestMain uses flags
  // setup
    code := m.Run()
  // teardown
    os.Exit(code)
}

經常使用的測試方法

  • Error(args ...interface{}) 輸出測試錯誤信息。
  • Log(args ...interface{}) 輸出測試日誌信息。
  • Parallel() 併發測試。
  • Fatal(args ...interface{}) 致命錯誤信息。
  • Skip(args ...interface{}) 跳過這個測試錯誤。

testdata

testdata 測試文件夾下能夠存放一些測試須要用到的測試數據、靜態文件。

表驅動測試(Table-driven test)

表測試是經過構建數據表來運行測試的一種方法。能夠結合 subtest 來覆蓋各類測試狀況。

func TestOrderSrv_OrderSendToPay(t *testing.T) {
    room := Room{}
    db.First(&room)
    order := test_createOrder(t, room)

    type args struct {
        order *models.Order
    }
    tests := []struct {
        name    string
        args    args
        wantErr bool
    }{
        {
            name: "提交訂單",
            args: args{
                order: order,
            },
            wantErr: false,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            s := &OrderSrv{}
            if err := s.OrderSendToPay(tt.args.order); (err != nil) != tt.wantErr {
                t.Errorf("OrderSrv.OrderSendToPay() error = %v, wantErr %v", err, tt.wantErr)
            }
        })
    }
}

建議使用 vscode 或 golandIDE 的 Go 插件支持生成測試用例模板。

Ref

相關文章
相關標籤/搜索