獨孤九劍(0x04) - 測試篇

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

《南皮縣誌·風土誌下·歌謠》:“兵馬不動,糧草先行”。作戰時兵馬還沒出動,軍用糧草的運輸要先行一步。在開發新功能之前,先編寫測試代碼,然後只編寫使測試通過的功能代碼,這種測試驅動開發的軟體開發模式是我非常推薦的。

對 Dit 的貢獻要求需要通過單元測試,編寫 Dit 的任意模組,都需要一併編寫測試案例。本文先簡述一下 Go 對測試的支援,後續會陸續提供 Dit 的測試方案和測試報告。

Go 對測試的支援

Go 內建的測試架構 testing 支援單元測試和效能測試。Go 規定測試檔案以 _test.go 為尾碼,使用命令 go test 命令自動運行測試案例。

單元測試

Test 開頭的方法為一個測試案例,並擁有一個參數 *testing.T, 寫法如下:

func TestXxx(*testing.T)

Xxx 部分為任意的字母數字組合,首字母不能是小寫字母。*testing.T 可記錄錯誤或者標記錯誤狀態。可通過Short判斷略過一部分測試,加快測試時間。如下:

func TestTimeConsuming(t *testing.T) {  if testing.Short() {    t.Skip("skipping test in short mode.")  }  ...}

效能測試

效能測試用例以 Benchmark 開始,參數為 *testing.B, 寫法如下:

func BenchmarkXxx(*testing.B)

使用 go test 運行效能測試用例時,需要加上參數 -bench

在編寫效能測試用例時,需牢記在迴圈體內使用 testing.B.N , 以使測試可以正常的運行:

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

對耗時的初始化操作,可在測試案例內部重設計時器 ResetTimer,確保引入不必要的誤差:

func BenchmarkBigLen(b *testing.B) {  big := NewBig()  b.ResetTimer()  for i := 0; i < b.N; i++ {    big.Len()  }}

使用 RunParallel 測試並行模組, 運行時需要加上參數 -cpu:

func BenchmarkTemplateParallel(b *testing.B) {  templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))  b.RunParallel(func(pb *testing.PB) {    var buf bytes.Buffer    for pb.Next() {      buf.Reset()      templ.Execute(&buf, "World")    }  })}

標準輸出測試

testing 包提供對標準終端輸出的測試, 測試案例以 Example 開始,結果使用注釋的方式,寫在 Output: 之後:

func ExampleHello() {  fmt.Println("hello")  // Output: hello}

Example 用例的命名規則:

func Example() { ... }func ExampleF() { ... } // F - functionfunc ExampleT() { ... } // T - typefunc ExampleT_M() { ... } // T_M - method M on type T// 多個 example 可用尾碼區分,The suffix must start with a lower-case letter.func Example_suffix() { ... }func ExampleF_suffix() { ... }func ExampleT_suffix() { ... }func ExampleT_M_suffix() { ... }

Main 測試

當需要批量 setup 或 teardown 測試環境時,可使用:

func TestMain(m *testing.M)

TestMain 簡單實現如下:

func TestMain(m *testing.M) {  flag.Parse()  os.Exit(m.Run())}

Demo

寫一個簡單的樣本,來 Demo 一下 testing 測試架構的用法。

// div.gopackage testimport (  "errors")func div(a, b int) (int, error) {  if b == 0 {    return 0, errors.New("b must NOT be 0")  }  return a / b, nil}// div_test.gopackage testimport (  "errors"  "flag"  "fmt"  "os"  "testing"  "time")func TestDivNormal(t *testing.T) {  ret, err := div(6, 2)  if err != nil || ret != 3 {    t.Error("6/2=3")  }}func TestDivZero(t *testing.T) {  _, err := div(6, 0)  if err.Error() != errors.New("b must NOT be 0").Error() {    t.Error("zero div error")  }}func BenchmarkDiv(b *testing.B) {  b.Log("run times:", b.N)  for i := 0; i < b.N; i++ {    div(6, 2)  }}func BenchmarkDiv_Sleep(b *testing.B) {  b.Log("run times:", b.N)  time.Sleep(3000) // 類比費時操作  b.ResetTimer()  for i := 0; i < b.N; i++ {    div(6, 2)  }}func ExampleOutput() {  ret, _ := div(6, 2)  fmt.Println("6 / 2 =", ret)  // Output:  // 6 / 2 = 3}func TestMain(m *testing.M) {  flag.Parse()  fmt.Println("Setup ... Done")  ret := m.Run()  fmt.Println("Teardown ... Done")  os.Exit(ret)}

運行 go test -v, 結果如下:

localhost:test zdd$ go test -vSetup ... Done=== RUN TestDivNormal--- PASS: TestDivNormal (0.00s)=== RUN TestDivZero--- PASS: TestDivZero (0.00s)=== RUN: ExampleOutput--- PASS: ExampleOutput (0.00s)PASSTeardown ... Doneok    github.com/zddhub/hellogo/test  0.005s

預設不執行效能測試用例,使用go test -v -bench .執行:

localhost:test zdd$ go test -v -bench .Setup ... Done=== RUN TestDivNormal--- PASS: TestDivNormal (0.00s)=== RUN TestDivZero--- PASS: TestDivZero (0.00s)=== RUN: ExampleOutput--- PASS: ExampleOutput (0.00s)PASSBenchmarkDiv  100000000         16.2 ns/op--- BENCH: BenchmarkDiv  div_test.go:27: run times: 1  div_test.go:27: run times: 100  div_test.go:27: run times: 10000  div_test.go:27: run times: 1000000  div_test.go:27: run times: 100000000BenchmarkDiv_Sleep  100000000         16.4 ns/op--- BENCH: BenchmarkDiv_Sleep  div_test.go:34: run times: 1  div_test.go:34: run times: 100  div_test.go:34: run times: 10000  div_test.go:34: run times: 1000000  div_test.go:34: run times: 100000000Teardown ... Doneok    github.com/zddhub/hellogo/test  3.305s

木乙言己 zddhub 出品
號: zddnotes
Just for fun!

文章唯寫給自己,如果你也喜歡,歡迎掃描以下二維碼關注哦~

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.