这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
Go语言基础——单元测试
一、什么是单元测试
单元测试是指对软件中的最小可测单元进行检查和验证,单元就是人为规定的最小的被测功能模块。在C语言中,一个单元指的是一个函数,在C++中一个单元指的可以是函数也可以是一个类,单元具体是什么,要根据实际情况去具体定义
二、Go语言中的单元测试
go语言自带一个测试框架testing和go test命令来实现单元测试。
单元测试的优点:
- 可以确保项目中的每个函数是可以运行的,且运行结果符合预期
- 确保写出来的代码的性能是没有问题的
- 能即时发现该单元中的程序设计的逻辑错误
如何使用单元测试
1.项目中的包结构
- 确保测试的单元和测试的代码在同一包下
- 测试文件的命名必须以“_test.go”来结尾
- 源代码的包为源代码和测试代码共同在的包,二测试代码的包为main
2.测试代码的编写
- 一个测试文件中可包含多个测试函数
- 测试函数必须以Test开头,后面为测试的函数的名字
- 测试函数的形参为t *testing.T
test_test.go的代码
package main
import (
"testing"
)
func TestHelloTom(t *testing.T) {
output := HelloTom()
expectOutput := "Tom"
if output != expectOutput {
t.Errorf("Expected %s do not match actual %s", expectOutput, output)
}
//t.Logf("Expected %s match actual %s", expectOutput, output)
}
test.go中的代码
package main
func HelloTom() string {
return "Jerry"
}
3.如何跑测试代码
运行测试用例指令
go test //如果运行正确,无日志,错误时输出日志
go test -v //运行正确或错误都输出日志
如果用的goland也可以直接右键运行
上述例子的输出结果:
我们可以很清晰的看到,我们预期的结果和我们的代码跑出来的结果是不同的,也可以很好的去定位到代码。
我们将test.go中的jerrry改为Tom
此时fail变为了pass,代码是否运行成功是不是一模了然呢?
go的测试代码没有main函数也可以运行,是不是很方便呢
tesing包详解
tesing包中的结构
-
testing.T:普通测试用例
-
testing.B:基准测试,对函数运行时间进行统计,也可以称为压力测试
测试函数以Benchmark开头,后面跟上测试的函数名
100000000:迭代次数
ns/op:平均每次迭代消耗时间
B/op:平均每次迭代消耗内存
allocs/op:平均每次迭代内存分配次数
func BenchmarkHelloTom(b *testing.B) { //打开内存 b.ReportAllocs() for i := 0; i < b.N; i++ { HelloTom() } } -
testing.F:模糊测试,可以自动生成测试用例
-
testing.M:main函数测试
func TestMain(m *testing.M) { //测试之前,数据装载,配置初始化等前置工作 code := m.Run() //测试之后,释放资源等收尾工作 os.Exit(code) } -
testing.PB:可以进行并发测试
func BenchmarkHelloTom2(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { HelloTom() } }) }