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

Go:测试框架GoConvey 简介

快速开始

在这里插入图片描述

GoConvey是一个完全兼容官方Go Test的测试框架,一般来说这种第三方库都比官方的功能要强大、更加易于使用、开发效率更高,闲话少说,先看一个example:

package utils
import (. "github.com/smartystreets/goconvey/convey""testing"
)func TestSpec(t *testing.T) {Convey("Given some integer with a starting value", t, func() {x := 1Convey("When the integer is incremented", func() {x++Convey("The value should be greater by one", func() {So(x, ShouldEqual, 2)})})})
}

看着复杂, 一层层的嵌套,如果你使用IDE的话你可以点到源码里面看一下其方法注释,其实已经说的非常清楚了,这里摘取部分看一下:

// Convey is the method intended for use when declaring the scopes of
// a specification. Each scope has a description and a func() which may contain
// other calls to Convey(), Reset() or Should-style assertions. Convey calls can
// be nested as far as you see fit.
//
// IMPORTANT NOTE: The top-level Convey() within a Test method
// must conform to the following signature:
//
//     Convey(description string, t *testing.T, action func())
//
// All other calls should look like this (no need to pass in *testing.T):
//
//     Convey(description string, action func())

这个用法相对简单了,Convey定义了一个局部的作用域,在这个作用域里面我们可以定义变量,调用方法,然后重复继续这个操作,low-level的Convey会继承top-level的变量。

了解之后,我们来扩展一下这个例子:

func TestSpec(t *testing.T) {Convey("Given some integer with a starting value", t, func() {x := 1y := 10Convey("When the integer is incremented", func() {x++Convey("The value should be greater by one", func() {So(x, ShouldEqual, 2)})})Convey("When x < y", func() {if x < y {x = x + ySo(x, ShouldBeGreaterThan, y)}})})
}

非常简单,当然这里我们并没有测试任何函数或方法,下面咱们写一个函数真正测试一下,假设有下面的方法:

func Div(a, b int) (int, error) {if b == 0 {return 0, errors.New("can not div zero")}return a / b, nil
}

使用GoConvey的话,测试代码可以这么写:

func TestDiv(t *testing.T) {const X = 10Convey("Normal Result", t, func() {res, err := Div(X, 2)So(res, ShouldEqual, 5)So(err, ShouldBeNil)Convey("Extend Scope", func() {res, err := Div(res, 2)So(res, ShouldEqual, 2)So(err, ShouldBeNil)})})Convey("Error Result", t, func() {res, err := Div(X, 0)So(res, ShouldEqual, 0)So(err, ShouldNotBeNil)})
}

有人可能会觉得这和官方的没多大区别,相当于多加了一个注释,可以对每一个测试用例标识,但是不仅仅如此,这个库还提供了大量增强的Assertions,可以非常方便的对字符串、slice、map结果进行断言测试,具体的话可以查看一下文档或者点进去看看源码注释,这些源码注释基本上已经写的非常清楚了。

Web UI

此外,框架还提供了一个Web端的UI界面,可以非常方便的查看测试覆盖和运行情况,还可以自动运行测试,执行goconvey命令就可以启动服务,快试一试吧!(虽然说像Goland这样的IDE也提供了GUI工具查看测试覆盖率,但是这个更加方便)

另外,这个框架还提供了自定义Assertions的功能,使用起来也很方便,有一个通用的模板:

