| 
                            
                                  testing包服务于自动化测试基本测试Table Drvien Test基于表的测试通过表形式进行测试每种情况的输入和期望输出,从而测试程序的正确性 
	
		
			| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | func TestFib(t *testing.T) {     var fibTests = []struct {         in       int // input         expected int // expected result     }{         {1, 1},         {2, 1},         {3, 2},         {4, 3},         {5, 5},         {6, 8},         {7, 13},     }     for _, tt := range fibTests {         actual := Fib(tt.in)         if actual != tt.expected {             t.Errorf("Fib(%d) = %d; expected %d", tt.in, actual, tt.expected)         }     } } |  
	跳过测试
	
		SkipNow(): 跳过测试Skip(): 跳过测试并输出logSkipf(): 跳过测试并格式化输出log失败但继续
	
		Fail(): 标记测试失败,但继续执行FailNow(): 标记测试失败,不继续执行Error(): 标记测试失败,并输出Errorf(): 标记测试失败,并格式化输出输出
	
	失败且中断
	
		Fatal(): 相当于FailNow() + Log()Fatalf(): 相当于FailNow() + Logf() Parallel()Parallel方法表示会和其他带有Parallel方法的测试并行执行 ExampleXXX()ExampleXXX方法中如果含有Output: 开头的行注释,则会在运行测试期间,将输出和注释中的值相比较 
如果是不确定的顺序,则可以以Unordered output: 作为开头 但如果没有这样的注释,这就是一个普通函数,不能被直接运行 压力测试压力测试方法以func BenchmarkXXX(*testing.B)函数名展现。 函数体格式如下 
	
		
			| 1 2 3 4 5 | func BenchmarkHello(b *testing.B) {     for i := 0; i < b.N; i++ {         // do sth     } } |  压力测试会自动调整b.N使得持续足够长时间 重置计时器如果想要跳过不需要计时的耗时工作,那么可以通过b.ResetTimer()重置计时器 并行测试如果想并行压力测试,那么可以通过RunParallel实现 
	
		
			| 1 2 3 4 5 | func BenchmarkHelloParallel(b *testing.B) {   b.RunParallel(func(pb *testing.PB) {     // do sth   }) } |  内存统计ReportAllocs方法用于打开内存统计功能 输出结果就会变成如下形式 
// 方法名        迭代总次数        平均每次迭代时间        平均每次迭代分配字节数        平均每次迭代的内存分配次数BenchmarkHello        2000000           898 ns/op         368 B/op           9 allocs/op
 自定义度量值ReportMetric(n float64, unit string)汇报自定义度量值 
	如果度量值是每次迭代的,你应该将其除以 b.N。按照惯例,单位应该以 “/op” 结尾。ReportMetric 会覆盖同一单位的任何先前报告的值。如果单位是空字符串,或者单位包含任何空格,ReportMetric 会引发 panic。如果单位是基准测试框架本身通常报告的单位(如 “allocs/op”),ReportMetric 会覆盖该度量值。将 “ns/op” 设置为 0 将禁止该内置度量值。 
	
		
			| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | testing.Benchmark(func(b *testing.B) {         var compares int64         for i := 0; i < b.N; i++ {             s := []int{5, 4, 3, 2, 1}             sort.Slice(s, func(i, j int) bool {                 compares++                 return s[i] < s[j]             })         }         // This metric is per-operation, so divide by b.N and         // report it as a "/op" unit.         b.ReportMetric(float64(compares)/float64(b.N), "compares/op")         // This metric is per-time, so divide by b.Elapsed and         // report it as a "/ns" unit.         b.ReportMetric(float64(compares)/float64(b.Elapsed().Nanoseconds()), "compares/ns")     }) |  子测试子测试也就是可以在测试中测试,子测试可以共用初始化等公共操作,并可以做父测试执行前的必要操作 
	
		
			| 1 2 3 4 5 6 7 8 9 10 11 | func TestSubTest(t *testing.T) {     t.Run("sub1", func(t *testing.T) {         t.Log("sub1")     })     t.Run("sub2", func(t *testing.T) {         t.Log("sub2")     })     t.Run("sub3", func(t *testing.T) {         t.Log("sub3")     }) } |  模糊测试模糊测试方法名为func FuzzXXX(f *testing.F) 
	
		
			| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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     }     // 进行模糊测试。对于string类型的参数,将生成随机字符串     // 对于本测试中的Reverse方法是可逆的,因此可以通过两次逆行操作来验证其正确性     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)         }     }) } |  运行模糊测试有go test和go test -fuzz两种方式,前者仅会运行手动添加的用例,而后者则会随机生成数据 
值得注意的是如果go test -fuzz执行之后存在运行错误的用例会添加到语料库文件中,那么即使下次执行的是go test也依然会执行语料库文件中的用例 Ref https://go.dev/doc/tutorial/fuzz https://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter09/09.0.html 
 |