单元测试
针对使用传统方式测试代码块的不足:
1)测试代码块需要在main函数中去调用,需要修改main函数,若项目正在运行,就可能去停止项目,不方便
2)不利于管理,当需要测试多个函数或多个模块时,都需要在main函数,不利于我们管理和清晰思路
3)引出单元测试。testing测试框架,很好解决上述问题。
单元测试基本原理
Go语言中的测试依赖go test命令。编写测试代码和编写普通的Go代码过程是类似的,并不需要学习新的语法、规则或工具。
go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以_test.go为后缀名的源代码文件都是go test测试的一部分,不会被go build编译到最终的可执行文件中。
在_test.go文件中有三种类型的函数,单元测试函数、基准测试函数和示例函数。
1、测试函数Test
a、在cal目录下有被测试文件cal.go
b、同样在cal目录下写测试函数,文件名为cal_test.go
c、运行测试指令
go test (如果运行正确,无日志,错误时输出日志)
go test -v (运行正确或错误都输出日志)
go test -v cal_test.go cal.go 测试单个文件
go test -v -run TestAddupper 测试单个方法
2、基准函数(测试函数的性能)----benchmark性能测试
benchmark函数以Benchmark开头而非 Test开头.
通过为go test命令添加-bench标记的方式运行benchmark测试,参数的值是一个正则表达式,如果运行全部benchmark测试,则指定为-bench=.即可;
为了避免普通的测试case被执行,可以加上-run=^$(匹配空函数)来跳过执行;
如果希望同步观察内存使用,可以通过-benchmem标记位来实现;
为了确保结果的一致性,可以加上-count参数来重复运行benchmark;
每个benchmark默认情况下会运行至少一分钟,我们可以通过 -benchtime标记位来生成一个更准确的结果;
b.N 的值会以1, 2, 5, 10, 20, 50, …这样的规律递增下去直到运行时间超过或等于1秒钟(可以通过上面的 -benchtime修改),这里不是时间一到就截止,运行期还会综合运行时间的稳定性来判断是否继续;
接上一条,由于程序判断运行时间稳定才会停止运行,所以千万不要在loop循环里面使用一个变化的值作为函数的参数,这里要注意b.N是也是一个动态变化的值!
package cal
import (
"testing"
)
func BenchmarkAllocOne(b *testing.B) {
for n := 0; n < b.N; n++ {
one()
}
}
func BenchmarkAllocBatch(b *testing.B) {
for i := 0; i < b.N; i++ {
batch()
}
}
func one() {
sum := 0
for i := 1; i < 10000; i++ {
sum = sum + i
}
}
func batch() {
sum := 0
for i := 1; i < 10000; i++ {
sum = sum + i
}
}
go test -run=^$ -bench=^BenchmarkAlloc* -benchmem
第一列是执行的函数名称,第二列是总的执行次数,第三列是平均运行时间;