Go单元测试基础
Go单元测试基础
- 1.go test工具
- 2.单元测试函数
- 3.go test -v/go test -run
- 4.跳过某些测试用例
- 5.子测试
- 6.表格驱动测试
- 7.并行测试
- 8.使用工具生成测试代码
- 9.测试覆盖率
1.go test工具
Go语言中的测试依赖go test
命令。编写测试代码和编写普通的Go代码过程是类似的,并不需要学习新的语法、规则或工具。
go tes
t命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以_test.go
为后缀名的源代码文件都是go test
测试的一部分,不会被go build
编译到最终的可执行文件中。
在*_test.go
文件中有三种类型的函数,单元测试函数、基准测试函数和示例函数。
go test
命令会遍历所有的*_test.go
文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。
2.单元测试函数
每个测试函数必须导入testing包,测试函数的基本格式(签名)如下:
func TestName(t *testing.T){// ...
}
测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头,举几个例子:
func TestAdd(t *testing.T){ ... }
func TestSum(t *testing.T){ ... }
func TestLog(t *testing.T){ ... }
其中参数t用于报告测试失败和附加的日志信息。 testing.T的拥有的方法如下:
func (c *T) Cleanup(func())
func (c *T) Error(args ...interface{})
func (c *T) Errorf(format string, args ...interface{})
func (c *T) Fail()
func (c *T) FailNow()
func (c *T) Failed() bool
func (c *T) Fatal(args ...interface{})
func (c *T) Fatalf(format string, args ...interface{})
func (c *T) Helper()
func (c *T) Log(args ...interface{})
func (c *T) Logf(format string, args ...interface{})
func (c *T) Name() string
func (c *T) Skip(args ...interface{})
func (c *T) SkipNow()
func (c *T) Skipf(format string, args ...interface{})
func (c *T) Skipped() bool
func (c *T) TempDir() string
实例:
package mainfunc sum(x, y int) int {return x + y
}
在当前目录下,我们创建一个danyuan_test.go
的测试文件,并定义一个测试函数如下:
package mainimport ("reflect""testing"
)func TestDanyuan(t *testing.T) {sum := Sum(10, 20) // 程序输出的结果want := 30 // 期望的结果if !reflect.DeepEqual(want, sum) { // 因为slice不能比较直接,借助反射包中的方法比较t.Errorf("expected:%v,got:%v", want, sum) // 测试失败输出错误提示}
}
在当前路径下执行go test
命令,可以看到输出结果如下:
3.go test -v/go test -run
一个测试用例有点单薄,我们再编写一个测试:
func TestDanyuanTwo(t *testing.T) {sum := Sum(-20, -30)want := -50if !reflect.DeepEqual(want, sum) { // 因为slice不能比较直接,借助反射包中的方法比较t.Errorf("expected:%v,got:%v", want, sum) // 测试失败输出错误提示}
}
现在我们有多个测试用例了,为了能更好的在输出结果中看到每个测试用例的执行
情况,我们可以为go test
命令添加-v
参数,让它输出完整的测试结果
都通过了:
假设有不通过的,会提示我们:
在执行go test
命令的时候可以添加-run
参数,它对应一个正则表达式,只有函数名匹配上的测试函数才会被go test
命令执行
例如通过给go test
添加-run=Two
参数来告诉它本次测试只运行第二个这个测试用例:
4.跳过某些测试用例
为了节省时间支持在单元测试时跳过某些耗时的测试用例
func TestTimeConsuming(t *testing.T) {if testing.Short() {t.Skip("short模式下会跳过该测试用例")}...
}
当执行go test -short
时就不会执行上面的TestTimeConsuming测试用例
5.子测试
通常单元测试中需要多组测试数据保证测试的效果
Go1.7+中新增了子测试,支持在测试函数中使用t.Run
执行一组测试用例,这样就不需要为不同的测试数据定义多个测试函数了,例如:
func TestDanyuan(t *testing.T) {t.Run("case1", func(t *testing.T) {sum := Sum(-20, -30)want := -50if !reflect.DeepEqual(want, sum) { // 因为slice不能比较直接,借助反射包中的方法比较t.Errorf("expected:%v,got:%v", want, sum) // 测试失败输出错误提示}})t.Run("case2", func(t *testing.T) {sum := Sum(20, 30)want := 50if !reflect.DeepEqual(want, sum) { // 因为slice不能比较直接,借助反射包中的方法比较t.Errorf("expected:%v,got:%v", want, sum) // 测试失败输出错误提示}})t.Run("case3", func(t *testing.T) {sum := Sum(-20, 30)want := 10if !reflect.DeepEqual(want, sum) { // 因为slice不能比较直接,借助反射包中的方法比较t.Errorf("expected:%v,got:%v", want, sum) // 测试失败输出错误提示}})
}
6.表格驱动测试
表格驱动测试不是工具、包或其他任何东西,它只是编写更清晰测试的一种方式和视角。
编写好的测试并非易事,但在许多情况下,表格驱动测试可以涵盖很多方面:表格里的每一个条目都是一个完整的测试用例,包含输入和预期结果,有时还包含测试名称等附加信息,以使测试输出易于阅读。
使用表格驱动测试能够很方便的维护多个测试用例,避免在编写单元测试时频繁的复制粘贴。
表格驱动测试的步骤通常是定义一个测试用例表格,然后遍历表格,并使用t.Run
对每个条目执行必要的测试。
例如我们针对上面的程序进行表格驱动测试:
package mainimport ("reflect""strconv""testing"
)/*
表格驱动测试
*/
func TestDanyuan(t *testing.T) {var danyuantests = []struct {in intout intwant int}{{10, 20, 30},{-30, 40, 10},{-55, -55, -110},{13131313, 14141414, 27272727},}// 遍历测试用例for _, tt := range danyuantests {t.Run(strconv.Itoa(tt.in), func(t *testing.T) { // 使用t.Run()执行子测试sum := Sum(tt.in, tt.out)if !reflect.DeepEqual(sum, tt.want) {t.Errorf("expected:%#v, got:%#v", tt.want, sum)}})}
}
在终端执行go test -v
,会得到如下测试输出结果:
> go test -v
=== RUN TestDanyuan
=== RUN TestDanyuan/10
=== RUN TestDanyuan/-30
=== RUN TestDanyuan/-55
=== RUN TestDanyuan/13131313
--- PASS: TestDanyuan (0.00s)--- PASS: TestDanyuan/10 (0.00s)--- PASS: TestDanyuan/-30 (0.00s)--- PASS: TestDanyuan/-55 (0.00s)--- PASS: TestDanyuan/13131313 (0.00s)
PASS
ok Go-Page 0.042s
7.并行测试
想要在单元测试过程中使用并行测试,可以像下面的代码示例中那样通过添加t.Parallel()
来实现
package mainimport ("reflect""strconv""testing"
)/*
表格驱动测试
*/
func TestDanyuan(t *testing.T) {var danyuantests = []struct {in intout intwant int}{{10, 20, 30},{-30, 40, 10},{-55, -55, -110},{13131313, 14141414, 27272727},}// 遍历测试用例for _, tt := range danyuantests {t.Run(strconv.Itoa(tt.in), func(t *testing.T) { // 使用t.Run()执行子测试t.Parallel() // 将每个测试用例标记为能够彼此并行运行sum := Sum(tt.in, tt.out)if !reflect.DeepEqual(sum, tt.want) {t.Errorf("expected:%#v, got:%#v", tt.want, sum)}})}
}
8.使用工具生成测试代码
社区里有很多自动生成表格驱动测试函数的工具,比如gotests等,很多编辑器如Goland也支持快速生成测试文件。这里简单演示一下gotests的使用
安装
go get -u github.com/cweill/gotests/...
执行(待测试的文件为mul.go)
gotests -all -w mul.go
9.测试覆盖率
测试覆盖率是指代码被测试套件覆盖的百分比。通常我们使用的都是语句的覆盖率,也就是在测试中至少被运行一次的代码占总代码的比例。在公司内部一般会要求测试覆盖率达到80%左右
Go提供内置功能来检查你的代码覆盖率,即使用go test -cover
来查看测试覆盖率
此处可以看到覆盖率是50%,原因是有一个函数我们没有对它添加单元测试
版权声明:本文教程基于李文周的Go语言博客
相关文章:

Go单元测试基础
Go单元测试基础1.go test工具2.单元测试函数3.go test -v/go test -run4.跳过某些测试用例5.子测试6.表格驱动测试7.并行测试8.使用工具生成测试代码9.测试覆盖率1.go test工具 Go语言中的测试依赖go test命令。编写测试代码和编写普通的Go代码过程是类似的,并不需…...
华为OD机试 -执行时长(Java) | 机试题+算法思路+考点+代码解析 【2023】
执行时长 题目 为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务,假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成 输入描述: 第一个…...

互联网检测服务器
互联网检测服务器 1. 题目要求2. 试题解析1. 题目要求 题目: 为了模拟 Internet 访问测试,请搭建网卡互联网检测服务。 2. 试题解析 根据windows的官方文档,互联网检测服务有专门的域名,通过注册表可以找到检测域名字符串的写法(字符串为www.msftconnecttest.com),具体位…...
YOLO系列模型改进指南
YOLO系列模型改进指南 目前包含yolov5,yolov7,yolov8模型的众多改进方案,效果因数据集和参数而定,仅供参考。 如果需要改进模型,建议baseline和改进模型也不要载入预训练权重,不然的话,他们的起…...
QML- 在QML定义JavaScript资源
在QML定义JavaScript资源一、概述二、后台代码实现文件三、共享JavaScript资源(库)一、概述 QML应用程序的一部分程序逻辑可以用 JavaScript 定义。JavaScript代码可以在QML文档中内联定义,也可以分离到单独的 JavaScript 文件中(在QML中称为JavaScript资源)。 QML…...

php(tp框架)使用七牛云对象存储
图片文件存服务器非常占用存储带宽资源,且用户访问体验也不佳,因此使用一些第三方oss存储就很有必要了。之前lz发布了一篇tp使用阿里云oss的博文。不过阿里oss是收费的。而七牛云提供了一些免费使用额度。所以,这里额外补充一篇。 1.前提准备…...

八大排序算法之插入排序+希尔排序
目录 一.前言(总体简介) 关于插入排序 关于希尔排序: 二.插入排序 函数首部: 算法思路: 算法分析 插入排序代码实现: 插入排序算法的优化前奏: 三.希尔排序(缩小增量排序) 1.算法思想: 2.算法拆分解析 序列分组 分组预排序: 分组预排序的另一种实现方式: 希尔…...

蓝桥杯第十四届蓝桥杯模拟赛第三期考场应对攻略(C/C++)
这里把我的想法和思路写出来,恳请批评指正! 目录 考前准备 试题1: 试题2: 试题3: 试题4: 试题5: 试题6: 试题7: 试题8: 试题9: 试题1…...

【数论】最大公约数、约数的个数与约数之和定理
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
第28篇:Java日期Calendar类总结(二)
目录 1、获取系统当前时间 2、获取指定日期 3、对象字段类型 4 、对象信息设置 4.1 Set设置...

【Python】字符串 - 集大成篇
目录 1. 不同语言的字符串比较 1.1 C 语言 1.2 C 语言 1.2.1 C 风格字符串 1.2.2 C 风格字符串 1.3 JAVA 1.4 Python 2. Python 字符串 2.1 方法 2.2.1 title () 2.2.2 lower () 2.2.3 upper () 2.2.4 rstrip () 2.2.5 lstrip …...

IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤
IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤 、 文章目录IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤IDEA 导入项目模块 Module一. 创建一个空项目二. 导入 Module三. 将 Module 与 当前项目关联上IDEA 将 Java程序打包成…...

算法的效率——时间复杂度和空间复杂度
文章目录1. 算法效率1.1 什么是算法1.2 算法的好坏2. 时间复杂度2.1 什么是时间复杂度2.2 时间复杂度的计算方法2.3 大O的渐进表示法2.4 常见时间复杂度计算举例3. 空间复杂度4. 常见复杂度对比1. 算法效率 1.1 什么是算法 目前普遍认可对算法的定义是:算法是解决…...

2021年 第12届 蓝桥杯 Java B组 省赛真题详解及小结【第1场省赛 2021.04.18】
总分:5 一、试题A:ASC 得分:5分 本题总分:5 分 【问题描述】 已知大写字母 A 的 ASCII 码为 65,请问大写字母 L 的 ASCII 码是多少? 【答案提交】 这是一道结果填空的题,你只需要算出结果后提…...

透过等待看数据库
等待分类与解决基本流程步骤1.定位问题系统等待往往能直观的反映出系统问题。通过一些常见的等待类型,同样可以找到系统瓶颈,结合性能计数器往往定位更准确。如:系统中存在大量IO类等待,那么可能表示你的磁盘或内存是语句运行缓慢…...

中科亿海微FPGA
国产FPGA中,紫光、安路、高云称得上是三小龙,其他的半斤八两,中科亿海微也算是其中之一。 其产品为亿海神针系列,如下: 可见其最小规模也有9.2KLUT,最大竟有136K之多了,对比其他国产࿰…...

【链表OJ题(三)】链表中倒数第k个结点
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(三)1. 链表…...

华为防火墙的学习
防火墙 - 含义和定义 什么是防火墙? 防火墙的工作原理 防火墙的区域: 包过滤防火墙----访问控制列表技术---三层技术 代理防火墙----中间人技术---应用层 状态防火墙---会话追踪技术---三层、四层 UTM---深度包检查技术----应用层 下一代防火墙 防火墙的…...

SPI 接口OLED 模块 - 兼容5V 和3.3V 电平
PCB 布局参考了老王0.8元128x32OLED显示屏转接板,开源项目地址:老王0.8元128x32OLED。 老王家买的屏幕放了快一年了,终于还是决定整个单独的模块,之前一直打算集成到开发板上的,不太灵活。相比那个转接板,主…...
css布局和定位
在Web开发中,CSS布局和定位是非常重要的技能。在这篇博客中,我们将深入探讨CSS布局和定位的概念、基本技术和最佳实践。 **CSS布局基础** ├── 盒模型 │ ├── 内边距 │ │ ├── padding │ │ ├── padding-top │ │ ├── p…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...