[TOC]
Golang测试用例和基准测试注意事项
老生常谈了,这里主要记录一下,测试用例(test)和压力测试(benchmark)中的注意事项
test测试用例
- 测试用例的文件名必须以
XXX_test.go
的格式. - 文件名的
XXX
不必一定和被测试文件的名称一样,但是保持一致是一个很好的习惯. - 测试用例中的测试函数名必须是
TestXXX(t *testing.T)
如此定义,否则不执行 - 每一个
test
文件必须要import
一个testing
包 go test
或者go test -v
命令测试当前包目录下的所有的tests- 用
t.Errorf
来打印错误信息,会输出错误信息,并且跳过当前测试函数 t.SkipNow()
跳过当前测试并且直接按PASS处理继续下一个test- go的test不会保证多个
TestXXX()
是顺序执行的,但是通常会顺序执行 - 要保持顺序执行需要使用subTest,即在test内使用
t.Run()
来顺序调用要测试的test函数,一般被调用的test,会把函数名定位testXXX
,这样的话就不会自动运行testXXX
,而是被t.Run()
来调用 - 使用
TestMain(m *tesging.M)
作为初始话test,并且使用m.Run()
来调用其他test可以完成一些初始话操作的testing,该函数必须调用m.Run()
- 如果没有在TestMain中调用
m.Run()
则除了testMain
之外的所有其他test都不会执行
package main
import(
"testing"
"fmt"
)
//因为是小写开头所以不会运行
func testPrint(t *testing.T){
//该方法可以跳过当前函数的测试,并通过测试
t.SkipNow()
res := MyFunc()
if res {
t.Errorf("wrong")
}
}
//因为是小写开头所以不会运行
func testprint1(t *testing.T){
res := MyFunc()
if !res {
t.Errorf("wrong 1")
}
}
func TestAll(t *testing.T){
//使用t.Run()调用函数来做顺序执行
t.Run("TestPrint", testPrint)
t.Run("TestPrint1", testPrint1)
}
//初始化函数,首先运行该函数
func TestMain(m *testing.M){
fmt.Println("this is Main func")
//必须要调用该函数,否则除了TestMain()其他函数都不会执行
m.Run()
}
benchMark基准测试
- benchmark函数需要Benchmaik开头
- benchmark的case标准一般会跑b.N次,而且每次执行都是如此
- 在执行中会根据实际的case执行时间是否是稳定的,会一直增加b.N的次数以达到执行时间是一种稳定的状态.比如说第一次我们执行10nm,第二次100nm,第三次300nm,那他就不会停止,会一直增加.等到平均每次执行的时间趋近于稳定他才会停
- 在我们的函数测试时,千万注意被测试函数总能在一定时间内达到一种稳态,否则会永远执行不完
func noSteady(n int) int{
for n >0 {
n --
}
return n
}
func steady(n int){
return
}
func BenchmarkAll(b *testing.B){
for n:=0;n<b.N;n++{
//会永远跑不完,因为我们每次穿进去的n是不一样的,
//而且该函数是线性增长的,比如2就执行2次,3就执行3次,等于N的时候就执行N次
//那么这时候b.N就会不断的调大以适应里面n的变化
//最终永远也跑不完
noSteady(n)
//肯定可以跑完
steady(n)
}
}