zoukankan      html  css  js  c++  java
  • 5.8 Go 单元测试

    5.8 Go 单元测试

    如果你不想后半生的美好时光都在寻找BUG中度过,那么必须写些程序用来检测产品代码的结果和预期的一样。

    Go语言的测试依赖于go test测试命令和一组按约定方式编写的测试函数,测试命令可以运行这些测试函数。

    Go单元测试对文件名和方法名有严格的要求。

    1、文件名必须以xx_test.go命名
    2、方法必须是Test[^a-z]开头
    3、方法参数必须 t *testing.T
    4、使用go test执行单元测试
    

    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 : 将那些运行时间较长的测试用例运行时间缩短
    

    目录结构

    test
          |
           —— calc.go
          |
           —— calc_test.go
    

    calc.go

    package main
    
    func add(a, b int) int {
        return a + b
    }
    
    func sub(a, b int) int {
        return a - b
    }
    

    calc_test.go

    package main
    
    import (
        "testing"
    )
    
    func TestAdd(t *testing.T) {
        r := add(2, 4)
        if r != 6 {
            t.Fatalf("add(2, 4) error, expect:%d, actual:%d", 6, r)
        }
        t.Logf("test add succ")
    }
    

    输出结果:

    cd test/
    ls
    calc.go        calc_test.go
    
    //-v参数显示通过函数的信息
    yugoMBP:test yuchao$ go test -v
    === RUN   TestAdd
    --- PASS: TestAdd (0.00s)
            calc_test.go:11: test add succ...is ok
    PASS
    ok      gostudy/gobook/test     0.006s
    

    单元测试文件代码规则:

    1.文件名必须是_test.go结尾的,这样在执行go test的时候才会执行到相应的代码
    2.你必须import testing这个包
    3.所有的测试用例函数必须是Test开头
    4.测试用例会按照源代码中写的顺序依次执行
    5.测试函数TestXxx()的参数是testing.T,我们可以使用该类型来记录错误或者是测试状态
    6.测试格式:func TestXxx (t *testing.T),Xxx部分可以为任意的字母数字的组合,但是首字母不能是小写字母[a-z],例如Testintdiv是错误的函数名。
    7.函数中通过调用testing.T的Error, Errorf, FailNow, Fatal, FatalIf方法,说明测试不通过,调用Log方法用来记录测试的信息。
    

    1.1. go 代码覆盖率

    获取测试结果文件 c.out

    go test -coverprofile=c.out
    

    使用go tool cover读取测试覆盖文件

    Usage of 'go tool cover':
    Given a coverage profile produced by 'go test':
            go test -coverprofile=c.out
    
    Open a web browser displaying annotated source code:
            go tool cover -html=c.out
    
    Write out an HTML file instead of launching a web browser:
            go tool cover -html=c.out -o coverage.html
    
    Display coverage percentages to stdout for each function:
            go tool cover -func=c.out
    
    Finally, to generate modified source code with coverage annotations
    (what go test -cover does):
            go tool cover -mode=set -var=CoverageVariableName program.go
    
    Flags:
      -V    print version and exit
      -func string
            output coverage profile information for each function
      -html string
            generate HTML representation of coverage profile
      -mode string
            coverage mode: set, count, atomic
      -o string
            file for output; default: stdout
      -var string
            name of coverage variable to generate (default "GoCover")
    
      Only one of -html, -func, or -mode may be set.
    

    用法

    go tool cover -html=c.out 
    生成一个html页面,查看覆盖率
    

    1.2. go 性能测试 benchmark

     go test -bench .
     go test -bench . -cpuprofile cpu.out
    

    1.3. go pprof

    go tool pprof cpu.out
    
    Type: cpu
    Time: Mar 21, 2019 at 9:29am (CST)
    Duration: 1.94s, Total samples = 1.58s (81.30%)
    Entering interactive mode (type "help" for commands, "o" for options)
    (pprof)  web
    

    输入web可以直接在线查看性能分析图


    OXS如果报错1:

    Failed to execute dot. Is Graphviz installed? Error: exec: "dot": executable file not found in $PATH

    解决方法

    brew install graphviz
    官网:graphviz.org
    

    报错2:

    OXS默认用sublime或者vscode打开svg文件,我们想要chrome打开

    修改svg格式文件,默认打开方式,用chrome即可
  • 相关阅读:
    Java I/O基础
    Python基础篇(九)
    Python基础篇(八)
    thinkphp5中Indirect modification of overloaded element of XXX has no effect的解决办法
    关于json_encode转义斜杠的问题
    [thinkexceptionErrorException] glob() has been disabled for security reasons
    CentOS7 安装svn
    -bash: /usr/bin/yum: /usr/bin/python: bad interpreter: No such file or directory
    php在线编辑本地文件方法共享
    python一些不错的东西
  • 原文地址:https://www.cnblogs.com/open-yang/p/11256864.html
Copyright © 2011-2022 走看看