这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
一、本堂课重点内容:
- 测试
二、详细知识点介绍:
- 测试
3.2 单元测试——依赖
幂等:对相同的输入重复测试得到的输出相同。
稳定:单元测试能在任何时间、任何函数独立运行。
单元测试的单元往往会依赖于文件、数据库或缓存等,若想满足幂等与稳定,则需要用到Mock机制。
3.3 单元测试——文件处理
原函数:
func ReadFirstLine() string {
open,err:=os.Open("log")
defer open.Close()
if err != nil{
return ""
}
scanner := bufio.NewScanner(open)
for scanner.Scan(){
return scanner.Text()
}
return ""
}
func ProcessFirstLine() string{
line := ReadFirstLine()
destLine := strings.ReplaceAll(line,"11","00")
return destLine
}
测试函数:
func TestProcessFirstLine(t *testing.T){
firstLine := ProcessFirstLine()
assert.Equal(t,"line00",firstLine)
}
依赖文件:
line11
line22
line33
line44
line55
这种情况下,测试依赖于依赖文件,不满足稳定。
3.4 单元测试——Mock
用到了一个常用的开源Mock测试包:monkey
Mock可以理解为:用打桩函数A替换原函数B来方便测试。
Patch:打桩
Unpatch:卸载桩
func TestProcessFirstLineWithMock(t *testing.T){
monkey.Patch(ReadFirstLine,func() string {
return "line110"
})
defer monkey.Unpatch(ReadFirstLine)
line := ProcessFirstLine()
assert.Equal(t,"line000",line)
}
对ReadFirstLine打桩测试,不再依赖本地文件。
3.5 基准测试
基准测试的通俗理解即为性能测试。
基准测试有助于优化代码,需要对当前代码进行分析。内置的测试框架提供了基准测试的能力。
3.5.1 基准测试——例子
服务器负载均衡例子:
import{
"math/rand"
}
var ServerIndex [10]int
func InitServerIndex(){
for i:=0;i<10;i++{
ServerIndex[i] = i+100
}
}
func Select() int {
return ServerIndex[rand.Intn(10)]
}
3.5.2 基准测试——运行
测试函数:
func BenchmarkSelect(b *testing.B) {
InitServerIndex()
b.ResetTimer()
for i := 0; i < b.N; i++ {
Select()
}
}
func BenchmarkSelectParallel(b *testing.B) {
InitServerIndex()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Select()
}
})
}
基准测试以Benchmark开头,同单元测试以Test开头相同。
入参为*testing.B类型。
- BenchmarkSelect
InitServerIndex():初始化服务器列表
b.ResetTimer():重置计数器,因为InitServerIndex()不在测试目标函数的范围内。
for循环执行Select():循环进行串行压力测试。
- BenchmarkSelectParallel
并行与串行大体相同。
执行结果:
我们发现并行基准测试的情况下性能有所劣化。
主要问题是Select中的rand()函数持有一把全局锁,在一定程度上降低了并发性能。
三、引用参考: