基本用法
- 測試文件名以
_test結(jié)尾 - 函數(shù)名以
Test開始
待測試代碼
// split.go
package split
import "strings"
func Split(str string, sep string) []string {
var ret []string
index := strings.Index(str, sep)
for index >= 0 {
ret = append(ret, str[:index])
str = str[index+len(sep):]
index = strings.Index(str, sep)
}
ret = append(ret, str)
return ret
}
測試代碼
// split_test.go
package split
import (
"reflect"
"testing"
)
func TestSplit(t *testing.T) {
got := Split("a:b:c", ":")
want := []string{"a", "b", "c"}
if !reflect.DeepEqual(got, want) {
t.Errorf("expected: %v, got: %v\n", want, got)
}
}
到所在目錄執(zhí)行
go test -v
測試組
優(yōu)化多個測試用例的代碼
func TestSplitByGroup(t *testing.T) {
type testCase struct {
str string
sep string
want []string
}
testGroup := []testCase {
{"babcbef", "b", []string{"", "a", "c", "ef"}},
{ "a:b:c", ":", []string{"a", "b", "c"}},
{"abcef", "bc", []string{"a", "ef"}},
}
for _, tg := range testGroup {
got := Split(tg.str, tg.sep)
if !reflect.DeepEqual(got, tg.want) {
t.Errorf("expected: %v, got: %v\n", tg.want, got)
}
}
}
子測試
用于區(qū)分測試組中,具體執(zhí)行了哪個測試用例
func TestSplit3(t *testing.T) {
type testCase struct {
str string
sep string
want []string
}
testGroup := map[string]testCase{
"case1": {str: "babcbef", sep: "b", want: []string{"", "a", "c", "ef"}},
"case2": {str: "a:b:c", sep: ":", want: []string{"a", "b", "c"}},
"case3": {str: "abcef", sep: "bc", want: []string{"a", "ef1"}},
}
for name, tg := range testGroup {
t.Run(name, func(t *testing.T) {
got := Split(tg.str, tg.sep)
if !reflect.DeepEqual(got, tg.want) {
t.Errorf("expected: %#v, got: %#v\n", tg.want, got)
}
})
}
}
測試結(jié)果可以看到是case3結(jié)果出錯了

image-20221119000527171
如果想跑某一個測試用例
go test -run=Split3/case1
go test -run=Split
// 如果run參數(shù)錯了,找不到測試用例,會warning
// testing: warning: no tests to run
測試覆蓋率
- 函數(shù)覆蓋率100%
- 代碼覆蓋著60%
簡單使用
go test -cover

image-20221119001017029
使用工具
go test -cover -coverprofile=cover.out
go tool cover -html=cover.out

image-20221119001337342
基準(zhǔn)測試
- 函數(shù)名以
Benchmark開始 - 必須執(zhí)行
b.N次
func BenchmarkSplit(b *testing.B) {
for i := 0; i < b.N; i++ {
Split("a:b:c", ":")
}
}
運(yùn)行
go test -bench=Split
go test -bench .

image-20221119141057822
看內(nèi)存信息
go test -bench=Split -benchmem

image-20221119141221966
每次操作使用了三次內(nèi)存分配
還可以重置時間
b.ResetTimer()
Test Main
當(dāng)測試文件中有TestMain函數(shù),執(zhí)行go test就會會調(diào)用TestMain,否則會創(chuàng)建一個默認(rèn)的TestMain;我們自定義TestMain時,需要手動調(diào)用m.Run()否則測試函數(shù)不會執(zhí)行
func TestMain(m *testing.M) {
fmt.Println("before code...")
retCode := m.Run()
fmt.Println("retCode", retCode)
fmt.Println("after code...")
os.Exit(retCode)
}