在做项目开发中,要测试某个函数或者方法是否正确的时候或者一个生产环境增加新功能,检测功能正确与稳定性,我们就需要使用到GO语言自带的testing测试框架完成。
GO语言通过自带的轻量级测试框架和自带的go test命令实现单元测试和性能测试,testing框架和其它语言中的类似,可以基于这个框架写针对相应的函数的测试用例,也可以基于框架写的相应压力测试用例,我们可以通过单元测试出函数可正常运行,输出结果准备,也可以确保代码的性能稳定,单元测试能及时发现程序设计或者实现的逻辑错误,使问题及早暴露,便于问题定位与解决,而性能测试的重点在于发现程序设计上的一些问题,让程序能够在高并发的情况下还能保持稳定运行。
1、假设我们要对main.go文件里的funcName(n int)测试,函数代码如下:
package comm
func funcName(n int) int {
return n + 1 //返回一个N+1的整数
}
2、我们现在要测试这个函数是否运行正确,我们需要在main.go的同级目录下新建一个文件为main_test.go(main为前缀是通用惯例,当然你用其它名字也可以,但必须以_test.go结尾),文件名前半部分可随意取。而且需要引用待测试函数的包,参数必须为 (test *testing.T)。:
package comm//如果不是同一个包就需要引包
import "testing"//引入testing测试框架
//TestFuncName命名规范为以Test开始,后面跟上要测试的函数名,并且第一个字母必须大写(我故意把测试函数小写来区别)
func TestFuncName(t *testing.T) {
res := funcName(10)//这里首字母小写原因要与main.go里的一样
if res != 11 {
t.Fatalf("funcName(n)运算出错,我们希望传入n后,返回n+1,预期结果应该是%v实际结果是%v", 11, res)
}
//t.Fatalf会停止运行并返回错误信息
t.Logf("funcName(n)运行正常")//格式化输出自己定义的日志
}
在main.go的目录命令行里输入:go test -v,如果只输入go test运行正确无日志,只有错误才输出日志,而go test -v不管对错都输出日志。
结果为:
=== RUN TestFuncName
prog.go:17: funcName(n)运行正常
--- PASS: TestFuncName (0.00s)
PASS
假设我们函数写错了,将输出:
=== RUN TestFuncName prog.go:14: funcName(n)运算出错,我们希望传入n后,返回n+1,预期结果应该是11实际结果是11 --- FAIL: TestFuncName (0.00s) FAIL 1 test failed.
上面测试引用的T是一个结构体,我们调用的是Fatalf方法,调用这个方法相当于在调用Logf后调用FailNow。翻译成人话就是先输出日志,再返回错误并结束程序~
t.Logf输出是自己定义的日志信息。testing框架不需要放到main函数体里去执行。可以同时测试多个函数。
如果我们要测试单个文件必须带上被测试文件的名字:
go test -v main_test.go main.go
我们还可以测试单个函数:
go test -v -test.run TestFuncName
Go的自动化测试框架要点如下:
- 测试代码以xxx_test.go方式命名
- 测试代码中import “testing”
- 测试函数形如 func TestFuncName(t *Testing.T) {…}
- 执行测试:go test 或者 go test -v
//TestMain 会在测试程序运行之前执行一些操作
func TestMain(m *testing.M) {
fmt.Println("单元测试要开始了~")
m.Run() //使用了TestMain,下面的TestFuncName就不会自动运行~所以我们要m.Run() 让程序继续向下走
}
//TestFuncName 将会自动运行,因为Test的T大写
func TestFuncName(t *testing.T) {
/*
运行第二个参数f作为名为名字(testSub)的t的子测试。
它在单独的goroutine中运行f并阻塞,直到f返回或调用t.Parallel成为并行测试。
Run报告子测试f是否成功(或者至少在调用t.Parallel之前没有失败)。
*/
t.Run("测试调用子函数:", testSub)
t.Run("第二个:", myfun)
}
func testSub(t *testing.T) {
fmt.Println("这是子测试,需要在TestFuncName使用 t.Run 调用")
}
func myfun(t *testing.T) {
fmt.Println("这是自定义名字~")
}
Run可以同时从多个goroutine调用,但是所有这样的调用必须在t的外部测试函数返回之前返回。
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/83
《GO语言上手实践2:使用testing测试框架进行单元测试》的网友评论(0)