195. go单元测试

普通测试

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错误状态), 直接打印到控制台, 同时结束程序
*/
原文地址:https://www.cnblogs.com/liuzhanghao/p/15353181.html