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

用GoConvey编写单元测试的一些总结

一、尽量用Convey将所有测试用例的Convey汇总

用Convey嵌套的方法,将所有测试用例的Convey用一个大的Convey包裹起来,每个测试函数下只有一个大的Convey。比如下面的示例代码:

import ("testing". "github.com/smartystreets/goconvey/convey"
)func TestStringSliceEqual(t *testing.T) {Convey("TestStringSliceEqual", t, func() {Convey("should return true when a != nil  && b != nil", func() {a := []string{"hello", "goconvey"}b := []string{"hello", "goconvey"}So(StringSliceEqual(a, b), ShouldBeTrue)})Convey("should return true when a == nil  && b == nil", func() {So(StringSliceEqual(nil, nil), ShouldBeTrue)})Convey("should return false when a == nil  && b != nil", func() {a := []string(nil)b := []string{}So(StringSliceEqual(a, b), ShouldBeFalse)})Convey("should return false when a != nil  && b != nil", func() {a := []string{"hello", "world"}b := []string{"hello", "goconvey"}So(StringSliceEqual(a, b), ShouldBeFalse)})})
}

这样做的好处是,看单测结果更为清晰直观:

=== RUN   TestStringSliceEqualTestStringSliceEqual should return true when a != nil  && b != nil ✔should return true when a == nil  && b == nil ✔should return false when a == nil  && b != nil ✔should return false when a != nil  && b != nil ✔4 total assertions--- PASS: TestStringSliceEqual (0.00s)
PASS
ok      infra/alg       0.006s

二、用GWT结构来描述复杂的测试用例

GWT结构嵌套了三层Convey:最外层是Given层,用来给定测试用例需要的数据;中间一层是When层,用来执行被测试的函数方法,得到result;最内层是Then层,用So来对result进行断言,看结果是否满足期望。

1 示例代码

示例代码如下:

func TestStringSliceEqualIfBothNil(t *testing.T) {Convey("Given two string slice which are both nil", t, func() {var a []string = nilvar b []string = nilConvey("When the comparision is done", func() {result := StringSliceEqual(a, b)Convey("Then the result should be true", func() {So(result, ShouldBeTrue)})})})
}func TestStringSliceNotEqualIfNotBothNil(t *testing.T) {Convey("Given two string slice which are both nil", t, func() {a := []string(nil)b := []string{}Convey("When the comparision is done", func() {result := StringSliceEqual(a, b)Convey("Then the result should be false", func() {So(result, ShouldBeFalse)})})})
}func TestStringSliceNotEqualIfBothNotNil(t *testing.T) {Convey("Given two string slice which are both not nil", t, func() {a := []string{"hello", "world"}b := []string{"hello", "goconvey"}Convey("When the comparision is done", func() {result := StringSliceEqual(a, b)Convey("Then the result should be false", func() {So(result, ShouldBeFalse)})})})
}

在实际运用中,可以结合第一条方法构成四层嵌套来描述一个测试用例:

func TestStringSliceEqual(t *testing.T) {Convey("TestStringSliceEqualIfBothNotNil", t, func() {Convey("Given two string slice which are both not nil", func() {a := []string{"hello", "goconvey"}b := []string{"hello", "goconvey"}Convey("When the comparision is done", func() {result := StringSliceEqual(a, b)Convey("Then the result should be true", func() {So(result, ShouldBeTrue)})})})})Convey("TestStringSliceEqualIfBothNil", t, func() {Convey("Given two string slice which are both nil", func() {var a []string = nilvar b []string = nilConvey("When the comparision is done", func() {result := StringSliceEqual(a, b)Convey("Then the result should be true", func() {So(result, ShouldBeTrue)})})})})Convey("TestStringSliceNotEqualIfNotBothNil", t, func() {Convey("Given two string slice which are both nil", func() {a := []string(nil)b := []string{}Convey("When the comparision is done", func() {result := StringSliceEqual(a, b)Convey("Then the result should be false", func() {So(result, ShouldBeFalse)})})})})Convey("TestStringSliceNotEqualIfBothNotNil", t, func() {Convey("Given two string slice which are both not nil", func() {a := []string{"hello", "world"}b := []string{"hello", "goconvey"}Convey("When the comparision is done", func() {result := StringSliceEqual(a, b)Convey("Then the result should be false", func() {So(result, ShouldBeFalse)})})})})}

 2 大坑

注意!Given层中最好只有一个Then,因为多个Then会导致每执行完一个Then就会再次执行一遍被测试的函数方法,导致多次执行的结果可能并不相同从而导致意料之外的错误(比如上面示例中的“result := StringSliceEqual(a, b)”)。所以如果选择使用GWT的结构,那么就要保证W中只有一个T,最好也要保证G中只有一个W。

