Test 的写法
- go的test一般以xxx_test.go为文件名。xxx的部分一般为xxx_test.go所要测试的代码文件名。go并没有特别要求xxx的部分必须是要测试的文件名。
- 每个test文件必须import一个
testing
因为testing里面包含了很多与test相关的东西,*testing.T - test文件下的每一个test case 均必须以Test(T大写)开头并且符合
TestXxx
形式,Xxx
的开头字母一定要大写,并仅接受一个类型为*testing.T
的参数,否则go test会直接跳过测试不执行
一般在写test case时,会以小写的 testXxxx 来作为 一个真正被识别的TestXxxx的case的中间过程。如
func Test(t *testing.T){ testPrint() fmt.print("this is the identified test case") }
- test case的入参为
t *testing.T
或b *testing.B
,普通的test case就传*testing.T
,有关benchmark之类的性能测试就传b *testing.B
,不传会报错 (这点我稍作保留,感觉不能这么简单地分) - t.Errorf()为错误信息,并且当前test case会被跳过。go语言中并没有用其他语言的 assert 的方式来进行打印断言,也不能说好坏,只是实现方式的一种。
t.SkipNow()
为跳过当前test,并且直接按PASS处理继续下一个test。注意:t.SkipNow()
必须写在test case的第一行,否则不生效:
func TestPrint(t *testing T){
t.SkipNow()
if 1 != 2 {
t.Errorf("assume it is wrong")
}
}
- go的test不会保证多个TestXxx是顺序执行,但是通常会顺序执行。使用
t.Run()
来执行subtests可以做到控制test输出以及控制test的顺序 【这里关于上一个test的输出作为下一个test的输入要明天探究一下,是否可以用子测试来完成】
经过测试,TestXxx的测试函数就只接受一个
t *testing.T
或者t *testing.B
的类型的参数,多写一个形参它会报错(goland 提示 wrong test signature);另外t.Run()就只接受类型为 func(t *T)的参数,而且返回值为bool,所以我没有找到方法做到”上一个test的输出作为下一个test的输入“,目前网上的用例以及自己的试验结果都只能证明子测试可以用来控制子test的执行顺序,但是没办法做到”上一个test的输出作为下一个test的输入“。另外如果想往TestXxx函数里面传其他函数的话,可以通过命令行来传,用flag包(go test -args c=2 好像也可以),但是应该在最开始执行时传一次吧。也可以考虑用表格驱动测试的方式曲线解决~
func TestFoo(t *testing.T) { // <setup code>
t.Run("A=1", func(t *testing.T) { ... }) //
t.Run("A=2", func(t *testing.T) { ... })
t.Run("B=1", func(t *testing.T) { ... })
// <tear-down code>}
- 使用
TestMain
作为初始化test,并且使用m.Run()来调用其他tests可以完成一些需要初始化操作的testing,比如数据库连接,文件打开,REST服务登录等 ,注意:如果没有在TestMain中调用m.Run(),则除了TestMain
以外的其他tests都不会被执行,也就是说,如果没用TestMain
,则其他test case是指可以正常执行的,如果用了TestMain
,则一定要在方法里面调用m.Run()
func TestMain(m *testing.M){
// code
m.Run()
}
// TODO:
还有一些 测试覆盖率(go test -cover)、并发测试(t.Parallel())等,遇到了再来深入点补充~