1 测试
- 测试分为回归测试,集体测试,单元测试
1.1 单元测试
1.1.1 单元测试-规则
- 所有测试文件都要以
_test.go结尾(方便找到测试代码) - 初始化逻辑放到
TestMain中 - 测试函数的名称必须以
Test开头,并且接受一个*testing.T类型的参数。
package main
import "testing"
func TestAdd(t *testing.T) {
sum := Add(1, 2)
if sum != 3 {
t.Errorf("Add(1, 2) = %d; want 3", sum)
}
}
1.1.2 单元测试-运行
- go test [flages][packages]
1.1.3 单元测试-asseert
assert.Equal(t,res1,res2)可以快速推断两个结果是一致,如果通过,输出pass
1.1.4 单元测试-覆盖率
通过代码覆盖率可以衡量代码是否经过了足够的测试
go test --cover 可以测试代码覆盖率(单步执行的代码行数占函数体总行数的比率)
提升覆盖率:经过多次测试,修改函数输入,可以逐步增加代码覆盖率
1.1.5 单元测试-Tips
- 一般覆盖率为:50%-60%,较高可达到80%
- 测试分支相互独立、全面反复改。
- 测试单元粒度足够小,函数单一职责。
1.2 单元测试-依赖
- 单元测试的强依赖:本地文件、数据库、Cache。
- 单元测试的目标:幂等(重复运行一个测试,结果应当是一样的)和稳定(单元测试应当是相互隔离的,单元测试在任何时间、任何函数都可以独立运行)
1.3单元测试-MOck
- 链接:GitHub - bouk/monkey: Monkey patching in Go
- 作用:为一个函数打桩(用一个函数A【打桩函数】替换另一个函数B),打桩测试不再依赖本地文件保障单元测试的稳定性。
两个方法:
Patch(target,replacement interface{})和Unpatch(target interface{})
Patch方法是运行打桩的方法,Unpatch是进行打桩函数的卸载
1.4 基准测试
- 优化代码,需要对当前代码分析
- 内置的测试框架,提供了基准测试的能力
- 基准测试的基本规则:进行基准测试时,需要一个稳定的环境来获得可重现的结果。应避免在共享硬件上运行测试,并注意节电和热缩放问题。最好使用专用的性能测试硬件,并保持机器上的软件版本不变2。
- 使用测试包进行基准测试:Go的
testing包内置了支持基准测试的能力。基准测试函数通常写在以test.go结尾的文件里,与单元测试共存。这些函数以Benchmark开头,接收testing.B类型的参数。例如,为一个计算斐波那契数列的函数编写基准测试,可以按照以下格式编写测试函数:func BenchmarkFib20(b testing.B)2。 - 运行基准测试:基准测试通过
go test命令执行,但默认情况下不会执行。要显式执行基准测试,请使用-bench标志。例如,使用go test -bench.运行包中所有的基准测试23。 - 编写基准测试的常见用法:基准测试代码文件必须以
test.go结尾。测试函数以Benchmark开头,参数为testing.B。函数内不能有返回值,且应使用b.ResetTimer()来避免初始化代码的干扰。b.N是基准测试框架提供的,表示循环次数3。 - 基准测试的目的和作用:基准测试用于量化代码的性能差异,帮助识别性能瓶颈,并为优化提供数据支持。它也可以用于监测性能回归、指导优化以及比较不同技术或方案4。
- 基准测试的输出结果解释:基准测试的输出包括函数名、运行时对应的GOMAXPROCS的值、运行循环的次数以及每次操作所需的时间。例如,
BenchmarkFib10-4 3360627 362 ns/op表示BenchmarkFib10函数在GOMAXPROCS为4的情况下,执行了3360627次,每次操作平均耗时362纳秒5。
fastrand函数可以提供快速的随机数,帮助优化随机性能。