golang 單元測試(一)


單元測試函數類型

Test(功能測試)

函數規則:

  • 函數名: TestXxxx , 以Test為前綴。Xxxx以大寫字母開頭
  • 參數類型: *testing.T
func TestXxxx(t *testing.T){...}

編寫一個簡單的例子,假設有下面一個待測函數:


func add(a, b int) int {
	return a + b
}

測試代碼如下:

import "testing"

func TestAdd(t *testing.T) {
	cases := []struct {
		first    int
		second   int
		excepted int
	}{
		{1, 2, 3},
		{1, 2, 4},
	}

	for _, c := range cases {
		result := add(c.first, c.second)
		if result != c.excepted {
			t.Fatalf("add function failed, first: %d, second:%d, execpted:%d, result:%d", c.first, c.second, c.excepted, result)
		}
	}
}

執行 go go test -v 結果如下:

=== RUN   TestAdd
--- FAIL: TestAdd (0.00s)
    example_test.go:30: add function failed, first: 1, second:2, execpted:4, result:3
FAIL
exit status 1
FAIL    gotest/gotest   0.006s

第二個測試用例出錯,未能通過單元測試,需要檢查測試數據或者被測試函數是否符合我們的預期。

從上述過程可以看出, TestXxxx 可以理解為功能性測試,其目的在於測試函數的功能性是否正確, 應當編寫盡可能多的測試用例來驗證被測函數的正確性。

Benchmark(基准測試)

函數規則:

  • 函數名: BenchmarkXxxx, 以Benchmark為前綴。Xxxx以大寫字母開頭
  • 參數類型: *testing.B
func BenchmarkXxx(b *testing.B){...}

性能測試函數如下:

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

執行 go test -bench=. -run=^$,結果如下:

goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8   	2000000000	         0.32 ns/op
PASS
ok  	gotest/gotest	0.667s

測試結果說明:

  • -8 表示 8個邏輯cpu個數(下文會解釋)
  • 2000000000 表示執行了 2000000000 次
  • 0.32 ns/op 每次操作耗時
  • 0.667s 是總時長

性能測試函數計時器:

當性能測試函數中有一些額外的初始化操作時,可以通過啟停計時器來屏蔽這些操作對最終性能測試的影響。簡單例子如下:

func BenchmarkAdd(b *testing.B) {
	time.Sleep(10 * time.Second)
	for i := 0; i < b.N; i++ {
		add(1, 2)
	}
}

執行命令go test -bench=.,結果如下:

goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8   	       1	10004479538 ns/op
PASS
ok  	gotest/gotest	10.011s

單個測試函數耗時為 10004479538 ns,同時我們也可以看到,這個函數執行一次就已經達到了最大上限時間。

加上時間計數器:

func BenchmarkAdd(b *testing.B) {
	b.StopTimer()
	time.Sleep(10 * time.Second)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		add(1, 2)
	}
}

測試結果如下:

goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8   	2000000000	         0.34 ns/op
PASS
ok  	gotest/gotest	60.751s

單次執行耗時為: 0.34 ns 了。

Tips:

對於 b.N 參數而言, test 命令先會嘗試設置為1,之后執行函數。如果測試函數沒有達到執行上限的話, test 函數會增大,之后再次執行測試函數,如此往復,直到執行時間大於或者等於上限時間為止。 上限時間可以使用 -benchtime設定

Example(示例測試)

函數規則:

  • 函數名: ExampleXxx
  • 輸出內容至標准輸出,參數列表沒有限制

示例測試函數如下:

func Println(content string) {
	fmt.Println("The output of\nthis example.")
}
func ExamplePrintln() {
	Println("The output of\nthis example.")
	// Output: The output of
	// this example.
}

go test 命令會檢測實際輸出與注釋中的期望輸出是否一致, 一致則測試通過,不一致則測試失敗。

go test 常用參數

  • -cpu: 設置測試最大 cpu 邏輯數(也就是 GPM 中 P, 最大並行執行的 gorouting 數量, 默認等於 cpu 核數)
  • -count: 設置執行測試函數的次數, 默認為 1
  • -run: 執行功能測試函數, 支持正則匹配, 可以選擇測試函數或者測試文件來僅測試單個函數或者單個文件
  • -bench: 執行基准測試函數, 支持正在匹配
  • -benchtime: 基准測試最大探索時間上限
  • -parallel: 設置同一個被測試代碼包中的功能測試函數的最大並發執行數
  • -v: 是展示測試過程信息

更多的參數可以參考下文的官方文檔

參考

golang 官方文檔

極客時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM