Golang 单元测试和基准测试实例详解

 更新时间:2022年08月24日 11:01:56   作者:六号积极分子  
这篇文章主要为大家介绍了Golang 单元测试和基准测试实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

多人协作的项目里,要保证代码的质量,自然离不开单元测试。开发完一个功能后肯定要对所写的代码进行测试,测试没有问题之后再合并到代码库供他人使用。如果强行合并到代码库可能会影响其他人开发,被上线的话肯定也会导致线上 Bug ,影响用户使用。

所以,单元测试也是一个很重要的事情。单元测试是指在开发中,对一个函数或模块的测试。其强调的是对单元进行测试。

Go 单元测试

Go 语言提供了单元测试的框架,只要遵循其规则即可:

测试文件命名:

  • 单元测试的代码文件都必须以 _test.go 结尾,这样才能被 Go 语言测试工具识别
  • 单元测试的文件命名都与被测试函数所在的 go 文件的文件名一样,然后再加 _test.go。比如 main.go 的测试文件 main_test.go

测试函数命名:

  • 单元测试的函数名必须以 Test 开头,再加上要测试函数名,且必须是公有的。比如main.go中有函数 func add(){},   其函数名应为 TestAdd
  • 测试函数的签名必须接收一个指向 testing.T 类型的指针,并且不能返回任何值
# main.go
func Add(){
    // to do something
}
# main_test.go
func TestAdd(t *testing.T) {
    result := Add()
    if result == 3 {
        println("success")
    } else {
        println("error")
    }
}

根据以上规则,就可以进行对某测试文件执行命令,进行单元测试:

go test -v ./main_test.go

如果显示的测试结果有 PASS 标记,说明单元测试通过。

单元测试覆盖率

函数是否被全面测试,还需要覆盖率进行检测。单元测试命令增加 --coverprofile 标记,就可以得到一个单元测试覆盖文件,且会在控制台打印出代码覆盖率是多少。

go test -v --coverprofile=main.cover ./main_test.go

Go 框架还可以生成 html 文件的覆盖率报告,这样就可以对单元测试覆盖率的结果更清晰,更明白。

go tool cover -html=main.cover -o=main.html

打开 html 文件就可以看到红色标记是没有被覆盖到,绿色是被测试到的。

以上是简单的功能的单元测试,验证功能逻辑的正确。但有时候还有性能的要求,这时就可以使用基准测试来评估代码的性能。

基准测试

基准测试是一项用于测试和评估软件性能指标的方法,主要测试代码的性能。基准测试的规则和单元测试的规则是不一样的:

  • 基准测试函数必须以 Benchmark 开头,且必须是可导出的
  • 函数的签名必须接收一个指向 testing.B 类型的指针,并且不能返回任何值;
  • 最后的 for 循环很重要,被测试的代码要放到循环里;
  • b.N 是基准测试框架提供的,表示循环的次数,因为需要反复调用测试的代码,才可以评估性能。

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add()
    }
}

写完基准测试,就可以执行命令进行测试:

go test -bench=. ./

使用 go test 命令,再加上 -bench 这个 Flag,它接受一个表达式作为参数,以匹配基准测试的函数,"."表示运行所有基准测试。

BenchmarkAdd-10, 其中的 -10 是运行基准测试时对应的 GOMAXPROCS 的值。基准测试的时间默认是 1 秒,也就是 1 秒调用 1000000000 次、每次调用花费 311 纳秒。如果想让测试运行的时间更长,可以通过 -benchtime 指定,比如 3 秒。

go test -bench=. -benchtime=3s ./
  • 重置计时方法

进行基准测试之前,需要进行一些数据准备,如构建测试数据,而这部分准备工作不属于性能测试计算范围内所以需要排除在外。通过使用充值计数器 ResetTimer重新计算。也支持使用 StartTimer 和 StopTimer 方法,控制何时开始计时何时结束。

  • 内存统计

