go test单元测试详解

news2024/11/19 13:39:18

目录

介绍&测试范围

测试函数

执行机制

常用执行模式

子测试

帮助函数Helper()

测试覆盖率


 

介绍&测试范围

go test测试是go自带的测试工具,主要包括单元测试和性能测试两大类。

包括了工程目录下所有以_test.go为后缀名的源代码文件,这些文件在编译时不会被编译到最终的可执行文件中。

测试函数

命名
        一般是以Test开头再加自定义函数名

正常:TestAnd

错误:Testand

参数
        测试函数参数只有一个,普通的单元测试均为*testing.T,参数如果不对则会提示:Wrong test signature

        可允许的参数类型如:

    *testing.T:普通单元测试
    *testing.B:benchmark基准测试,一般用于测试性能
    *testing.M:测试主函数,在运行指定测试函数之前首先运行测试文件中的func TestMain(m *testing.M),TestMain运行在主goroutine中。

如待测函数为Add:

func Add(a int, b int) int {
    return a + b
}

func TestAdd(t *testing.T) {
    if result := Add(1, 2); result != 3 {
        t.Errorf("1 + 2 = 3, not %d", result)
    }

    if result := Add(-1, -2); result != -3 {
        t.Errorf("-1 + -2 = -3, not %d", result)
    }
}

执行机制

go test过程首先扫描*_test.go的文件,会生成一个临时的main包用于调用相应的测试函数,然后构建、运行、产生测试结果,最后清理测试中生成的临时文件。

常用执行模式

1、仅运行一个测试函数

go test -run TestAdd

2、运行一个包下所有的测试函数

根目录下运行指定包

go test awesomeProject/testt 

或进入指定包下再执行

go test -v

其中 -v用于显示具体用例测试结果,不是必须的

注意,当有两个测试函数 TestAdd、TestAdd0时,执行go test -run TestAdd会将这两个都进行测试。

测试打印

测试函数与其它go函数一样都是函数,可使用fmt、log等进行打印,但参数t自带了常用的打印方法:

    // 打印日志
    t.Log()
    t.Logf()
    
    // 打印错误,遇到错误终止执行
    t.Fatal()
    t.Fatalf()
    
    // 打印错误,遇到错误继续执行
    t.Error()
    t.Errorf()

子测试

子测试是指在测试场景下允许使用t.Run来创建不同的子测试用例。

举例如下:

func TestAdd(t *testing.T) {
    testsAdd := []struct {
        a, b int
        want int
    }{
        {0, 1, 1},
        {1, 2, 3},
        {2, 2, 4},
        {0, -1, -1},
        {-3, 4, 1},
        {-3, 1, -2},
        {-1, -1, -2},
        {-1, -2, -3},
    }

    for _, tt := range testsAdd {
        t.Run("", func(t *testing.T) {
            if got := Add(tt.a, tt.b); got != tt.want {
                t.Errorf("Add(%d,%d) = %d, want %d", tt.a, tt.b, got, tt.want)
            }
        })
    }
}

这种写法直观、清晰,新增用例方便、格式统一。用例正常时结果如下:

PASS
ok      awesomeProject/testt    0.754s

若将第一个用例写错模拟Add函数问题,结果如下:

--- FAIL: TestAdd (0.00s)
    --- FAIL: TestAdd/#00 (0.00s)
        f_test.go:35: Add(0,1) = 1, want 2
FAIL
exit status 1
FAIL    awesomeProject/testt    0.669s

帮助函数Helper()

改造上述测试函数,设定写法如下:

func TestAddWithHelper(t *testing.T) {
    type model struct {
        a, b int
        want int
    }

    execRun := func(t *testing.T, tt model) {
        // t.Helper()
        if got := Add(tt.a, tt.b); got != tt.want {
            t.Errorf("Add(%d,%d) = %d, want %d", tt.a, tt.b, got, tt.want)  // 52行
        }
    }

    execRun(t, model{a: 0, b: 1, want: 0})  // 56行 设定错误,模拟测试不通过
    execRun(t, model{a: 1, b: 2, want: 3})
}

多个自定义execRun在执行时都有出问题的可能,对于上述代码,当不加t.Helper()时提示如下:

--- FAIL: TestAddWithHelper (0.00s)
    f_test.go:52: Add(0,1) = 1, want 0
