其实以前对于测试本身一直比较弱,不论是python的仍是go的,关于测试这块并无很是注重,此次就好好整理一下关于go的测试python
Go程序主要包含三类测试: 功能测试(test)、基准测试(benchmark,也称性能测试)以及示例测试并发
这里提一下,示例测试其实也是一种功能测试,只不过它更关注程序打印出来的内容app
通常状况下:一个测试赛源码文件只会针对某个命令源码文件, 或库源码文件作测试,因此咱们应该把它们放在同一个代码包内函数
测试源码文件的主名称应该以被测试源码文件的主名称为前导, 而且必须以“_test”为后缀,如被测试的源码文件名是demo.go 那么测试源码文件名是demo_test.go性能
Go 语言对测试函数的名称和签名都有哪些规定?单元测试
关于go test 命令的主要流程是:测试
go test 命令在开始运行时会先作一些准备工做,好比,肯定内部须要用到的命令,检查咱们指定的代码包或源码文件的有效性,以及判断咱们基于的标记是否合法等等spa
在准备工做完成后,go test 命令会针对每一个测试代码包依次进行构建,执行包中符合要求的测试函数,清理临时文件,打印测试结果。日志
这里的依次:表示对每一个测试代码包,go test 命令会串行的执行测试流程中的每一个步骤。可是为了加快测试速度,它一般会并发地对多个被测试代码包进行功能测试。只不过最后打印测试结果的时候code
会按照咱们给定的顺序逐个进行,让咱们感受是在串行的执行测试
因为并发测试会让性能测试的结果存在误差,因此性能测试通常都是串行进行的
go test -v 能够看到测试中更详细的日志信息
若是想要某个测试在执行的过程当中当即失败,能够在该函数中调用:t.FailNow方法
怎么解释性能测试的测试结果?
这个仍是很是重要的,以前并无去细致的了解
这里有一段代码,并为之写了一个性能测试代码内容以下:
package demo54 import "math" func GetPrimes(max int) []int { if max <= 1 { return []int{} } marks := make([]bool, max) var count int squareRoot := int(math.Sqrt(float64(max))) for i := 2; i <= squareRoot; i++ { if marks[i] == false { for j := i * i; j < max; j += i { if marks[j] == false { marks[j] = true count++ } } } } primes := make([]int, 0, max-count) for i := 2; i < max; i++ { if marks[i] == false { primes = append(primes, i) } } return primes }
性能测试的代码为:
package demo54 import "testing" func BenchmarkGetPrimes(b *testing.B) { for i:=0;i<b.N;i ++ { GetPrimes(1000) } }
下面是测试命令和结果
zhaofan@zhaofandeMacBook-Pro ~/go_project go test -bench=. -run=^$ 36/demo54 goos: darwin goarch: amd64 pkg: 36/demo54 BenchmarkGetPrimes-4 500000 2728 ns/op PASS ok 36/demo54 1.407s
这里对这个命令进行解释:
第一个标记-bench=. 只有有了这个标记命令才会进行性能测试,该标记. 代表须要执行任意名称的性能测试函数,固然这里仍是要符合Go程序测试的基本规则的
第二个标记及值是-run=^$ 这个标记用于代表须要执行哪些功能测试函数,这一样是以函数名称为依据的 该标记的值^$ 意味着只执行名称为空的功能测试函数,其实就是不执行任何功能测试函数
结果中:BenchmarkGetPrimes-4 被称为单个性能测试的名称,表示命令执行了性能测试函数BenchmarkGetPrimes 而且当时全部最大的P 数量为4 最大P 数量至关于能够同时运行goroutine的逻辑CPU的最大个数。这里的CPU能够被称为CPU核心,但他并等同于计算机中真正的CPU核心
go test -cpu 能够设置最大P数量的列表
关于测试代码的解释:
func BenchmarkGetPrimes(b *testing.B) { for i:=0;i<b.N;i ++ { GetPrimes(1000) } }
这里在一个会循环迭代b.N次方的循环中调用了GetPrimes函数,并传递的参数为1000, go test 命令会先尝试把b.N 设置为1,
而后执行测试函数
若是测试的函数执行时间没有超过上限, 此伤心啊默认为1秒,那么命令就会改大b.N的值,而后再次执行测试函数,如此往复,知道这个时间大于或等于上限为止。
当某次执行的时间大于或等于上限时, 咱们就说这事命令这次对该测试函数的最后一次执行,这时b.N的值就会包含在测试结果中,也就是上述测试结果中的500000
结果中:2728 ns/op 代表单次执行GetPrimes函数的平均耗时为2728纳秒。 这其实就是最后一次执行测试函数的时间,除以被测函数的执行测试得出的结果