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

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 test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以_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之多了,对比其他国产&#xff0…...

【链表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…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

无法与IP建立连接,未能下载VSCode服务器

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

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

免费数学几何作图web平台

光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...