• [Go] 单元测试/性能测试 (go test)


    特征

    Golang 单元测试对文件名和方法名,参数都有很严格的要求。例如:

    1、文件名必须以 _test.go 结尾

    2、方法名必须是 Test 开头

    3、方法参数必须是 t *testing.Tb *testing.B

    命令详解

    go test 是 go 语言自带的测试工具,其中包含的是两类,单元测试(即 功能测试) 和 性能测试

    通过 go help test 可以看到 go test 的使用说明:

    格式:

    go test [-c] [-i] [build flags] [packages] [flags for test binary]

    参数:

    -c : 编译 go test 成为可执行的二进制文件,但是不运行测试。

    -i : 安装测试包依赖的 package,但是不运行测试。

    关于 build flags,调用 go help build,这些是编译运行过程中需要使用到的参数,一般设置为空

    关于 packages,调用 go help packages,这些是关于包的管理,一般设置为空

    关于 flags for test binary,调用 go help testflag,这些是 go test 过程中经常使用到的参数:

    -test.v : 是否输出全部的单元测试用例(不管成功或者失败),默认没有加上,所以只输出失败的单元测试用例

    -test.run pattern : 只跑哪些单元测试用例

    -test.bench patten : 只跑那些性能测试用例

    -test.benchmem : 是否在性能测试的时候输出内存情况

    -test.benchtime t : 性能测试运行的时间,默认是1s

    -test.cpuprofile cpu.out : 是否输出cpu性能分析文件

    -test.memprofile mem.out : 是否输出内存性能分析文件

    -test.blockprofile block.out : 是否输出内部goroutine阻塞的性能分析文件

    -test.memprofilerate n : 内存性能分析的时候有一个分配了多少的时候才打点记录的问题。这个参数就是设置打点的内存分配间隔,也就是 profile 中一个 sample 代表的内存大小。默认是设置为 512 * 1024 的。如果你将它设置为 1,则每分配一个内存块就会在 profile 中有个打点,那么生成的 profile 的 sample 就会非常多。如果你设置为 0,那就是不做打点了

    你可以通过设置 memprofilerate=1 和 GOGC=off 来关闭内存回收,并且对每个内存块的分配进行观察

    -test.blockprofilerate n : 基本同上,控制的是 goroutine 阻塞时候打点的纳秒数。默认不设置就相当于 -test.blockprofilerate=1,每一纳秒都打点记录一下

    -test.parallel n : 性能测试的程序并行 cpu 数,默认等于 GOMAXPROCS

    -test.timeout t : 如果测试用例运行时间超过 t,则抛出 panic

    -test.cpu 1,2,4 : 程序运行在哪些 CPU 上面,使用二进制的 1 所在位代表,和 nginx 的 nginx_worker_cpu_affinity 是一个道理

    -test.short : 将那些运行时间较长的测试用例运行时间缩短

    示例

    单元测试(测试 某个包)

    在 golang 的 src 目录下新建目录 math,测试目录结构如下:

    ibonacci.go 代码如下,主要有一个 Fibonacci 函数

    package lib
    
    // 斐波那契数列
    // 求出第n个数的值
    func Fibonacci(n int64) int64 {
        if n < 2 {
            return n
        }
        return Fibonacci(n-1) + Fibonacci(n-2)
    }

    fibonacci_test.go 就是测试的文件了,golang 需要测试文件一律用 “_test” 结尾,测试的函数都用 Test 开头,代码如下:

    package lib
    
    import (
        "testing"
    )
    
    func TestFibonacci(t *testing.T) {
        r := Fibonacci(10)
        if r != 55 {
            t.Errorf("Fibonacci(10) failed. Got %d, expected 55.", r)
        }
    }

    使用 go test 测试这个程序

    $ go test lib
     ok lib 0.008s

    性能测试

    结合上面的方法,这里测试一下函数的性能,如果需要进行性能测试,则函数开头使用 Benchmark 就可以了。

    // 性能测试
    func BenchmarkFibonacci(b *testing.B) {
        for i := 0; i < b.N; i++ {
            Fibonacci(10)
        }
    }

    接下来执行这个性能测试:

    $ go test -bench=. lib
     PASS
     BenchmarkFibonacci 5000000 436 ns/op
     ok lib 2.608s

    其中第二行输出表示这个函数运行了 5000000 次,平均运行一次的时间是 436ns。

    这个性能测试只测试参数为 10 的情况。如果有需要可以测试多个参数:

    // 测试参数为5的性能
    func BenchmarkFibonacci5(b *testing.B) {
        for i := 0; i < b.N; i++ {
            Fibonacci(5)
        }
    }
    
    // 测试参数为20的性能
    func BenchmarkFibonacci20(b *testing.B) {
        for i := 0; i < b.N; i++ {
            Fibonacci(20)
        }
    }

    运行一下:

    $ go test -bench=. lib
     PASS
     BenchmarkFibonacci 5000000 357 ns/op
     BenchmarkFibonacci5 100000000 29.5 ns/op
     BenchmarkFibonacci20 50000 44688 ns/op
     ok lib 7.824s

    如果性能测试的方法非常多,那需要的时间就会比较久。可以通过 -bench=参数 设置需要运行的性能测试方法:

    $ go test -bench=Fibonacci20 lib
     PASS
     BenchmarkFibonacci20 50000 44367 ns/op
     ok lib 2.677s

    测试 某个文件

    一定要带上被测试的原文件,否则会提示找不到包

    go test -v  wechat_test.go wechat.go 

    测试 某个方法

    go test -v -test.run TestRefreshAccessToken

    延伸阅读:

    【Go命令教程】8. go test

  • 相关阅读:
    求单源最短路径两顶点最短距离(BFS)
    运用DFS算法解决的图的相关算法应用
    关于图的简单路径,输出、是否存在等总结
    邻接表与邻接矩阵互换
    Weblogic WLS-WebServices组件反序列化漏洞复现
    Android测试(四)——内容供应器泄露
    Android测试(三)——APK文件反编译
    漏洞复现——Apache SSI远程命令执行
    漏洞复现——Apache HTTPD多后缀解析漏洞
    漏洞复现——httpd换行解析漏洞
  • 原文地址:https://www.cnblogs.com/52php/p/6985411.html
Copyright © 2020-2023  润新知