1. 程式人生 > >golang 測試,單元測試和基準測試

golang 測試,單元測試和基準測試

go test xxx.go

帶 -v 表示冗餘輸出,成功pass的也會輸出資訊。

檔案命名使用 xx_test.go 儲存在專案目錄裡即可,也可以新建個test目錄,TestAll

測試分為單元測試(功能)和基準測試(效能)。

單元測試函式名Test開頭,接收一個指標型引數(*testing.T)。Example示例程式也算單元測試,不用接收引數。

go test -v -run="指定函式名"

// one_test.go
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
)

const checkMark = "\u2713" // 對號 %v
const ballotX = "\u2717"   // 錯號

// 輸出測試
func TestA(t *testing.T) {
	t.Log(checkMark, "測試成功,Logf")
	t.Error(ballotX, "失敗了但繼續,Errorf")
	t.Fatal(ballotX, "\t 失敗了並終止,Fatalf, \\t是製表符")
	t.Log("執行不到這裡了")
}

// 模擬伺服器返回
func mockServer() *httptest.Server {
	f := func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(200)
		fmt.Fprintf(w, "success")
	}
	return httptest.NewServer(http.HandlerFunc(f))
}
func TestB(t *testing.T) {
	server := mockServer()
	defer server.Close()
	resp, _ := http.Get(server.URL)
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	t.Log(checkMark, "GET內容:", string(body))

	//	func init(){ .. } 這裡可以自建net/http伺服器
	//    req,err := http.NewRequest()
	//    rw := httptest.NewRecorder()
	//    http.DefaultServeMux.ServeHTTP(rw,req)
	//    這樣可以模擬外部訪問,rw.Body就是內容了

}

// Example示例也是測試,如果返回結果和註釋中的結果不一樣,就會FAIL。
func ExampleC() {
	fmt.Println("233")
	//    Output:
	//    233
}

結果如下:

C:/Go/bin/go.exe test -v [C:/Users/pxlol/Desktop/demo]
=== RUN   TestA
--- FAIL: TestA (0.00s)
	2018_7_31_test.go:17: ✓ 測試成功,Logf
	2018_7_31_test.go:18: ✗ 失敗了但繼續,Errorf
	2018_7_31_test.go:19: ✗ 	 失敗了並終止,Fatalf, \t是製表符
=== RUN   TestB
--- PASS: TestB (0.00s)
	2018_7_31_test.go:37: ✓ GET內容: success
=== RUN   ExampleC
--- PASS: ExampleC (0.00s)
FAIL
exit status 1
FAIL	_/C_/Users/pxlol/Desktop/demo	0.088s

基準測試以Benchmark開頭,接收一個指標型引數(*testing.B)

go test -v -run="none" -bench=.    不允許單元測試,執行所有的基準測試,-bench可以指定函式名,支援正則。

-benchmem 表示分配記憶體的次數和位元組數,-benchtime="3s" 表示持續3秒

// two_test.go
package main

import (
	"fmt"
	"strconv"
	"testing"
)

func BenchmarkA(b *testing.B) {
	number := 10
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		fmt.Sprintf("%d", number)
	}
}

func BenchmarkB(b *testing.B) {
	number := 10
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		strconv.Itoa(number)
	}
}

執行結果:

$ go test -v -bench=. -benchmem
goos: windows
goarch: amd64
BenchmarkA-4    20000000               122 ns/op              16 B/op          2 allocs/op
BenchmarkB-4    100000000               11.0 ns/op             0 B/op          0 allocs/op
PASS
ok      _/C_/Users/pxlol/Desktop/demo   3.791s

122ns/op 表示每次操作耗時122納秒, 16B表示每次操作用了16位元組,2 allocs表示每次操作分配記憶體2次。