转golang心路历程 | 第4集 惊!两个简单例子竟搞懂转单元测试了

141 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、在go里面,单元测试有何价值?

在搬砖的过程中,经常会写一些方法(func)来解决一些业务功能上的一些问题,当代码盲写完了后就需要考察其是否可以正常运行,是否可以拿到预期的结果,代码的质量是否过关,是否测试介入的时候能被少提一些bug。如果需要达成这些就需要单元,使问题及早暴露,便于问题的定位解决,而性能测试的重点在于发现程序设计上的一些问题,让线上的程序能够在高并发的情况下还能保持稳定,下面博主就讲一下在Golang语言中如何来实现单元测试和性能测试。

二、如何编写单元测试之测试用例?

1. 废话少数,先上代码

    // 主体功能
    
    package gotest
 
    import (
        "errors"
    )

    func Division(a, b float64) (float64, error) {
        if b == 0 {
            return 0, errors.New("不好意思,除数不能为0!")
        }
 
        return a / b, nil
    }

    // 测试用例
    
    package gotest
 
    import (
        "testing"
    )
 
    func Test_Division_Demo(t *testing.T) {
        if i, e := Division(6, 2); i != 3 || e != nil { //try a unit test on function
            t.Error("大哥拜托,除法函数测试都没通过!") // 断言一下,如果不是如预期的那么就报错
        } else {
            t.Log("大哥牛掰,第一个测试通过了") //写个日志,记录一些你想要记录的信息
        }
    }
 
    func Test_Division_Demo1(t *testing.T) {
        t.Error("大哥,你别折腾了,这里是牛角尖地带,你通过不了的")
    }

2. 深入浅出,要点解析

1. Go语言中自带有一个轻量级的测试框架『testing』和自带的『go test』命令来实现单元测试和性能测试

2. 如果你想自动生成测试文件,可以执行如下命令来下载gotests插件 

` go get -u -v github.com/cweill/gotests/... `

3. 文件名必须是`_test.go`结尾的(文件名必须是`*_test.go`的类型,*代表要测试的文件名),这样在执行`go test`的时候才会执行到相应的代码

4. 所有的测试用例函数必须是`Test`开头(函数名必须以Test开头如:TestXxxTest_xxx)

5. 测试函数`TestXxx()`的参数是`testing.T`,我们可以使用该类型来记录错误或者是测试状态

6. 测试格式:`func TestXxx (t *testing.T)`,`Xxx`部分可以为任意的字母数字的组合,但是首字母不能是小写字母[a-z],例如`Testintdiv`是错误的函数名。

7. 函数中通过调用`testing.T``Error``Errorf``FailNow``Fatal``FatalIf`方法,说明测试不通过,调用`Log`方法用来记录测试的信息。

3. 知行合一,实战演习

  • 直接通过用例左侧的按钮进行单个测试用例执行

image.png

  • 切到test文件所在目录下面,批量执行 go test 命令

image.png

三、如何编写单元测试之性能测试?

1. 废话少说,先上代码

package gotest
 
import (
    "testing"
)
 
func Benchmark_Division(b *testing.B) {
    for i := 0; i < b.N; i++ { // b.N可以用来遍历
        Division(4, 5)
    }
}
 
func Benchmark_TimeConsumingFunction(b *testing.B) {
    b.StopTimer() //调用该函数停止压力测试的时间计数
 
    //处理一些相对复杂的业务逻辑
 
    b.StartTimer() //重新开始时间
    for i := 0; i < b.N; i++ {
        Division(4, 5)
    }
}

2. 深入浅出,要点解析

    
1. 创建benchmark性能测试用例文件`*_b_test.go`(文件名使用`*_b_test.go`的类型(也可直接放在test文件中),*代表要测试的文件名

2. 函数名必须以Benchmark开头如:BenchmarkXxxBenchmark_xxx),压力测试用例必须遵循如下格式,其中xxx可以是任意字母数字的组合,但是Xxx首字母不能是小写字母

3. `go test`不会默认执行压力测试的函数,如果要执行压力测试需要带上参数`-test.bench`,语法:`-test.bench="test_name_regex"`,例如`go test -test.bench=".*"`表示测试全部的压力测试函数

4. 在压力测试用例中,请记得在循环体内使用`testing.B.N`,以使测试可以正常的运行

5. 如果需要可视化结果,可以依次执行如下命令

//先生成生成的`cpu profile`文件, -c 生成二进制文件

`go test -bench=".*" -cpuprofile=cpu.prof -c`

//后使用go tool pprof工具

`go tool pprof *.test cpu.prof`

//调用web(需要安装graphviz)来生成svg文件,生成后使用浏览器查看svg文件

3. 执行合一,实战演习

image.png

在打通了golang开发的基本环境和调试工具之后,就需要好好学学万变不离其宗的书写语法了, 下节课会给大家分享些常用的学习资料及重点、难点、易错点 ~

欲知后事如何, 倾听下回讲解 ~

image.png