测试
代码在开发时难免会出现错误,语法上的错误在编译时就可以解决,但是一些逻辑上的错误,就需要测试来找出和解决问题,以免造成事故
测试是避免事故的最后一道屏障
从上到下,覆盖率逐层变大,成本却逐层降低
单元测试
单元测试就是对某个组件或某个端口进行测试,来保证功能的健全性
单元测试的规则
1.所有测试文件以_test.go结尾
2.测试函数命名规则:func TestXxx(*testing.T)
3.初始化逻辑放到TestMain中
示例代码
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 测试文件名 源文件名
单元测试组件-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)
}
运行结果
单元测试覆盖率
通常用单元测试的覆盖率,来衡量代码测试的程度
在测试命令后面加上--cover就可以显示测试代码的覆盖率
1.一般覆盖率:50%~60%,较高覆盖率80%+
2.测试分支相互独立、全面覆盖
3、测试单元粒度足够小,函数单一职责
单元测试-依赖
外部依赖 => 稳定&幂等
单元测试-文件处理
示例代码
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)
}
运行结果
单元测试-Mock
monkey:github.com/bouk/monkey
快速Mock函数
为一个函数打桩
为一个方法打桩
对ReadFirstLine打桩测试,不在依赖本地文件
基准测试
1.优化代码,需要对当前代码分析
2.内置的测试框架提供了基准测试的能力
fastrand随机数
获取命令:go get "github.com/NebulousLabs/fastrand"
示例代码
server.go
package main
import (
"math/rand"
"time"
)
var ServerIndex [10]int
func 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()
}
})
}*/
运行结果