单元测试
在学习单元测试之前,测试代码一般都是些在main函数里去调用我们写的函数,以此来判断函数的正确性。学习单元测试后,我们可以直接在测试函数里去测试,提提高代码的可读性和测试效率。
go测试
golang中提供了非常完善的测试功能。所有测试代码文件以*_test.go
命名,测试函数以Test被测函数名(TestAdd)
命名,测试命令以go test
开头。
golang中有3中测试函数,分别为单元测试函数、性能测试函数、示例函数。
类型 | 格式 | 作用 |
---|---|---|
单元测试函数 | 函数名以Test 为前缀 |
测试代码逻辑是否正确 |
性能测试函数(基准函数) | 函数名以Benchmark 为前缀 |
测试函数的性能 |
示例函数 | 函数名前缀为Example | 为文档提供示例文档 |
单元测试函数
每个测试函数必须导入test
包,函数名以Test
为前缀,*testing.T
用于报告测试失败和附加的日志信息。单元测试函数格式如下
func TestAdd(t *testing.T) {
// todo
}
简单测试函数示例
定义一个test
包,并编写函数Add
package test
func Add(m int, n int) (sum int) {
sum = m + n
return
}
接下来,在当前目录下创建add_test.go
文件,并定义测试函数:
//测试函数名必须以Test开头,必须接收一个*testing.T类型参数
func TestAdd(t *testing.T) {
/**
* 简单测试
*/
got := Add(3, 5) // 程序计算得出的结果
want := 8 // 期望结果
if got != want { // 程序计算出的结果与期望结果比较
t.Errorf("excepted:%v, got:%v", want, got)
}
}
在test包目录下执行go test
命令,得到结果:
-
程序得到结果与预期结果相同:
image.png -
程序得到结果与预期结果不同:
image.png
子测试函数示例
在简单测试函数示例中,我们一次只能测试一组数据,如果有多组测试数据的话要么在创建一个函数来测试,要么使用循环。使用循环测试的情况下,我们无法得出哪条测试数据有问题。golang中提供子测试方法,我们可以通过*testing.T.Run
方法来执行子测试。
func TestAdd(t *testing.T) {
// 测试数据,期望结果结构体
type data struct {
m int
n int
want int
}
// 测试组需要使用map类型,后续查看测试结果比较方便
tests := map[string]data{
"one": {m: 1, n: 2, want: 3},
"two": {m: 10, n: 5, want: 15},
"three": {m: 25, n: 16, want: 41},
"four": {m: 10, n: 6, want: 16},
"five": {m: 0, n: 0, want: 1},
}
for name, d := range tests{
// t.Run函数,需要传入测试数据的name,即上面map中的one\two\three
t.Run(name, func(t *testing.T) {
got := Add(d.m, d.n)
if got != d.want {
t.Errorf("name:%s excepted:%#v, got:%#v", name, d.want, got) // 将测试用例的name格式化输出
}
})
}
}
执行go test -v
查看测试结果的详细信息
性能测试函数
性能测试函数也叫基准测试函数,函数名以Benchmark
为前缀。性能测试函数格式如下:
性能测试函数需要执行b.N
次,这个由系统决定的。
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
// todo
}
}
性能测试示例:
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(999999, 99999)
}
}
执行基准函数:go test -bench=函数名 -benchmem(go test -bench=Add -benchmem)
- 基准函数默认是不会执行的,需要参数
-bench
- -benchmen会显示一些内存分配的统计数据
image.png
统计数据的意义: - BenchmarkAdd-8:表示GOMAXPROCS(线程数)的值为8
- 2000000000:表示执行的次数
- 0.26 ns/op:表示每次执行时间0.26ns
- 0B/op:表示每次执行分配内存0B
- 0 allocs/op:表示每次执行分配内存的次数
覆盖率测试
覆盖率测试表示代码被测试套件覆盖的百分比。
执行命令:go test -cover
可以看到,当前代码的覆盖率是50%
-coverprofile
参数可以将覆盖率的相关信息输出到一个文件中将函数覆盖率相关信息输出到
a.out
,a.out在当前目录下生成。image.png
执行命令:
go tool cover -html=a.out
,可以在浏览器上看到覆盖率相关信息image.png
测试命令总结
- 测试包下所有测试文件:
go test
- 打印测试详细信息:
go test -v
- 测试单个方法:
go test -v -run=方法名
// go test -v -run=Add - 覆盖率测试:
go test -cover
- 覆盖率测试,并输出到文件中:
go test -cover -coverprofile=c.out
- 浏览器查看覆盖率文件:
go tool cover -html=c.out
- 性能测试:
go test -bench=方法名
- 性能测试显示详细信息:
go test -bench=方法名 -benchmem
- 只执行性能测试不执行单元测试 :
go test -v -run=none -bench=方法名
网友评论