GO语言工程实践之测试(二)|青训营笔记

69 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

一、本堂课重点内容:

  • 测试

二、详细知识点介绍:

  • 测试

3.2 单元测试——依赖

image.png

幂等:对相同的输入重复测试得到的输出相同。

稳定:单元测试能在任何时间、任何函数独立运行。

单元测试的单元往往会依赖于文件、数据库或缓存等,若想满足幂等与稳定,则需要用到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来方便测试。

image.png

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

并行与串行大体相同。

执行结果:

image.png

我们发现并行基准测试的情况下性能有所劣化。

主要问题是Select中的rand()函数持有一把全局锁,在一定程度上降低了并发性能。

三、引用参考: