golang测试

作者: 一如既往wfqwfq | 来源:发表于2020-06-02 10:56 被阅读0次

    单元测试

    在学习单元测试之前,测试代码一般都是些在main函数里去调用我们写的函数,以此来判断函数的正确性。学习单元测试后,我们可以直接在测试函数里去测试,提提高代码的可读性和测试效率。

    go测试

    golang中提供了非常完善的测试功能。所有测试代码文件以*_test.go命名,测试函数以Test被测函数名(TestAdd)命名,测试命令以go test开头。
    golang中有3中测试函数,分别为单元测试函数、性能测试函数、示例函数。

    类型 格式 作用
    单元测试函数 函数名以Test为前缀 测试代码逻辑是否正确
    性能测试函数(基准函数) 函数名以Benchmark为前缀 测试函数的性能
    示例函数 函数名前缀为Example 为文档提供示例文档

    单元测试函数

    每个测试函数必须导入test包,函数名以Test为前缀,*testing.T用于报告测试失败和附加的日志信息。单元测试函数格式如下

    func TestAdd(t *testing.T) {
      // todo
    }
    

    简单测试函数示例

    定义一个test包,并编写函数Add

    package test
    
    func Add(m int, n int) (sum int) {
        sum = m + n
        return
    }
    

    接下来,在当前目录下创建add_test.go文件,并定义测试函数:

    //测试函数名必须以Test开头,必须接收一个*testing.T类型参数
    func TestAdd(t *testing.T) {
    
        /**
        * 简单测试
        */
        got := Add(3, 5)  // 程序计算得出的结果
        want := 8  // 期望结果
        if got != want  {  // 程序计算出的结果与期望结果比较
            t.Errorf("excepted:%v, got:%v", want, got)
        }
    }
    

    在test包目录下执行go test命令,得到结果:

    • 程序得到结果与预期结果相同:


      image.png
    • 程序得到结果与预期结果不同:


      image.png

    子测试函数示例

    在简单测试函数示例中,我们一次只能测试一组数据,如果有多组测试数据的话要么在创建一个函数来测试,要么使用循环。使用循环测试的情况下,我们无法得出哪条测试数据有问题。golang中提供子测试方法,我们可以通过*testing.T.Run方法来执行子测试。

    func TestAdd(t *testing.T) {
        // 测试数据,期望结果结构体
        type data struct {
            m int
            n int
            want int
        }
        // 测试组需要使用map类型,后续查看测试结果比较方便
        tests := map[string]data{
            "one": {m: 1, n: 2, want: 3},
            "two": {m: 10, n: 5, want: 15},
            "three": {m: 25, n: 16, want: 41},
            "four": {m: 10, n: 6, want: 16},
            "five": {m: 0, n: 0, want: 1},
        }
        for name, d := range tests{
            //  t.Run函数,需要传入测试数据的name,即上面map中的one\two\three
            t.Run(name, func(t *testing.T) {
                got := Add(d.m, d.n)
                if got != d.want {
                    t.Errorf("name:%s excepted:%#v, got:%#v", name, d.want, got) // 将测试用例的name格式化输出
                }
            })
        }
    }
    

    执行go test -v查看测试结果的详细信息

    image.png

    性能测试函数

    性能测试函数也叫基准测试函数,函数名以Benchmark为前缀。性能测试函数格式如下:
    性能测试函数需要执行b.N次,这个由系统决定的。

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

    性能测试示例:

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

    执行基准函数:go test -bench=函数名 -benchmem(go test -bench=Add -benchmem)

    • 基准函数默认是不会执行的,需要参数-bench
    • -benchmen会显示一些内存分配的统计数据
      image.png
      统计数据的意义:
    • BenchmarkAdd-8:表示GOMAXPROCS(线程数)的值为8
    • 2000000000:表示执行的次数
    • 0.26 ns/op:表示每次执行时间0.26ns
    • 0B/op:表示每次执行分配内存0B
    • 0 allocs/op:表示每次执行分配内存的次数

    覆盖率测试

    覆盖率测试表示代码被测试套件覆盖的百分比。
    执行命令:go test -cover
    可以看到,当前代码的覆盖率是50%

    image.png
    -coverprofile参数可以将覆盖率的相关信息输出到一个文件中
    将函数覆盖率相关信息输出到a.out,a.out在当前目录下生成。
    image.png
    执行命令:go tool cover -html=a.out,可以在浏览器上看到覆盖率相关信息
    image.png

    测试命令总结

    • 测试包下所有测试文件:go test
    • 打印测试详细信息:go test -v
    • 测试单个方法:go test -v -run=方法名 // go test -v -run=Add
    • 覆盖率测试:go test -cover
    • 覆盖率测试,并输出到文件中:go test -cover -coverprofile=c.out
    • 浏览器查看覆盖率文件:go tool cover -html=c.out
    • 性能测试:go test -bench=方法名
    • 性能测试显示详细信息:go test -bench=方法名 -benchmem
    • 只执行性能测试不执行单元测试 :go test -v -run=none -bench=方法名

    相关文章

      网友评论

        本文标题:golang测试

        本文链接:https://www.haomeiwen.com/subject/kyziahtx.html