普通测试
package main
import (
"fmt"
)
func AddUpper(n int) int {
res := 0
for i := 1; i <= n; i++ {
res += i
}
return res
}
func main() {
ans := AddUpper(10)
if ans == 55 {
fmt.Printf("AddUpper 正确, 返回值%v, 期望值%v
", ans, 55)
} else {
fmt.Printf("AddUpper 错误, 返回值%v, 期望值%v
", ans, 55)
}
}
单元测试入门
上面看似很好但是假如你的main函数正在运行你直接跑一个么? 不可能必然会影响服务
目录结构:
day02/utils/func.go
package utils
func AddUpper(n int) int {
res := 0
for i := 1; i <= n; i++ {
res += i
}
return res
}
func Sub(a, b int) int {
return a - b
}
day02/utils/cal_test.go
package utils
import (
"fmt"
"testing"
)
//go test day02/utils -v 使用go test运行测试文件 -v 表示打印详细信息
func TestAddUpper(t *testing.T) { // 函数名字可以随便写, 但是建议与Test+原函数名
res := AddUpper(10)
if res != 56 {
fmt.Printf("addUpper(10) error, ans: %v", res)
}
t.Logf("test addUpper succ")
}
func TestSub(t *testing.T) {
ans := Sub(10, 2)
if ans != 8 {
fmt.Printf("Sub(10) error, ans: %v", ans)
}
t.Logf("test Sub succ")
}
/*
单元测试快速入门总结
1) 测试用例文件名必须以 _test.go 结尾。 比如 cal_test.go , cal 不是固定的。
2) 测试用例函数必须以 Test 开头,一般来说就是 Test+被测试的函数名,比如 TestAddUpper
3) TestAddUpper(t *tesing.T) 的形参类型必须是 *testing.T 【看一下手册】
4) 一个测试用例文件中,可以有多个测试用例函数,比如 TestAddUpper、TestSub
5) 运行测试用例指令
(1) cmd>go test [如果运行正确,无日志,错误时,会输出日志]
(2) cmd>go test -v [运行正确或是错误,都输出日志]
6) 当出现错误时,可以使用 t.Fatalf 来格式化输出错误信息,并退出程序
7) t.Logf 方法可以输出相应的日志
8) 测试用例函数,并没有放在 main 函数中,也执行了,这就是测试用例的方便之处[原理图].
9) PASS 表示测试用例运行成功,FAIL 表示测试用例运行失败
10) 测试单个文件,一定要带上被测试的原文件
go test -v cal_test.go cal.go
11) 测试单个方法
go test -v -test.run TestAddUpper // 老师的里面把-test写上了, 实际上执行时不需要写
go test day02/utils/ -v -run TestAddUpper -run 使用正则匹配满足后面条件的用例
*/
单元测试在通过go test 调用是会将你写的这些函数加载到单元测试框架的main函数中执行, 不影响现有业务, 通过可以根据不同参数执行不同的测试方法, 具体查看go help test.
单元测试案例
目录结构:
day02/monster/monster.go
package monster
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type Monster struct {
Name string
Age int
Skill string
}
// 序列化一个Monster对象到文件
func (this *Monster) Store() bool {
data, err := json.Marshal(this)
if err != nil {
fmt.Println("marshal err: ", err)
return false
}
filepath := "C:/Users/yzt/Desktop/test.txt"
err = ioutil.WriteFile(filepath, data, 0666)
if err != nil {
fmt.Println("write file err: ", err)
return false
}
return true
}
// 从文件反序列化Monster对象
func (this *Monster) ReStore() bool {
filepath := "C:/Users/yzt/Desktop/test.txt"
data, err := ioutil.ReadFile(filepath)
if err != nil {
fmt.Println("read file failed, err: ", err)
return false
}
err = json.Unmarshal(data, this)
if err != nil {
fmt.Println("unmarshal failed, err: ", err)
return false
}
return true
}
day02/monster/monster.go
package monster
import (
"testing"
)
func TestStore(t *testing.T) {
var m1 = Monster{Name: "巴拉巴拉", Age: 12, Skill: "会飞"}
ok := m1.Store()
if !ok {
t.Fatalf("monster.Store() 错误, 期望为%v, 实际为%v", true, ok)
}
t.Logf("monster.Store() success")
}
func TestReStore(t *testing.T) {
var m1 = &Monster{}
ok := m1.ReStore()
if !ok {
t.Fatalf("monster.ReStore() 错误, 期望为%v, 实际为%v", true, ok)
}
if m1.Name != "巴拉巴拉" {
t.Fatalf("monster.ReStore() 错误, 期望为%v, 实际为%v", "巴拉巴拉", m1.Name)
}
t.Logf("monster.ReStore() success")
}
/*
t.Logf 作用类似 fmt.Printf 会将你填入的参数进行拼接, 同时记录入日志中, 如果不见-v参数成功日志默认不打印, 加上-v显示内容(不结束程序)
t.Fatalf 作用类似t.Logf, 不过是相当于报错(将本次测试直接比较为FAIL错误状态), 直接打印到控制台, 同时结束程序
*/