go语言单元测试 | 青训营

49 阅读2分钟

测试

代码在开发时难免会出现错误,语法上的错误在编译时就可以解决,但是一些逻辑上的错误,就需要测试来找出和解决问题,以免造成事故

image.png

测试是避免事故的最后一道屏障

image.png

从上到下,覆盖率逐层变大,成本却逐层降低

单元测试

单元测试就是对某个组件或某个端口进行测试,来保证功能的健全性

image.png

单元测试的规则

1.所有测试文件以_test.go结尾

2.测试函数命名规则:func TestXxx(*testing.T)

3.初始化逻辑放到TestMain中

image.png

示例代码

hello.go

package main
​
func HelloTom() string {
    return "Jerry"
}

hello_test.go

package main
​
import (
    "testing"
)
​
func TestHelloTom(t *testing.T) {
    output := HelloTom()
    expectOutput := "Tom"
    if output != expectOutput {
        t.Errorf("Expected %s do not match actual %s", expectOutput, output)
    }
}

运行结果

运行命令:go test 测试文件名 源文件名

image.png

单元测试组件-assert

assert组件中,提供了一些接口可以用于测试代码

获取assert命令:go get "github.com/stretchr/testify/assert"

示例代码

hello_test.go

package main
​
import (
    "testing""github.com/stretchr/testify/assert"
)
​
func TestHelloTom(t *testing.T) {
    output := HelloTom()
    expectOutput := "Tom"
    //利用assert组件进行单元测试
    assert.Equal(t, expectOutput, output)
}

运行结果

image.png

单元测试覆盖率

通常用单元测试的覆盖率,来衡量代码测试的程度

在测试命令后面加上--cover就可以显示测试代码的覆盖率

1.一般覆盖率:50%~60%,较高覆盖率80%+

2.测试分支相互独立、全面覆盖

3、测试单元粒度足够小,函数单一职责

单元测试-依赖

image.png

外部依赖 => 稳定&幂等

单元测试-文件处理

示例代码

hello.go

package main
​
import (
    "bufio"
    "os"
    "strings"
)
​
func ReadFirstLine() string {
    open, err := os.Open("log")
    defer open.Close()
    if err != nil {
        return ""
    }
    scanner := bufio.NewScanner(open)
    for scanner.Scan() {
        return scanner.Text()
    }
    return ""
}
​
func ProcessFirstLine() string {
    line := ReadFirstLine()
    destLine := strings.ReplaceAll(line, "11", "00")
    return destLine
}

hello_test.go

package main
​
import (
    "testing""github.com/stretchr/testify/assert"
)
​
func TestProcessFirstLine(t *testing.T) {
    firstLine := ProcessFirstLine()
    assert.Equal(t, "line00", firstLine)
}

运行结果

image.png

单元测试-Mock

monkey:github.com/bouk/monkey

快速Mock函数

为一个函数打桩

为一个方法打桩

image.png

image.png

对ReadFirstLine打桩测试,不在依赖本地文件

基准测试

1.优化代码,需要对当前代码分析

2.内置的测试框架提供了基准测试的能力

fastrand随机数

获取命令:go get "github.com/NebulousLabs/fastrand"

示例代码

server.go

package main
​
import (
    "math/rand"
    "time"
)
​
var ServerIndex [10]intfunc InitServerIndex() {
    for i := 0; i < 10; i++ {
        ServerIndex[i] = i + 100
    }
}
​
func Select() int {
    rand.Seed(time.Now().UnixNano())
    return ServerIndex[rand.Intn(10)]
}
​
/*func FastSelect() int {
    return ServerIndex[fastrand.Intn(10)]
}*/

server_test.go

package main
​
import (
    "testing"
)func BenchmarkSelect(b *testing.B) {
    InitServerIndex()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        Select()
    }
}
​
/*func BenchmarkSelectParallel(b *testing.B) {
    InitServerIndex()
    b.ResetTimer()
    b.RunParallel(
        func(pb *testing.PB) {
            for pb.Next() {
                Select()
            }
        })
}*/

运行结果

image.png