内存统计主要是统计每次操作分配内存的次数和分配的字节数。使用 ReportAllocs() 方法

func BenchmarkAdd(b *testing.B) {
    b.ResetTimer() // 重置计时时间
    b.ReportAllocs() // 内存统计
    for i := 0; i < b.N; i++ {
        Add()
    }
}

对以上命令执行后可在控制台上得到结果。多了两个指标。

  • 第一个表示:每次操作分配多少字节内存
  • 第二个表示:每次操作分配内存的次数

两个指标没有统一标准区说明越小越好还是越大越好,主要还是需要根据业务场景来判断的。

  • 并发基准测试

在并发的情况下,Go 也支持基准测试。Go 语言通过 RunParallel 方法运行并发基准测试。创建多个 goroutine 然后将 b.N 分配给这些 goroutine 执行。

func BenchmarkAdd(b *testing.B) {
    b.RunParallel(func(pb *testing.PB) {
        for pb.Next() {
            Add()
        }
    })
}

单元测试可以保证代码质量,但其也不是万能的,还需要 code Review 和人工测试才能更好的保证代码的质量。

参考资料:https://www.jb51.net/article/260482.htm

以上就是Golang 单元测试和基准测试实例详解的详细内容,更多关于Golang 单元测试基准测试的资料请关注脚本之家其它相关文章!

相关文章

  • Golang Map value不可寻址使用指针类型代替示例详解

    Golang Map value不可寻址使用指针类型代替示例详解

    这篇文章主要为大家介绍了Golang Map value不可寻址使用指针类型代替示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Go easyjson使用及反射原理

    Go easyjson使用及反射原理

    这篇文章主要介绍了Go easyjson使用技巧,详细介绍了go自带JSON库使用的反射原理,性能相对较差,可以使用easyjson代替,需要的朋友可以参考下
    2022-04-04
  • 简单高效!Go语言封装二级认证功能实现

    简单高效!Go语言封装二级认证功能实现

    本文将介绍如何使用Go语言封装二级认证功能,实现简单高效的用户认证流程,二级认证是一种安全措施,要求用户在登录后进行额外的身份验证,以提高账户安全性,
    2023-10-10
  • Go语言实现单端口转发到多个端口

    Go语言实现单端口转发到多个端口

    这篇文章主要为大家详细介绍了Go语言实现单端口转发到多个端口,文中的示例代码讲解详细,具有一定的参考价值,对大家的学习或工作有一定的帮助,需要的小伙伴可以了解下
    2024-02-02
  • 深入理解Golang channel的应用

    深入理解Golang channel的应用

    channel是用于 goroutine 之间的同步、通信的数据结构。它为程序员提供了更高一层次的抽象,封装了更多的功能,这样并发编程变得更加容易和安全。本文通过示例为大家详细介绍了channel的应用,需要的可以参考一下
    2022-10-10
  • 详解go基于viper实现配置文件热更新及其源码分析

    详解go基于viper实现配置文件热更新及其源码分析

    这篇文章主要介绍了详解go基于viper实现配置文件热更新及其源码分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Go语言基础入门应用简介及常用命令

    Go语言基础入门应用简介及常用命令

    这篇文章主要为大家介绍了Go语言基础入门应用简介及常用命令,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-11-11
  • GoPath模式和GoMoudle模式的相爱相杀

    GoPath模式和GoMoudle模式的相爱相杀

    这篇文章主要介绍了GoPath模式和GoMoudle模式的相爱相杀,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Kubernetes上使用Jaeger分布式追踪基础设施详解

    Kubernetes上使用Jaeger分布式追踪基础设施详解

    这篇文章主要为大家介绍了Kubernetes上使用Jaeger分布式追踪基础设施详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 详解如何使用Golang扩展Envoy

    详解如何使用Golang扩展Envoy

    这篇文章主要为大家介绍了详解如何使用Golang扩展Envoy实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06

最新评论