引入
我们写了一段函数或者一个模块,我们该怎么确认他的运行结果是正确的呢?
当然我们有最简单粗暴的方法,就是直接调用该函数,看实际输出结果和预期结果是否一致,但是这样很不方便,我们在main函数里面调用,如果项目正在运行,需要停止项目,同时我们要测试多模块的时候需要调用很多函数,非常麻烦。
我们为了优化传统的测试方式,Go引入了testing框架和go test命令来进行单元测试和性能测试,testing框架和其他语言的测试框架类似,可以基于这个框架写针对相应函数的测试用例,也可以基于该框架写相应的压力测试用例,单元测试可以解决如下问题:
- 确保函数可运行,结果正确
- 代码性能良好
- 单元测试便于定位问题,性能测试可以使程序在高并发状态下能够保持稳定。
快速入门
我们就直接来一个案例,来体验一下。
特别说明:测试时要退出360(?别问为啥是360,ttdr电脑里没有360),因为360可能认为测试用例程序是木马
cal1.go
package main
func addUpper(n int) int {
res := 0
for i := 1; i <= n-1; i++ {
res += i
}
return res
}
cal_test.go
testing框架会直接将xxx_test.go文件引入,同时调用TestXxx函数
package main
import (
"testing"
)
// 测试用例
func TestAddUpper(t *testing.T) {
res := addUpper(10)
if res != 55 {
t.Fatalf("执行错误实际值为%v", res)
}
t.Logf("执行正确")
}

总结
- 测试用例文件名必须是)
_test.go结尾,测试用例函数必须是Test开头。 - Test开头的测试用例函数二点形参类型必须是
*testing.T* - 一个测试用例文件中可以有多个测试用例函数
- 运行测试用例指令
go test、go test -v - 出现错误时可以用
t.Fatalf来格式化输出错误信息,并退出程序 t.Logf可以输出相应日志- 测试用例函数并没有放在main函数中,但是也执行了,这就是测试用例的方便之处
- PASS表示测试用例运行成功,FAIL表示测试用例运行失败
案例
- 编写一个Monster结构体,字段 Name, Age, Skill
- 给Monster绑定方法Store,可以将一个Monster变量(对象),序列化后保存到文件中
- 给Monster绑定方法ReStore,可以将一个序列化的Monster,从文件中读取,并反序列化为Monster对象,检查反序列化,名字正确。
- 编程测试用例文件 monster_test.go,编写测试用例函数 TestStore 和 TestRestore 进行测试。
monster.go
package testing
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type Monster struct {
Name string
Age int
Skill string
}
func (this *Monster) Store() bool {
data, err := json.Marshal(this)
if err != nil {
fmt.Println("序列化失败", err)
return false
}
filePath := "d:/日志/monster.ser"
err = ioutil.WriteFile(filePath, data, 0666)
if err != nil {
fmt.Println("write file err:", err)
return false
}
return true
}
func (this *Monster) UnStore() bool {
filePath := "d:/日志/monster.ser"
data, err := ioutil.ReadFile(filePath)
if err != nil {
return false
}
err = json.Unmarshal([]byte(data), this)
if err != nil {
fmt.Println("反序列化失败", err)
}
return true
}
func main() {
}
monster_test.go
package testing
import "testing"
func TestMonster_Store(t *testing.T) {
monster := Monster{
Name: "幻胧",
Age: 1000,
Skill: "丰饶",
}
res := monster.Store()
if !res {
t.Fatalf("store()错误,错误值为%v", res)
}
t.Logf("monster.Store()测试成功")
}
func TestMonster_UnStore(t *testing.T) {
var monster Monster
res := monster.UnStore()
if !res {
t.Fatalf("unstore()错误,错误值为%v", res)
}
if monster.Name != "幻胧" {
t.Fatalf("unstore()错误,错误值为%v", res)
}
t.Logf("unstore测试成功")
}










