作为⼀个优秀的开发者,任何代码可能的执⾏分⽀都应测试。在Go语⾔当中,官⽅包testing给我们提
供了很好的测试服务。官⽅包为我们提供了两种测试:单元测试与压⼒测试。
⾄于单元测试,除了项⽬本身的代码外,还要提供专⻔针对某package或功能的测试⽂件。该⽂件有3
个要求:
- ⽂件必须以"_test.go"作为结尾
- ⽂件内的测试函数必须以TestXxx开头,Xxx要求⾸字⺟必须⼤写
- 函数参数是 *testing.T 类型
⽐如我们测试,新建⼀个⽬录animal,在⽬录下创建两个⽂件,⼀个是源码⽂件,⼀个是测试代码⽂
件。
animal.go
// 源码包
package animal
import (
"fmt"
)
type Cat struct {
Name string
Color string
Age uint
}
func NewCat(name, color string, age uint) *Cat {
return &Cat{name, color, age}
}
func (c *Cat) Sleeping() {
fmt.Println(c.Color, "Cat", c.Name, "is sleeping")
}
func (c *Cat) Eating() {
fmt.Println(c.Color, "Cat", c.Name, "is Eating")
}
func (c *Cat) Print() {
fmt.Printf("+%v\n", c)
}
ani_test.go
// 测试代码
package animal
import (
"testing"
)
func Test_sleeping(t *testing.T) {
c := NewCat("Sinmigo", "white", 20)
c.Sleeping()
}
func Test_eating(t *testing.T) {
c := NewCat("Sinmigo", "black", 20)
c.Eating()
if c.Color == "white" {
t.Log("Eating测试通过")
} else {
t.Error("Eating测试不通过")
}
}
func BenchmarkBigLen(b *testing.B) {
//c := NewCat("Sinmigo", "white", 20)
for i := 0; i < b.N; i++ {
//c.Sleeping()
}
}
对我们来说,主要关注两个参数
- v 显示测试详细信息
- cover 显示测试的覆盖率
localhost:animal teacher$ go test -v -cover
=== RUN Test_sleeping
white Cat Sinmigo is sleeping
--- PASS: Test_sleeping (0.00s)
=== RUN Test_eating
black Cat Sinmigo is Eating
--- FAIL: Test_eating (0.00s)
ani_test.go:18: Eating测试不通过
FAIL
coverage: 75.0% of statements
exit status 1
FAIL github.com/teacher/animal 0.005s
经过运⾏,我们看到代码测试覆盖率为75%,Eating测试不通过(我们⼈为造成的)。
在上⾯的测试代码中,我们可以看到⼀个BenchmarkBigLen函数,这个函数是Go语⾔当中性能测试的
函数。这类性能测试的要求是:
- BenchmarkXxx 这样的函数声明,Xxx⾸字⺟要⼤写
- 函数参数为*testing.B
可以在运⾏的时候添加 -bench参数,来测试函数执⾏的性能,它的内部可以是执⾏数量巨⼤的循环。
localhost:animal teacher$ go test -bench=.
white Cat Sinmigo is sleeping
black Cat Sinmigo is Eating
goos: darwin
goarch: amd64
pkg: github.com/teacher/animal
BenchmarkBigLen-4 1000000000 0.266 ns/op
PASS
ok github.com/teacher/animal 0.299s
bench后⾯是⼀个正则表达式,如果只针对某⼀个函数测试,写具体的函数名称也可以