基本用法
- 测试文件名以
_test
结尾 - 函数名以
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)
}
}
到所在目录执行
go test -v
测试组
优化多个测试用例的代码
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)
}
}
}
子测试
用于区分测试组中,具体执行了哪个测试用例
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)
}
})
}
}
测试结果可以看到是case3结果出错了
如果想跑某一个测试用例
go test -run=Split3/case1
go test -run=Split
// 如果run参数错了,找不到测试用例,会warning
// testing: warning: no tests to run
测试覆盖率
- 函数覆盖率100%
- 代码覆盖着60%
简单使用
go test -cover
使用工具
go test -cover -coverprofile=cover.out
go tool cover -html=cover.out
基准测试
- 函数名以
Benchmark
开始 - 必须执行
b.N
次
func BenchmarkSplit(b *testing.B) {
for i := 0; i < b.N; i++ {
Split("a:b:c", ":")
}
}
运行
go test -bench=Split
go test -bench .
看内存信息
go test -bench=Split -benchmem
每次操作使用了三次内存分配
还可以重置时间
b.ResetTimer()
Test Main
当测试文件中有TestMain
函数,执行go test
就会会调用TestMain
,否则会创建一个默认的TestMain
;我们自定义TestMain
时,需要手动调用m.Run()
否则测试函数不会执行
func TestMain(m *testing.M) {
fmt.Println("before code...")
retCode := m.Run()
fmt.Println("retCode", retCode)
fmt.Println("after code...")
os.Exit(retCode)
}