0%

Go语言测试

东风夜放花千树。更吹落、星如雨。宝马雕车香满路。凤箫声动,玉壶光转,一夜鱼龙舞。蛾儿雪柳黄金缕。笑语盈盈暗香去。众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。 —— 南宋.辛弃疾 《青玉案·元夕》

一、基础

  1. go test命令用于对Go语言编写的程序进行测试,会自动读取源码目录下面名为*_test.go的源码文件,生成并运行测试用的可执行文件并输出结果信息。

    • 查看命名参数使用方法go help testflag
    • 常用参数
      • -v:显示测试的详细命令
      • -bench regexp:执行正则匹配的基准测试函数,如-bench=.-bench '^(BenchmarkFib)$'
      • -cover:开户测试覆盖率
      • -run regexp:只运行正则匹配的函数
  2. 测试分类

    • 功能测试
      • 功能测试文件名必须为xxx_test.go
      • 功能测试的函数名必须为TestXxx,即大驼峰命名法
      • 功能测试函数参数必须为t *testing.T
        • t.Fail()
        • t.FailNow
        • t.Log()
        • t.Logf()
        • t.Error()
        • t.Errorf()
        • t.Fatal()
        • t.Fatalf()
    • 性能测试,也称基准测试
      • 性能测试文件名同上要求
      • 性能测试的函数名必须为以BenchmarkXxx,即大驼峰命名法
      • 性能测试函数参数必须为b *testing.B
      • 执行go test 命令时需要加-bench参数,可为正则表达式或具体的被测文件
    • 样例测试,也称示例测试
      • 样例测试文件名同上要求
      • 样例测试的函数名必须为以ExampleXxx,即大驼峰命名法
      • 样例测试函数参数没有强制要求
    • 模糊测试,也称fuzzing测试(1.18引入)
      • 文件名同上要求
      • 函数名固定以FuzzXxx开头
      • 函数固定以*testing.F类型做为入参
      • 两个函数
        • t.Add:用于开发者输入模糊测试的种子数据,fuzzing根据这些种子数据自动随机生成更多测试数据
        • t.Fuzz:开始运行模糊测试,t.Fuzz的入参是一个Fuzz Target函数
  3. 相关命令

    • go env GOCACHE,查看缓存目录
    • go clean -cache,删除所有缓存
    • go clean -testcache,删除测试缓存

二、使用

  1. list.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package unit

func Fib(n int) int {
if n < 2 {
return n
}
return Fib(n-1) + Fib(n-2)
}

func Reverse(s string) string {
// b := [] byte(s)
b := []rune(s)
for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
b[i], b[j] = b[j], b[i]
}
return string(b)
}
  1. list_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package unit

import (
"testing"
"unicode/utf8"
)

func BenchmarkFib(b *testing.B) {
var (
in = 7
expect = 13
)
actual := Fib(in)
if actual != expect {
b.Errorf("Fib(%d) = %d; want %d", in, actual, expect)
}
}

func TestFib(t *testing.T) {
var (
in = 7
//expect = 13
//故意整错
expect = 23
)
actual := Fib(in)
if actual != expect {
t.Errorf("Fib(%d) = %d; want %d", in, actual, expect)
}
}

func FuzzReverse(f *testing.F) {
testcases := []string{"Hello, world", " ", "!12345"}
for _, tc := range testcases {
f.Add(tc) // Use f.Add to provide a seed corpus
}
f.Fuzz(func(t *testing.T, orig string) {
rev := Reverse(orig)
doubleRev := Reverse(rev)
if orig != doubleRev {
t.Errorf("Before: %q, after: %q", orig, doubleRev)
}
if utf8.ValidString(orig) && !utf8.ValidString(rev) {
t.Errorf("Reverse produced invalid UTF-8 string %q", rev)
}
})
}


func TestReverse(t *testing.T) {
testcases := []struct {
in, want string
}{
{"abc", "cba"},
{"liu", "uil"},
{"12345", "54321"},
}
for _, tc := range testcases {
rev := Reverse(tc.in)
if rev != tc.want {
t.Errorf("Reverse: %q, want %q", rev, tc.want)
}
}
}
  1. 执行测试
    • 功能测试go test -cover -v list_test.go list.go
    • 基准测试go test -bench=. -cover -v
      • 对于TestFib函数expect = 23,执行go test -bench=. -cover -v会报错,可以通过-run选择不测试该函数
      • 只测试满足正则匹配的函数go test -v -cover -run '^Benchmark$' -bench=.
    • 样例测试
    • 模糊测试go test -fuzz=Fuzz,也可指定具体的函数-fuzz=FuzzReverse

三、参考

  1. 参考一