FAIL
FAIL    awesomeProject/testt    0.707s
FAIL

可以看到是t.Errorf这一行,不是特别直观,下面加上t.Helper(),结果如下:

--- FAIL: TestAddWithHelper (0.00s)
    f_test.go:56: Add(0,1) = 1, want 0
FAIL
FAIL    awesomeProject/testt    0.743s
FAIL

可以看到直接提示是56行的问题。

测试覆盖率

go test awesomeProject/testt -run TestAdd0 -cover

其中-cover测试表示本次测试启用覆盖率检测。

覆盖率的含义是,代码被测试套件覆盖的百分比,即测试中至少被运行一次的代码占总代码的比例。

将覆盖率结果生成报告:

go test awesomeProject/testt -run TestAdd0 -cover -coverprofile=a

如上,-coverprofile=a 参数会将覆盖率信息输出到文件a中,接着使用go tool调用本地浏览器来生成一个html格式的报告:

go tool cover -html=a

效果如下 

77b55392177d4665bcbeb85dccffde80.png

加函数测试了,减函数未测试。 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1434898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 语法文件

程序运行时产生的数据都属于临时数据,程序结束就会被释放。 通过文件可以可以将数据持久化 c中对文件操作需要包含头文件fstream 文件的类型分为两种 1.文本文件 文件以文本的ASCII码形式存储在计算机中 2.二进制文件 稳重以文本的二进制形式存储在计算机中 用…

基于idea解决springweb项目的Java文件无法执行问题

前言 上一篇文章的话介绍了spring以及创建spring项目,但是因为有宝子私聊我说创建的项目那个JAVA文件显示灰色还有一个红点,问我怎么解决下面我来简答的写一下怎么修改配置让他正常的运行 配置 原因好像是因为基于maven的JAVA项目构架,对应…

Android Studio中打开文件管理器

文章目录 一、前言二、操作步骤 一、前言 在Android Studio中有时候需要查看手机的文件目录或者复制文件,但是有时候文件管理器找不到在哪,这里记录该操作流程 二、操作步骤 第一步: 第二步: 第三步:

CentOS7搭建k8s-v1.28.6集群详情

文章目录 1.灌装集群节点操作系统1.1 设置hosts1.2 设置nameserver1.3 关闭防火墙1.4 关闭Selinux1.5 关闭Swap分区1.6 时间同步1.7 调整内核参数1.8 系统内核升级 2.安装Docker2.1 卸载旧Docker2.2 配置Docker软件源2.3 安装Docker 3.部署Kubernets集群3.1 设置 K8s 软件源3.2…

51单片机 跑马灯

#include <reg52.h>//毫秒级延时函数 void delay(int z) {int x,y;for(x z; x > 0; x--)for(y 114; y > 0 ; y--); }sbit LED1 P1^0x0; sbit LED2 P1^0x1; sbit LED3 P1^0x2; sbit LED4 P1^0x3; sbit LED5 P1^0x4; sbit LED6 P1^0x5; sbit LED7 P1^0x6; s…

属性“xxxx”在类型“ArrayConstructor”上不存在。是否需要更改目标库? 请尝试将 “lib” 编译器选项更改为“es2015”或更高版本。

使用vscode编写vue&#xff0c;在使用elementUI时&#xff0c;发现代码中的form报错如下&#xff1a; 属性“form”在类型“ArrayConstructor”上不存在。是否需要更改目标库? 请尝试将 “lib” 编译器选项更改为“es2015”或更高版本。 解决方法&#xff1a; 打开jsconfig.…

如何配置SSH实现无公网ip远程连接访问Deepin操作系统

&#x1f4d1;前言 本文主要是配置SSH实现无公网ip远程连接访问Deepin操作系统的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️** &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &…

【防止重复提交】Redis + AOP + 注解的方式实现分布式锁

文章目录 工作原理需求实现1&#xff09;自定义防重复提交注解2&#xff09;定义防重复提交AOP切面3&#xff09;RedisLock 工具类4&#xff09;过滤器 请求工具类5&#xff09;测试Controller6&#xff09;测试结果 工作原理 分布式环境下&#xff0c;可能会遇到用户对某个接…

有趣的CSS - 按钮文字上下滑动

