golang单元测试

单元测试

类型 前缀 签名 用途
测试函数 Test func TestXxx(t *testing.T) 功能测试、验证逻辑正确性
基准函数 Benchmark func BenchmarkXxx(b *testing.B) 性能测试、效率评估
示例函数 Example func ExampleXxx() 用法展示、生成文档

testing框架

  1. 文件名以_test.go结尾,放在与被测试包相同的包中
  2. 测试用例函数名以Test开头,一般为Test+被测试的函数名)
  3. **TestaddUpper(*testing.T)**的形参类型必须是*testing.T
  4. 一个测试用例文件中,可以有很多测试用例函数,比如TestAddUpper、TestSub
  5. 运行测试用例指令
    • cmd>go test 运行正确,无日志;运行错误,输出日志
    • cmd>go test -v 运行正确或是错误,都将输出日志
  6. t.Fatalf方法可以格式化输出错误信息,并退出程序
  7. t.Logf方法可以输出相应日志
  8. PASS表示运行成功,FAIL表示运行失败
go 复制代码
func addUpper(n int) int {
	res := 0
	for i := 1; i <= n; i++ {
		res += i
	}
	return res
}

func TestAddUpper(t *testing.T) {

	res := addUpper(10)
	if res != 55 {
		//fmt.Println("AddUpper(10) 执行错误,期望值=%v 实际值=%v", 55, res)
		t.Fatalf("AddUpper(10) 执行错误,期望值=%v 实际值=%v", 55, res)
	}

	//如果正确,输出日志
	t.Logf("AddUpper(10) 执行正确...")
}

实例:

go 复制代码
// 给Monster绑定方法Store,可以将一个Monster变量(对象),序列化后保存到文件中
func (this *Monster) Store() bool {

	//先序列化
	data, err := json.Marshal(this)
	if err != nil {
		fmt.Println("marshal err =", err)
		return false
	}
	//保存到文件
	filePath := "D:\\GoLand-go\\filedemo.txt"
	err = ioutil.WriteFile(filePath, data, 0666)
	if err != nil {
		fmt.Println("write file err =", err)
		return false
	}
	return true
}

// 给Monster绑定方法ReStore,可以将一个序列化的Monster,从文件中读取
// 并且反序列化为monster对象,检查反序列化,名字正确
func (this *Monster) ReStore() bool {

	//先从文件中,读取序列化的字符串
	filePath := "D:\\GoLand-go\\filedemo.txt"
	data, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Println("ReadFile err =", err)
		return false
	}

	//使用读取到data []byte,对反序列化
	err = json.Unmarshal(data, this)
	if err != nil {
		fmt.Println("UnMarshal err = ", err)
		return false
	}
	return true
}

// 测试用例,测试Store方法
func TestMonster_Store(t *testing.T) {

	//先创建一个Monster实例
	monster := Monster{
		Name:  "红孩儿",
		Age:   10,
		Skill: "吐火",
	}
	res := monster.Store()
	if !res {
		t.Fatalf("monster.Store() 错误,希望为=%v 实际为=%v", true, res)
	}
	t.Logf("monster.Store() 测试成功!")
}

// 测试用例,测试ReStore方法
func TestMonster_ReStore(t *testing.T) {

	//先创建一个Monster实例,不需要指定字段的值
	var monster Monster

	res := monster.ReStore()
	if !res {
		t.Fatalf("monster.ReStore() 错误,希望为=%v 实际为=%v", true, res)
	}
	//进一步判断
	if monster.Name != "红孩儿" {
		t.Fatalf("monster.ReStore() 错误,希望为=%v 实际为=%v", "红孩儿", monster.Name)

	}

	t.Logf("monster.ReStore() 测试成功!")
}

基准测试

基准测试以Benchmark为前缀,需要一个testing.B类型的参数 b*,基准测试必须要执行b.N次,这样的测试才有对照性,b.N的值是系统根据实际情况去调整的,从而保证测试的稳定性

基准测试并不会默认执行,需要增加**-bench参数(还可以为基准测试添加-benchmem**参数,来获得内存分配的统计数据)

默认情况下,每个基准测试至少运行1秒。如果在Benchmark函数返回时没有到1秒,则b.N的值会按1,2,5,10,20,50,...增加,并且函数再次运行

b.ResetTimer之前的处理不会放到执行时间里,也不会输出到报告中,所以可以在之前做一些不计划作为测试报告的操作

相关推荐
知识分享小能手1 小时前
C++ 学习教程,从入门到精通,C++ 友元、异常和其他特性 — 详细知识点(15)
开发语言·c++·学习
朝朝辞暮i1 小时前
C++ 第 26 课:对象、指针与 ->
java·开发语言·c++
2601_962885722 小时前
如何用 Python 做股价历史分位选股?(筛出处于历史低位的股票)
开发语言·python
殷色玫瑰3 小时前
C++入门基础复习:从命名空间到引用与nullptr,一篇重新捡回C++基础
java·开发语言·c++
(Charon)3 小时前
【C++面试】手写线程池:任务队列、工作线程与优雅退出
开发语言·c++
言乐63 小时前
Python概括后端原理
开发语言·python·django·virtualenv·pygame
@大迁世界3 小时前
JEV RAG:更高效的 RAG 系统解决方案?
开发语言·rust
朝朝辞暮i4 小时前
C++ 第一阶段总结:从零基础到 ROS2 前置语法
开发语言·c++·算法
2601_962885724 小时前
如何用 Python 回测定投策略(定期定额 DCA)?(和一次性买入对比)
开发语言·人工智能·python
周杰偷奶茶4 小时前
【JavaSE】类和对象基础
java·开发语言