当前位置: 首页 > article >正文

【Golang】Go语言编程思想(四):测试与性能调优

测试与性能调优

传统测试 vs. 表格驱动测试

Golang 采用“表格驱动测试”的做法。

传统测试

  • 测试数据和测试逻辑混在一起;
  • 出错信息不明确;
  • 一旦一个数据出错测试全部结束;

表格驱动测试

  • 分离的测试数据和测试逻辑;
  • 明确的出错信息;
  • 可能部分失败;
  • Go 语言的语法使得我们更容易实践表格驱动测试(Java / C++ 很难实现表格驱动测试,原因是语法上支持度较差);

执行测试

在 Golang 当中,将测试的代码命名为 […]_test.go,将其与被测的代码放在一起:
在这里插入图片描述
以测试给定的三个整型变量是否可以构成三角形的三条边为例,triangle_test.go 应该以如下方式进行编写,从而完成表格驱动测试:

package main	// 与 basic.go 的 package 相同, 都是 main

import "testing"

func TestTriangle(t *testing.T) {
	tests := []struct{ a, b, c int }{
		{3, 4, 5},
		{5, 12, 13},
		{8, 15, 17},
		{12, 35, 0},			// 故意引入一个错误实例
		{30000, 40000, 50000},
	}

	for _, tt := range tests {
		if actual := calcTriangle(tt.a, tt.b); actual != tt.c {
			t.Errorf("calcTriangle(%d, %d) = %d, want %d", tt.a, tt.b, actual, tt.c)
		}
	}
}

执行测试:
在这里插入图片描述
Goland 非常友好,当测试没有执行通过时,会标红:
在这里插入图片描述
修改测试用例,使测试通过:
在这里插入图片描述
在这里插入图片描述
如果想要在命令行中进行测试,那么直接进入到要测试的目录下,这个目录下应该包含想要测试的文件以及测试它的文件,直接使用go test .即可完成测试。

使用测试进行代码覆盖率检察以及性能测试

可以直接在 IDE 中右键点击 test 函数,执行“使用覆盖率运行…”:
在这里插入图片描述
以此可以得到代码的覆盖率。

同时,可以编写用于性能测试的函数:

func BenchmarkSubstr(b *testing.B) {
	// 性能测试
	s := "TestForNonRepeatingSubstr"
	ans := 11
	actual := lengthOfNonRepeatingSubStr(s)

	for i := 0; i < b.N; i++ {	// b.N 是 内置的用于性能测试的量
		if actual != ans {
			b.Errorf("got %d for input %s; "+
				"expected %d",
				actual, s, ans)
		}
	}
}

使用 pprof 进行性能调优

需要注意的是,刚才进行的性能调优使用的测试数据过短,可以使用以下的方式对上述性能测试函数进行改写,得到:

func BenchmarkSubstr(b *testing.B) {
	// 性能测试
	s := "TestForNonRepeatingSubstr"

	for i := 0; i < 13; i++ {
		s = s + s // 扩展测试数据
	}
	ans := 11

	b.Logf("len(s)=%d", len(s))
	b.ResetTimer() // 重置时钟, 只计算下面测试需要用的时间, 不包括扩展数据的时间

	for i := 0; i < b.N; i++ {
		actual := lengthOfNonRepeatingSubStr(s)
		if actual != ans {
			b.Errorf("got %d for input %s; "+
				"expected %d",
				actual, s, ans)
		}
	}
}

可以在命令行执行上述操作,首先在 terminal 中进入到当前路径下。

之后使用命令 go test -bench .,在命令行中完成与 IDE 相同的测试操作。

可以进一步使用go test -bench . -cpuprofile cpu.out来将测试的结果输入到文件当中,并使用go tool pprof cpu.out来查看文件:
在这里插入图片描述
注意到,输入命令后可以在命令行进行交互,输入 web,可以在 html 输出一个可视化的结果:
在这里插入图片描述
这里遇到了一个坑,在第一次输入 web 的时候,会报错,提示failed to execute dot. Is Graphviz installed? Error: exec: "dot": executable file not found in %PATH%,在查找资料后发现,需要安装 Graphviz 库,并导入到环境变量,具体做法参考了https://blog.csdn.net/June_hjx/article/details/105520532。需要注意的两个点是:

  • 即使在 .exe 安装包选择了导入到环境变量,也要去检查一下环境变量;
  • 安装并导入环境变量之后,应该重启 IDE。

在可视化结果当中,方框越大、线越粗,代表所花费的时间越多(联想到可以通过可视化工具来检查哪部分代码还需要优化)。


http://www.kler.cn/a/429366.html

相关文章:

  • LLMs之RAG:《EdgeRAG: Online-Indexed RAG for Edge Devices》翻译与解读
  • Autodl转发端口,在本地机器上运行Autodl服务器中的ipynb文件
  • Agent一键安装,快速上手Zabbix监控!
  • DHCP详解和部署
  • .NET 9.0 的 Blazor Web App 项目中 Hash 变换(MD5、Pbkdf2) 使用备忘
  • R5天气识别学习笔记
  • 字符串知识
  • C语言专题之结构体的使用
  • 锐捷网络设备常用命令(交换机、路由器)
  • “掌握AWD:解密全轮驱动的终极性能“
  • amazon亚马逊滑动识别验证码
  • Python Web 开发:FastAPI 依赖注入与中间件应用
  • PHP期末复习(通过30道填空题梳理知识点)
  • 十六,Spring Boot 整合 Druid 以及使用 Druid 监控功能
  • 零基础微信小程序开发——WXML 模板语法之事件绑定(保姆级教程+超详细)
  • 嵌入式驱动开发详解4(内核定时器)
  • sessionStorage对象--JSON数组--使用花括号{}直接定义对象--丝滑小连招:----客户端缓存之一
  • 【linux】shell(32)-循环控制
  • C#导出数据库到Excel文件(.NET)
  • Mac Open in terminal 总是打开vscode
  • 计算机网络-IPSec VPN工作原理
  • ejb组件(rmi) webservice平台(xml)
  • ChatUI使用.引导<基于react使用><全网唯一>
  • C++中的多线程及其之后的周边
  • XML与HTML的区别汇总
  • 【TensorFlow】基本概念:张量、常量、变量、占位符、计算图