目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页面渲染效果 整体效果 这个按钮效果主要使用 :hover 伪选择器以及 transition 过渡属性来实现两个子元素上下过渡的效果。 此效果可以在主入口按钮、详情或者更多等按钮处使用&#xff0c;增加一些鼠…

Express框架介绍—node.js

Express—Node.js 官网传送门(opens new window) 基于 Node.js 平台&#xff0c;快速、开放、极简的 Web 开发框架 Express 是用于快速创建服务器的第三方模块。 Express 初体验 基本使用 安装 Express&#xff1a; npm install express创建服务器&#xff0c;监听客户端请…

前端实现搜索框筛选

效果图 页面解析 是一个input输入框和一个button按钮组成输入框查询 内容是一个折叠面板 html代码 <div class"left-content-box"><div class"colum-search"><el-input v-model"columKey" clearable placeholder"请输入关…

第二届 N1CTF Junior Crypto-junior RSA WP

题目&#xff1a; from Crypto.Util.number import * from secret import flagm bytes_to_long(flag)def gen(bits):while True:a getPrime(bits)b getPrime(bits)c getPrime(bits)p (a << (2*bits)) (b << bits) cq (c << (2*bits)) (a << …

Day4.

单链表 #include <head.h>typedef struct List{int value;struct List *pointe; }*list; list create_space() {list s(struct List *)malloc(sizeof(struct List)); //向堆区申请空间s->pointe NULL;//初始化s->value 0;return s; } list inserhead_list(lis…

问题排查利器 - 分布式 trace

在分布式系统开发中&#xff0c;系统间的调用往往会横跨多个应用之间的接口。负责的调用链路也导致了&#xff0c;当线上环境出现问题时&#xff0c;例如请求失败、延迟增加或错误发生&#xff0c;我们无法第一时间确定是哪个环节出了问题&#xff0c;这给故障排查和修复带来了…

Spring Data Envers 数据审计实战

随着各行各业信息化发展&#xff0c;决策者们越来越意识到数据版本追踪的重要性&#xff0c;尤其是上市公司&#xff0c;数据对于他们尤为重要。考虑到研发成本&#xff0c;对重要表单数据支持页面级的修改历史查看、对所有业务数据支持DB级的版本查看是一个不错的选择。 对于…

基于OpenCV灰度图像转GCode的斜向扫描实现

基于OpenCV灰度图像转GCode的斜向扫描实现基于OpenCV灰度图像转GCode的斜向扫描实现 引言激光雕刻简介OpenCV简介实现步骤 1.导入必要的库2. 读取灰度图像3. 图像预处理4. 生成GCode5. 保存生成的GCode6. 灰度图像斜向扫描代码示例 总结 系列文章 ⭐深入理解G0和G1指令&…

通过遵循最佳做法来提高 EDA 和 HPC 应用程序的 Azure NetApp 文件性能

介绍 Azure NetApp 文件是一项托管存储解决方案&#xff0c;适用于各种方案&#xff0c;包括高性能计算 (HPC) 基础结构。 低延迟和每秒高 I/O 操作数 (IOPS) 对于大规模企业而言是一种很好的组合。 假设你就职于一家半导体公司。 你的任务是设计公司的集成电路芯片&#xff…

问题:塑瓷后的牙冠要比完成的牙冠大() #学习方法#其他

问题&#xff1a;塑瓷后的牙冠要比完成的牙冠大&#xff08;&#xff09; A.10% B.10%-15% C.15%-20% D.20%-30% E.50% 参考答案如图所示

mysql8通过binlog恢复数据

参考资料: 通过binlog恢复误update的数据(一)_binlog 恢复update-CSDN博客 记录一次工作中的误删除&#xff0c;使用binlog恢复数据的问题。 1&#xff1a;找到mysql8的binlog文件。 2&#xff1a;把binlog文件转换为初始sql文件 mysqlbinlog -vv --base64-outputdecode-row…

【CSS】什么是BFC?BFC有什么作用?

【CSS】什么是BFC&#xff1f;BFC有什么作用&#xff1f; 一、BFC概念二、触发BFC三、BFC特性即应用场景1、解决margin塌陷的问题2、避免外边距margin重叠&#xff08;margin合并&#xff09;3、清除浮动4、阻止元素被浮动元素覆盖 一、BFC概念 BFC(block formatting context)…