func should<do-something>(actual interface{}, expected ...interface{}) string {if <some-important-condition-is-met(actual, expected)> {return ""   // empty string means the assertion passed}return "<some descriptive message detailing why the assertion failed...>"
}

举个例子,这里定义一个试试:

func shouldNotGreatThan100(actual interface{}, expected ...interface{}) string {if actual.(int) > 100 {return "too big than 100"} else {return ""}
}

定义通用的逻辑

有时候测试会需要做一些准备工作,而且是重复的,比如说一些初始化操作,这时候就可以定义一个函数完成这件事,不必每次测试重复做,官方文档里面举了一个数据库测试的例子,每次测试前开启事务,测试结束后回滚事务,这里贴一下官方的example,大家看一下,很容易理解:

package main
import ("database/sql""testing"_ "github.com/lib/pq". "github.com/smartystreets/goconvey/convey"
)
func WithTransaction(db *sql.DB, f func(tx *sql.Tx)) func() {return func() {tx, err := db.Begin()So(err, ShouldBeNil)Reset(func() {/* Verify that the transaction is alive by executing a command */_, err := tx.Exec("SELECT 1")So(err, ShouldBeNil)tx.Rollback()})/* Here we invoke the actual test-closure and provide the transaction */f(tx)}
}
func TestUsers(t *testing.T) {db, err := sql.Open("postgres", "postgres://localhost?sslmode=disable")if err != nil {panic(err)}Convey("Given a user in the database", t, WithTransaction(db, func(tx *sql.Tx) {_, err := tx.Exec(`INSERT INTO "Users" ("id", "name") VALUES (1, 'Test User')`)So(err, ShouldBeNil)Convey("Attempting to retrieve the user should return the user", func() {var name stringdata := tx.QueryRow(`SELECT "name" FROM "Users" WHERE "id" = 1`)err = data.Scan(&name)So(err, ShouldBeNil)So(name, ShouldEqual, "Test User")})}))
}
/* Required table to run the test:
CREATE TABLE "public"."Users" ( "id" INTEGER NOT NULL UNIQUE, "name" CHARACTER VARYING( 2044 ) NOT NULL
);
*/

相关文章:

Go:测试框架GoConvey 简介

快速开始 GoConvey是一个完全兼容官方Go Test的测试框架&#xff0c;一般来说这种第三方库都比官方的功能要强大、更加易于使用、开发效率更高&#xff0c;闲话少说&#xff0c;先看一个example&#xff1a; package utils import (. "github.com/smartystreets/goconvey…...

JavaWeb-特殊文件(propertis与XML)

目录 Properties文件 一.properties介绍 二.properties使用 三.解决中文乱码问题 XML文件 一.XML介绍 二.XML文件的语法规则 三.XML的使用 Properties文件 一.properties介绍 1.什么是properties文件 Properties文件是一种常用的配置文件格式&#xff0c;用于存储键值…...

ffmpeg合并mp4视频文件

下载ffmpeg Download FFmpeg 2配置环境 右键此电脑-》属性-》高级系统设置 环境变量-》path 解压上面ffmpeg压缩包&#xff0c;找到bin目录&#xff0c;复制完整路径&#xff0c;添加到path环境变量中 测试ffmpeg ffmpeg合并MP4文件 创建一个文本文件&#xff0c;例如inpu…...

ATF BL1/BL2 ufs_read_blocks/ufs_write_blocks使用分析

ATF BL1/BL2 ufs_read_blocks/ufs_write_blocks使用分析 1 ATF的下载链接2 ATF BL1/BL2 ufs_read_blocks/ufs_write_blocks处理流程2.1 ATF BL1/BL2 ufs_read_blocks2.2 ATF BL1/BL2 ufs_write_blocks 3 UFS System Model4 ufs_read_blocks/ufs_write_blocks详细分析4.1 ufs_re…...

Elasticsearch(十二)搜索---搜索匹配功能③--布尔查询及filter查询原理

一、前言 本节主要学习ES匹配查询中的布尔查询以及布尔查询中比较特殊的filter查询及其原理。 复合搜索&#xff0c;顾名思义是一种在一个搜索语句中包含一种或多种搜索子句的搜索。 布尔查询是常用的复合查询&#xff0c;它把多个子查询组合成一个布尔表达式&#xff0c;这些…...

解决Windows下的docker desktop无法启动问题

以管理员权限运行cmd 报错&#xff1a; docker: error during connect: Post http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/containers/create: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows,…...

LLM生成式 AI 项目生命周期Generative AI project lifecycle

在本课程的其余部分中&#xff0c;您将学习开发和部署LLM驱动应用所需的技巧。在这个视频中&#xff0c;您将了解一个能帮助您完成此工作的生成式AI项目生命周期。此框架列出了从构思到启动项目所需的任务。到课程结束时&#xff0c;您应该对您需要做的重要决策、可能遇到的困难…...

java高并发系列 - 第13天:JUC中的Condition对象

java高并发系列 - 第13天:JUC中的Condition对象 java高并发系列第13篇文章 本文内容 synchronized中实现线程等待和唤醒Condition简介及常用方法介绍及相关示例使用Condition实现生产者消费者使用Condition实现同步阻塞队列Object对象中的wait(),notify()方法,用于线程等待…...

【TTY子系统】printf与printk深入驱动解析

tty子系统解析 tty子系统是一个庞大且复杂&#xff0c;也是内核维护者所头大的子系统。 At a first glance, the TTY layer wouldn’t seem like it should be all that challenging. It is, after all, just a simple char device which is charged with transferring byte-o…...

无涯教程-PHP - 全局变量函数

全局变量 与局部变量相反,可以在程序的任何部分访问全局变量。通过将关键字 GLOBAL 放置在应被识别为全局变量的前面,可以很方便地实现这一目标。 <?php$somevar15;function addit() {GLOBAL $somevar;$somevar;print "Somevar is $somevar";}addit(); ?> …...

shell脚本之循环语句

循环语句 循环含义 将某代码段重复运行多次&#xff0c;通常有进入循环的条件和退出循环的条件 for循环语句 一般知道循环次数使用for循环 第一类 格式1&#xff1a; for名称 in 取值次数;do;done; 格式2&#xff1a; for 名称 in {取值列表} do done# 打印20次 for i i…...

派森 #P122. 峰值查找

描述 给定一个长度为n的列表nums&#xff0c;请你找到峰值并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个所在位置即可。 &#xff08;1&#xff09;峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于&#xff1b; &…...

基础网络详解4--HTTP CookieSession 思考

一、cookie技术思考 一台多用户浏览器发起了三笔请求&#xff0c;将某款产品放入购物车中&#xff0c;A一次&#xff0c;选择了篮球&#xff1b;B两次&#xff0c;第一次选了足球&#xff0c;第二次选了钢笔。如何确认选择篮球、足球、钢笔的请求属于谁呢&#xff1f;如果不确认…...

14. 利用Canvas自制时钟组件

1. 说明 在自定义时钟组件时&#xff0c;使用到的基本控件主要是Canvas&#xff0c;在绘制相关元素时有两种方式&#xff1a;一种时在同一个canvas中绘制所有的部件元素&#xff0c;这样需要不断的对画笔和画布的属性进行保存和恢复&#xff0c;容易混乱&#xff1b;另一种就是…...

微信小程序使用云存储和Markdown开发页面

最近想在一个小程序里加入一个使用指南的页面&#xff0c;考虑到数据存储和减少页面的开发工作量&#xff0c;决定尝试在云存储里上传Markdown文件&#xff0c;微信小程序端负责解析和渲染。小程序端使用到一个库Towxml。 Towxml Towxml是一个可将HTML、Markdown转为微信小程…...

【C++】运算符重载 | 赋值运算符重载

Ⅰ. 运算符重载 引入 ❓什么叫运算符重载&#xff1f; 就是&#xff1a;运用函数&#xff0c;将现有的运算符重新定义&#xff0c;使其能满足各种自定义类型的运算。 回想一下&#xff0c;我们以前运算的对象是不是都是int、char这种内置类型&#xff1f; 那我们自定义的“…...

Python学习 -- 类对象从创建到常用函数

在Python编程中&#xff0c;类是一种强大的工具&#xff0c;用于创建具有共同属性和行为的对象。本篇博客将详细介绍Python中类和对象的创建&#xff0c;类的属性和方法&#xff0c;以及一些常用的类函数&#xff0c;通过丰富的代码例子来帮助读者深入理解。 一、类和对象的创…...

数组分割(2023省蓝桥杯)n种讨论 JAVA

目录 1、题目描述&#xff1a;2、前言&#xff1a;3、动态规划&#xff08;bug)&#xff1a;3、递归 剪枝&#xff08;超时&#xff09;&#xff1a;4、数学&#xff08;正解&#xff09;&#xff1a; 1、题目描述&#xff1a; 小蓝有一个长度为 N 的数组 A [A0, A1,…, AN−…...

很好的启用window10专业版系统自带的远程桌面

启用window10专业版系统自带的远程桌面 文章目录 启用window10专业版系统自带的远程桌面前言1.找到远程桌面的开关2. 找到“应用”项目3. 打开需要远程操作的电脑远程桌面功能 总结 前言 Windows操作系统作为应用最广泛的个人电脑操作系统&#xff0c;在我们身边几乎随处可见。…...

TCP定制协议,序列化和反序列化

目录 前言 1.理解协议 2.网络版本计算器 2.1设计思路 2.2接口设计 2.3代码实现&#xff1a; 2.4编译测试 总结 前言 在之前的文章中&#xff0c;我们说TCP是面向字节流的&#xff0c;但是可能对于面向字节流这个概念&#xff0c;其实并不理解的&#xff0c;今天我们要介…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

Debian系统简介

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

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...