三、自定义断言函数

断言函数So中第二个参数Assertion类型定义:

type Assertion func(actual interface{}, expected ...interface{}) string

返回空字符串表示断言成功,否则就是断言失败了。

1 自定义断言函数

所以我们自定义断言函数时也要注意这点,下面是一个参考示例:

func ShouldSummerBeComming(actual interface{}, expected ...interface{}) string {if actual == "summer" && expected[0] == "comming" {return ""} else {return "summer is not comming!"}
}

上述代码中,第一个条件表示断言成功,其它所有情况都是断言失败。

2 在So中使用自定义的断言函数

func TestSummer(t *testing.T) {Convey("TestSummer", t, func() {So("summer", ShouldSummerBeComming, "comming")So("winter", ShouldSummerBeComming, "comming")})
}

测试结果:

=== RUN   TestSummerTestSummer ✔✘Failures:* /Users/zhangxiaolong/Desktop/D/go-workspace/src/infra/alg/slice_test.go Line 52:summer is not comming!2 total assertions--- FAIL: TestSummer (0.00s)
FAIL
exit status 1
FAIL    infra/alg       0.006s

相关文章:

用GoConvey编写单元测试的一些总结

一、尽量用Convey将所有测试用例的Convey汇总 用Convey嵌套的方法,将所有测试用例的Convey用一个大的Convey包裹起来,每个测试函数下只有一个大的Convey。比如下面的示例代码: import ("testing". "github.com/smartystreet…...

Linux Arm64修改页表项属性

文章目录 前言一、获取pte1.1 pgd_offset1.2 pud_offset1.3 pmd_offset1.4 pte_offset_kernel 二、修改pte属性2.1 set/clear_pte_bit2.2 pte_wrprotect2.3 pte_mkwrite2.4 pte_mkclean2.5 pte_mkdirty 三、set_pte_at四、__flush_tlb_kernel_pgtable五、demo参考资料 前言 在…...

elasticsearch14-高亮

个人名片: 博主:酒徒ᝰ. 个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来。 本篇励志:三人行,必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud…...

HUAWEI华为MateBook X Pro 2021款 i7 集显(MACHD-WFE9Q)原装出厂Win10系统20H2

华为笔记本电脑原厂系统自带指纹驱动、显卡驱动、声卡驱动、网卡驱动等所有驱动、出厂主题壁纸、系统属性华为专属LOGO标志、Office办公软件、华为电脑管家等预装程序 链接:https://pan.baidu.com/s/1oeSM0ciwyyRIKms5tR4SNA?pwdo2gq 提取码:o2gq...

21天学会C++:Day9----初识类与对象

CSDN的uu们,大家好。这里是C入门的第九讲。 座右铭:前路坎坷,披荆斩棘,扶摇直上。 博客主页: 姬如祎 收录专栏:C专题 目录 1. 面向过程与面向对象 2. 类的定义 3. 类中的访问限定符 3.1 访问限定符的…...

【深度学习】 Python 和 NumPy 系列教程(十七):Matplotlib详解:2、3d绘图类型(3)3D条形图(3D Bar Plot)

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 0. 设置中文字体 1. 线框图 2. 3D散点图 3. 3D条形图(3D Bar Plot) 一、前言 Python是一种高级编程语言,由Guido van Rossum于1991年创建。它以简洁、易读…...

基于Spring Boot+vue的酒店管理系统

文章目录 项目介绍主要功能截图:前台后台部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于Spring Boot+vue的酒店管理…...

Python 通过threading模块实现多线程

视频版教程 Python3零基础7天入门实战视频教程 我们可以使用threading模块的Thread类的构造器来创建线程 def _ init _(self, groupNone, targetNone, nameNone, args(), kwargsNone, *, daemonNone): 上面的构造器涉及如下几个参数。 group:指定该线程所属的线程组。目前该…...

用一个RecyclerView实现二级评论

先上个效果图(没有UI,将就看吧),写代码的整个过程花了4个小时左右,相比当初自己开发需求已经快了很多了哈。 给产品估个两天时间,摸一天半的鱼不过分吧(手动斜眼) 需求拆分 这种大家…...

音视频 SDL简介

一、SDL简介 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Win…...

7.前端·新建子模块与开发(自动生成)

文章目录 学习地址视频笔记自动代码生成模式开发增删改查功能调试功能权限分配 脚本实现权限分配 学习地址 https://www.bilibili.com/video/BV13g411Y7GS/?p15&spm_id_frompageDriver&vd_sourceed09a620bf87401694f763818a31c91e 视频笔记 自动代码生成模式开发 …...

Linux 创建目录

语法:mkdir xxx Linux路径 在当前目录下创建文件夹 在/目录下创建文件夹 如果想要一次性创建多个层级的目录,如下图 会报错,因为上级目录test并不存在,所以无法创建test目录 可以通过-p选项,将一整个链条都创建完成…...

【DIY小记】修复Win10启动出现蓝屏0xc0000185错误的一些方法

近些日子想到自己尘封已久的笔记本电脑没有开机了,很多软件驱动之类的没有更新,就打算把电脑开起来做一轮批量升级。但开电脑的时候很久没有进入Win10桌面,等了很长一段时间蓝屏提示0xc0000185错误,说系统需要恢复。经历了一番折腾…...

Linux 下的 10 个 PDF 软件

本文[1]是我们正在进行的有关 Linux 顶级工具系列的延续,在本系列中,我们将向您介绍最著名的 Linux 系统开源工具。 随着互联网上越来越多地使用可移植文档格式 (PDF) 文件来获取在线书籍和其他相关文档,拥有 PDF 查看器/阅读器对于桌面 Linu…...

浅谈redis分布式锁

浅谈redis分布式锁 分布式锁介绍 分布式锁,顾名思义,分布式系统中的锁,当多个进程不在同一个系统中时,用分布式锁控制各个进程对共享资源的访问,通过互斥来保持一致性。 使用场景:电商中某商品的秒杀活动…...

【Python保姆级教程】List容器

文章目录 前言一、列表是什么二、列表的定义2.1 有初始值2.2 空列表使用方括号创建空列表使用list()函数创建空列表 三、list列表常用操作3.1 添加元素3.2 删除元素3.3 修改元素3.4 列表长度 四、遍历操作4.1 使用for循环4.2 使用while循环和索引 总结 前言 Python是一种广泛使…...

微服务保护-授权规则

个人名片: 博主:酒徒ᝰ. 个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来。 本篇励志:三人行,必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud…...

v-if失效原因

一般v-if失效都是和绑定变量有关&#xff0c;我所知道的一般有两种 1.绑定的变量为String类型或者其他类型 就是返回的变量类型与所需要的布尔类型不匹配。 <template><div><div id"container" ref"container" v-iftype></div>&l…...

Chrome 基于 Wappalyzer 查看网站所用的前端技术栈

1. 找到谷歌商店 https://chrome.google.com/webstore/search/wappalyzer?utm_sourceext_app_menu 2. 搜索 Wappalyzer 3. 添加至Chrome 4. 使用 插件 比如打开 https://www.bilibili.com/ 就可以看到其所以用的前端技术栈了...

python的装饰器

作用:在不改变原来函数的代码情况下,进行修改,或者增加函数的功能装饰器本质上就是一个闭包雏形:def wrapper(fn): wrapper: 装饰器 , fn: 目标函数def inner():# 在目标函数执行前的一些动作fn()# 在目标函数执行后的一些动作return inner #千万别加(),这里是返回一…...

P2P协议的传输艺术

TP 采用两个 TCP 连接来传输一个文件。 控制连接&#xff1a;服务器以被动的方式&#xff0c;打开众所周知用于 FTP 的端口 21&#xff0c;客户端则主动发起连接。该连接将命令从客户端传给服务器&#xff0c;并传回服务器的应答。常用的命令有&#xff1a;list——获取文件目…...

辅助驾驶功能开发-功能规范篇(21)-4-XP行泊一体方案功能规范

XPilot Parking 自动泊车系统 • 超级自动泊车辅助(Super AutoParking Assist)、语音控制泊车辅助(Autoparking with Speech) - 产品定义 超级自动泊车辅助是⼀个增强的自动泊车辅助系统。在超级自动泊车辅助系统中,识别车位将会变得实时可见, 并且不可泊入的⻋位也将…...

家政服务小程序上门服务小程序预约上门服务维修保洁上门服务在线派单技师入口

套餐一:源码=1500元 套餐二:全包服务 包服务器+域名+认证小程序+搭建+售后=2000元 主要功能: 1、服务商入驻 支持个人或企业入驻成为平台服务商; 2、发布商品 入驻服务商后,可以发布服务商品,用户可以在线下单,预约服务; 3、发布需求 用户可以发布一口价或竞价需求…...

LeetCode精选100题-【3数之和】-2

这里写自定义目录标题 解法1:解法2: 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。注意&#xff1a;答案中不…...

springboot集成mybatis-plus

一、在spring boot中配置mybatis-plus 1、创建一个spring boot项目&#xff0c;注意勾选mysql 2、在pom.xml文件中添加mybatis-plus的依赖包 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0&qu…...

再想一想GPT

一 前言 花了大概两天时间看完《这就是ChatGPT》&#xff0c;触动还是挺大的&#xff0c;让我静下来&#xff0c;认真地想一想&#xff0c;是否真正理解了ChatGPT&#xff0c;又能给我们以什么样的启发。 二 思考 在工作和生活中&#xff0c;使用ChatGPT或文心一言&#xff0c;…...

Blazor前后端框架Known-V1.2.15

V1.2.15 Known是基于C#和Blazor开发的前后端分离快速开发框架&#xff0c;开箱即用&#xff0c;跨平台&#xff0c;一处代码&#xff0c;多处运行。 Gitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;https://github.com/known/Known 概述 基于C#和Blazo…...

Tomcat 的部署和优化

目录 1、什么是Tomcat 1.1、静态页面的选择 2、Tomcat是怎么运行的 3、安装jdk &#xff06; 部署jdk环境 & Tomcat 安装 1、安装jdk 2、配置jdk环境变量 3、tomcat安装 4、Tomcat启动 5.优化tomcat启动速度 6.Tomcat的主要命令 7.Tomcat 配置虚拟主机 8.Tomca…...

后端中间件安装与启动(Redis、Nginx、Nacos、Kafka)

后端中间件安装与启动 RedisNginxNacosKafka Redis 1.打开cmd终端&#xff0c;进入redis文件目录 2.输入redis-server.exe redis.windows.conf即可启动&#xff0c;不能关闭cmd窗口 &#xff08;端口配置方式&#xff1a;redis目录下的redis.windows.conf配置文件&#xff0c;…...

【电子元件】常用电子元器件的识别之电阻器

目录 前言1. 电阻器的识别1.1 普通电阻器的识别1. 普通电阻器的识别色环电阻器绕线电阻器水泥电阻器贴片电阻器网络电阻器(排阻)保险电阻器精密电阻器2. 电阻器的符号3. 普通电阻器的主要参数标称阻值和允许误差额定功率最高工作电压温度系数1.2 电位器的识别1. 电位器的识别…...

物联网技术是学什么的/seo薪资水平

FlatBuffers是一个高性能、跨平台的序列化库&#xff0c;支持C、C#、C、Go、Java、JavaScript、TypeScript、PHP和Python。由google开发&#xff0c;并用于游戏及其他对性能要求高的应用。 1、不用解析/解包&#xff0c;就可以直接访问序列化的数据 1&#xff09;写schema文件。…...

网站如何做点击链接地址/网络推广网站排行榜

我正在尝试从电子表格中读取日期列和时间列.我可以从工作表中退出日期列,但不能退出时间列.例如,我的工作表将包含以下形式的行&#xff1a;约会时间11/2/2012 12:15:01我有以下代码来获取日期列&#xff1a;while(cellIterator.hasNext()) {HSSFCell cell (HSSFCell)cellIter…...

wordpress 代码框/防疫管控优化措施

1.字符方式读写函数fgetc( )和fputc( ) 逐个字符读写函数&#xff0c;fgetc函数实现从fp所指式的磁盘文件读入一个字符待ch。 函数调用格式&#xff1a; chfgetc(fp); //该函数的功能于getchar()函数功能相似&#xff0c;从键盘上读取一个字符&#xff1b; fgetc函数实现把…...

什么叫seo网站推广/初学者做电商怎么入手

信息系统集成有以下几个显著特点。(1)信息系统集成要以满足用户需求为根本出发点。(2)信息系统集成不只是设备选择和供应&#xff0c;更重要的&#xff0c;它是具有高技术含量的工程过程&#xff0c;要面向用户需求提供全面解决方案&#xff0c;其核心是软件。(3)系统集成的最终…...

推广网站方案/百度一下你就知道了百度

逻辑运算符短路与,短路或 1.逻辑运算符说明 a:逻辑运算符一般用于连接boolean类型的表达式或者值。 b:表达式&#xff1a;就是用运算符把常量或者变量连接起来的符合java语法的式子。 2.&&和&(遇false则false)的区别? a:最终结果一样。 b:&&具有短路效果(…...

收录软件最多的网站/深圳网络营销推广渠道

另一列中写入 IF(COUNTIF(C:C,C1)>1,"有重复","") 其余往下拖拉公式 我在想如果可以有不往下拖的呢? 不过好像筛选中也有类似的选项.转载于:https://www.cnblogs.com/vimmer/p/3445794.html...