这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
1.复习已学知识
- 复习并发编程的基本知识
- 复习Goroutine
- 复习WaitGroup
- 复习Lock
- 复习Channel
- 复习依赖管理
2.观看Go语言进阶与依赖管理
- Go 与单元测试
为什么需要测试,什么是单元测试
通常,对于一个玩具项目,我们喜欢将其写完后直接部署到生产环境,有 Bug 在修,但是,这对于企业开发来说是完全不能忍受的,因为一个小小的 Bug 便可带来天文数字的损失。因此,在程序上线前进行测试对于企业开发来说便是一个必要的活动。
通常,有多种测试方法可以使用,例如回归测试,集成测试,单元测试,而单元测试(Unit Test) 是成本最低,覆盖率最高的测试方法。所谓单元测试,便是为代码的每一个模块,函数定制单独的测试,保证输入指定值后输出正常值。通过多个单元测试合并运作,我们便可得知项目的每一个细节都在正确运行,最终得知项目整体运作正常。
进行单元测试
Go 内置单元测试支持。所有以 _test.go 结尾的代码会被 Go 识别为单元测试文件。
一个单元测试函数的函数名应当以 Test 开头,并包含 *testing.T 形参。
可通过 func TestMain(m *testing.M) 函数对测试数据进行初始化,并调用 m.Run() 运行单元测试。
以下代码是一个简单的单元测试例子,测试 HelloTom 函数是否正常返回值 Tom:
// In xxx.go:
func HelloTom() string {
return "Jerry"
}
// In xxx_test.go:
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 指令运行单元测试,得到运行失败的输出:
=== RUN TestHelloTom
xxx_test.go:9: Expected Tom do not match actual Jerry
--- FAIL: TestHelloTom (0.00s)
当然,我们也可以引入社区提供的依赖库来加快单元测试开发,诸如通过 testify/assert 库进行覆盖率测试,或通过 bouk/monkey 库对数据进行 Mock。此处不再赘述。
基准测试
有时,我们想要测量一个函数执行不同次数,或是在不同环境下执行函数的性能,这时,就需要进行基准测试。Go 内置基准测试支持。
以下代码模拟了一个负载均衡的例子,在 10 个服务器中随机返回数据,我们将对 Select 方法分别进行串行和并行的基准测试:
// In xxx.go:
import "math/rand"
var ServerIndex [10]int
func InitServerIndex() {
for i := 0; i < 10; i++ {
ServerIndex[i] = i + 100
}
}
func Select() int {
return ServerIndex[rand.Intn(10)]
}
// In xxx_test.go:
package main
import "testing"
func BenchmarkSelect(b *testing.B) {
InitServerIndex()
b.ResetTimer() // 重置计数器是因为 InitServerIndex 不应包含在测试时间内
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()
}
})
}
并使用 go test -bench= 指令运行基准测试,得到结果:
GOROOT=F:\Program Files\Go #gosetup
GOPATH=C:\Users\shaok\go #gosetup
"F:\Program Files\Go\bin\go.exe" test -c -o C:\Users\shaok\AppData\Local\Temp\GoLand___gobench_helloWorld.test.exe helloWorld #gosetup
C:\Users\shaok\AppData\Local\Temp\GoLand___gobench_helloWorld.test.exe -test.v -test.paniconexit0 -test.bench . -test.run ^$ #gosetup
goos: windows
goarch: amd64
pkg: helloWorld
cpu: AMD Ryzen 7 5800H with Radeon Graphics
BenchmarkSelect
BenchmarkSelect-16 164467417 7.332 ns/op
BenchmarkSelectParallel
BenchmarkSelectParallel-16 26950542 43.85 ns/op
PASS
根据基准测试结果,我们可以进行针对性的优化。