0


golang单元测试框架实践

一、简介

单元测试主要是通过模拟业务中的参数,调用我们的函数,然后获取执行结果,再判断结果是否符合规则;同时还可以对某一个方法进行性能分析

在Go 标准库中有一个叫做

testing

的测试框架, 可以用于单元测试和性能测试. 它是和命令

go test

集成使用的,测试文件是以后缀

_test.go

命名的, 通常和被测试的文件放在同一个包中.

规则:

  • 单元测试代码的go文件必须以_test.go结尾,Go语言测试工具只认符合这个规则的文件
  • 单元测试的函数名必须以Test开头,是可导出公开的函数。备注:函数名最好是Test+要测试的方法函数名
  • 测试函数的签名必须接收一个指向testing.T类型的指针作为参数,并且该测试函数不能返回任何值

math_func.go:

package mathfunc

func Add(num1 int, num2 int) int {
    return num1 + num2
}

add_test.go:

package mathfunc

import (
    "testing"
)

func TestAdd(t *testing.T) {
    tests := []struct{ a, b, c int }{
        {1, 2, 3},
        {4, 5, 9},
        {5, 5, 10},
        {40000, 50000, 90000},
    }

    for _, test := range tests {
        if actual := Add(test.a, test.b); actual != test.c {
            t.Errorf("Add(%d,%d) actual is %d , expected is %d", test.a, test.b, actual, test.c)
        }
    }
}

search.go:

package searchutil

func SearchNoRepeatStrMaxLength(str string) int {
    runeStrArray := []rune(str)
    var strRune = make([]rune, 0)
    var ensureStrRune []rune = nil
    var length = -1
    for _, r := range runeStrArray {
        if len(strRune) != 0 {
            if strRune[len(strRune)-1] != r {
                strRune = append(strRune, r)
            } else {
                if len(strRune) > length {
                    length = len(strRune)
                    ensureStrRune = make([]rune, 0)
                    ensureStrRune = append(ensureStrRune, strRune...)
                }
                strRune = strRune[0:0]
                continue
            }
        } else {
            strRune = append(strRune, r)
        }
    }

    if len(strRune) > length {
        length = len(strRune)
        ensureStrRune = strRune
    }

    return len(ensureStrRune)
}

benchmark_test.go:

package searchutil

import (
    "fmt"
    "testing"
)

func BenchmarkAdd(b *testing.B) {
    var str = "hellottthelloyyytuiopioyytestt"
    for i := 0; i < 13; i++ {
        str += str
    }

    fmt.Println(len(str))

    var res = 9

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        if actual := SearchNoRepeatStrMaxLength(str); actual != res {
            b.Errorf("SearchNoRepeatStrMaxLength(%s) : actual => %d ; expected: %d", str, actual, res)
        }
    }
}

二、单元测试使用

2.1 普通测试

普通测试主要是验证返回的结果是否符合预期,执行的命令如下所示

go test -v add_test.go math_func.go

命令执行后,返回的结果如下所示

从上图中可以看到,单元测试提示测试通过,说明我们程序符合预期

2.2 性能测试

性能测试主要是通过多次调用程序,总耗时来分析程序的性能,类似于AB压力测试,执行命令如下所示

go test -v --bench="BenchmarkAdd$" --run=none benchmark_test.go search.go 

命令中的

-bench="BenchmarkAdd$"

参数代表要执行哪一个方法,执行结果如下所示

2.3 测试覆盖率

go test -coverprofile c.out

go tool cover -html=c.out

生成的代码覆盖率页面:

2.4 性能分析

性能分析主要是查看方法中具体的瓶颈,比如A方法调用了C、B、D多个方法,具体耗时在什么位置,我们可以在上一条性能测试的命令中加入

-cpuprofile cpu.out

参数(文章附录有多种分析指标类型)加入到性能测试中的具体信息保存

go test -v --bench="BenchmarkAdd$" --run=none -cpuprofile cpu.out benchmark_test.go search.go

通过go 自带工具分析保存的文件

go tool pprof cpu.out

提示需要安装Graphviz,下载链接如下:

Download | GraphvizSource CodeSource code packages for the latest stable anddevelopment versions of Graphviz are available, along with instructions for anonymous …http://www.graphviz.org/download/ 安装完成后,再次运行:

go tool pprof cpu.out

交互式输入web,即可打开性能分析图:


本文转载自: https://blog.csdn.net/wtl1992/article/details/124773222
版权归原作者 AI机械师 所有, 如有侵权,请联系我们删除。

“golang单元测试框架实践”的评论:

还没有评论