Go基础之测试与性能调优

一.测试 

 1.传统测试 VS 表格驱动测试

传统测试                  表格驱动测试     

 1.测试数据与测试逻辑混在一起       1.分离的测试数据和测试逻辑

 2.出错信息不明确             2.明确的出错信息

 3.一旦一个数据出错测试全部结束      3.可以部分失败

 go语言的语法使得我们更容易实践表格驱动测试

传统测试                                                                                                       表格驱动测试

@Test  public void testAdd(){                                                                         tests := [ ] struct {a, b, c int32} {

    assertEquals(3, add(1, 2));                                                                             {1, 2, 3}, 

    assertEquals(2, add(0, 2));                                                                           {0, 2, 2},

    assertEquals(0, add(0, 0));                         {0, 0, 0},                                                                       

    assertEquals(0, add(-1, 1));                                                                       {-1, 1, 0},                                                                     

    assertEquals(Integer.MIN_VALUE,                                                                 {math.MaxInt32, 1, math.MinInt32},

    add(1, Integer.MAX_VALUE));                                                                     }

}                                                                                                                        for _, test := range tests {                                                                                                                                                                             if actual := add(test.a, test.b); actual != test.c {                                                                                                                                          }                                                                                                                                                                                                          }                                                          

 2. 测试文件

  • "testing"包 提供对 Go 包的自动化测试的支持。

  • 在终端进入要测试的文件包中,通过 `go test` 命令,能够自动执行如下形式的任何函数:
  func TestXxx(*testing.T)

  注:其中 Xxx 可以是任何字母数字字符串(但第一个字母不能是 [a-z]),用于识别测试例程。

  • 在这些函数中,使用 Error, Fail 或相关方法来进行错误说明。要编写一个新的测试套件,需要创建一个名称以 _test.go 结尾的文件,该文件包含 `TestXxx` 函数,如上所述。 将该文件放在与被测试的包相同的包中。该文件将被排除在正常的程序包之外,但在运行 “go test” 命令时将被包含。 有关详细信息,请运行 “go help test” 和 “go help testflag” 了解。
package main

import (
	"math"
	"fmt"
)

func Triangle(a, b int) int {
	c := int(math.Sqrt(float64(a*a+b*b)))
	return c
}

func main(){
	fmt.Println(Triangle(3, 4))
}



//测试文件
package main

import (
	"testing"
)

func TestTriangle(t *testing.T){
	tests := []struct{
		a, b, c int
	}{
		{3, 4, 5},
		{5, 12, 13},
		{8, 15, 17},
		{12, 35, 37},
	}
	
	for _, tt := range tests {
		
		if actual := Triangle(tt.a, tt.b); actual != tt.c{
			t.Errorf("Triangle(%d, %d) got %d, expacted %d", tt.a, tt.b, actual, tt.c)
		}
		
	} 
	
}

 3.查看代码覆盖率 

命令行输入:

  go test -coverprofile=c.out    // 生成覆盖率文件c.out

       go tool cover -html=c.out      //使用 go tool 来查看c,out     

 4.http测试 

  • 通过使用假的 Request / Response
  • 使用"ne/http/testing"包,通过起服务器

 二.性能优化

 1.基准测试(Benchmarks)

  • 如下形式的函数:
  func BenchmarkXxx(*testing.B)

  被认为是基准测试,可以与测试函数   "func TestXxx(*testing.T)"  放在同一个文件中,通过 "go test" 命令,加上 -bench flag 来执行 (go test -bench .  )。多个基准测试按照顺序运行。

  testing flags 的详细描述, 参见 https://github.com/golang/go/blob/master/cmd/go/#hdr-Description_of_testing_flags.

  • 基准测试函数样例看起来如下所示:
  func BenchmarkHello(b *testing.B) {
      for i := 0; i < b.N; i++ {
          fmt.Sprintf("hello")   // 待测试的代码段
      }
  }

   基准函数会运行目标代码 b.N 次。在基准执行期间,会调整 b.N 直到基准测试函数持续足够长的时间。输出

   BenchmarkHello    10000000    282 ns/op

   意味着循环执行了 10000000 次,每次循环花费 282 纳秒(ns)。

  • 如果在运行前基准测试需要一些耗时的配置,则可以先重置定时器:
   func BenchmarkBigLen(b *testing.B) {
       big := NewBig()
       b.ResetTimer()
       for i := 0; i < b.N; i++ {
           big.Len()
       }
   }

 2.具体优化 

命令行输入:

  go test -bench . -cpuprofile cpu.out     // 生成记录cpu具体执行时间文件 cpu.out (二进制文件)

  go tool pprof cpu.out                           //打开 pprof 命令行

  在 pprof 命令行下输入: web          // 在web页面显示cpu时间分配图,可以针对cpu占用时间长的代码进行优化

     注: pprof 下使用 web 需安装  "graphviz"    下载:Download | Graphviz

        更多 pprof 命令 可以 输入"help"查看

三. 生成文档

  • 在代码中写的注释可以生成文档
  • 在测试文件中写的Examples既可以用来做测试,同时也可以将example生成在文档中
  • 使用 go doc / godoc 来 查看 / 生成 文档

   命令行输入:godoc 包名 函数名    //直接在终端查看某个包或某函数的注释文档

         godoc -http :6060     //在 http://localhost:6060 查看文档 

Examples

  • 该包运行并验证示例代码。示例函数可以包括以 "Output:" 开头的行注释,并在运行测试时与函数的标准输出进行比较。 (比较时会忽略前导和尾随空格。)例如:
    func ExampleHello() {
            fmt.Println("hello")
            // Output: hello
    }

    func ExampleSalutations() {
            fmt.Println("hello, and")
            fmt.Println("goodbye")
            // Output:
            // hello, and
            // goodbye
    }
  • "Unordered output:" 形式的注释,和 "Output:" 类似,但是能够以任意顺序匹配行:
    func ExamplePerm() {
        for _, value := range Perm(4) {
            fmt.Println(value)
        }
        // Unordered output: 4
        // 2
        // 1
        // 3
        // 0
    }
  • 没有输出注释的示例函数被编译但不执行。
  • example 声明的命名约定:包,函数 F,类型 T,类型 T 上的方法 M 依次是:
    func Example() { ... }
    func ExampleF() { ... }
    func ExampleT() { ... }
    func ExampleT_M() { ... }
  • 可以为 包/类型/函数/方法 提供多个 example 函数,这通过在名称上附加一个不同的后缀来实现。后缀必须是以小写字母开头。
    func Example_suffix() { ... }
    func ExampleF_suffix() { ... }
    func ExampleT_suffix() { ... }
    func ExampleT_M_suffix() { ... }
  • 当一个文件包含一个示例函数,同时至少一个其他函数,类型,变量或常量声明,或没有测试或基准函数时,这个测试文件作为示例存在,通常命名为 example_test.go

注:第三方辅助包 “GitHub - stretchr/testify: A toolkit with common assertions and mocks that plays nicely with the standard library

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值