golang测试框架--smartystreets/goconvey
视频教程和配套博客:goconvey - 课时 1:优雅的单元测试
Go 语言虽然自带单元测试功能,在 GoConvey 诞生之前也出现了许多第三方辅助库。但没有一个辅助库能够像 GoConvey 这样优雅地书写代码的单元测试,简洁的语法和舒适的界面能够让一个不爱书写单元测试的开发人员从此爱上单元测试。
下载安装 GoConvey:
go get github.com/smartystreets/goconvey
在$GOPATH/src目录下新增了github.com子目录,该子目录里包含了GoConvey框架的库代码
在$GOPATH/bin目录下新增了GoConvey框架的可执行程序goconvey
API 文档
请移步 Go Walker。
基本使用方法
示例:
下面是一个能够实现整数基本四则运算(加、减、乘、除)的代码:
package main import "errors" func Add(a, b int) int {
return a + b
} func Subtract(a, b int) int {
return a - b
} func Multiply(a, b int) int {
return a * b
} func Division(a, b int) (int, error) {
if b == {
return , errors.New("被除数不能为 0")
}
return a / b, nil
}
func main() { }
在上面的代码中,我们实现了 4 个函数,因此需要为这 4 个函数分别书写单元测试:
package main import (
. "github.com/smartystreets/goconvey/convey"
"testing"
) func TestAdd(t *testing.T) {
Convey("将两数相加", t, func() {
So(Add(, ), ShouldEqual, )
})
} func TestSubtract(t *testing.T) {
Convey("将两数相减", t, func() {
So(Subtract(, ), ShouldEqual, -)
})
} func TestMultiply(t *testing.T) {
Convey("将两数相乘", t, func() {
So(Multiply(, ), ShouldEqual, )
})
} func TestDivision(t *testing.T) {
Convey("将两数相除", t, func() { Convey("除以非 0 数", func() {
num, err := Division(, )
So(err, ShouldBeNil)
So(num, ShouldEqual, )
}) Convey("除以 0", func() {
_, err := Division(, )
So(err, ShouldNotBeNil)
})
})
}
首先,您需要使用官方推荐的方式导入 GoConvey 的辅助包以减少冗余的代码:. "github.com/smartystreets/goconvey/convey"
。
每个单元测试的名称需要以 Test
开头,例如:TestAdd
,并需要接受一个类型为 *testing.T
的参数。
使用 GoConvey 书写单元测试,每个测试用例需要使用 Convey
函数包裹起来。它接受的第一个参数为 string 类型的描述;第二个参数一般为 *testing.T
,即本例中的变量 t;第三个参数为不接收任何参数也不返回任何值的函数(习惯以闭包的形式书写)。
Convey
语句同样可以无限嵌套,以体现各个测试用例之间的关系,例如 TestDivision
函数就采用了嵌套的方式体现它们之间的关系。需要注意的是,只有最外层的 Convey
需要传入变量 t,内层的嵌套均不需要传入。
最后,需要使用 So
语句来对条件进行判断。在本例中,我们只使用了 3 个不同类型的条件判断:ShouldBeNil
、ShouldEqual
和 ShouldNotBeNil
,分别表示值应该为 nil、值应该相等和值不应该为 nil。有关详细的条件列表,可以参见 官方文档。
测试:
go test -v
输出结果(ubuntu):
=== RUN TestAdd 将两数相加 ✔ total assertion --- PASS: TestAdd (.00s)
=== RUN TestSubtract 将两数相减 ✔ total assertions --- PASS: TestSubtract (.00s)
=== RUN TestMultiply 将两数相乘 ✔ total assertions --- PASS: TestMultiply (.00s)
=== RUN TestDivision 将两数相除
除以非 数 ✔✔
除以 ✔ total assertions --- PASS: TestDivision (.00s)
PASS
ok tttt .004s
我们可以看到,输出结果调理非常清晰,单元测试的代码写起来也非常优雅。那么,这就是全部吗?当然不是。GoConvey 不仅支持在命令行进行人工调用调试命令,还有非常舒适的 Web 界面提供给开发者来进行自动化的编译测试工作。
Web 界面
想要使用 GoConvey 的 Web 界面特性,需要在相应目录下执行 goconvey
(需使用 go get
安装到 $GOPATH/bin
目录下),然后打开浏览器,访问 http://localhost:8080 ,就可以看到下以下界面:
//一般都是在项目根目录下(具体根据自己的情况)
goconvey // 确保 $GOPATH/bin 目录下存在 goconvey文件
在 Web 界面中,您可以设置界面主题,查看完整的测试结果,使用浏览器提醒等实用功能。
其它功能:
- 自动检测代码变动并编译测试
- 半自动化书写测试用例:http://localhost:8080/composer.html
- 查看测试覆盖率:http://localhost:8080/reports/
- 临时屏蔽某个包的编译测试
Skip
针对想忽略但又不想删掉或注释掉某些断言操作,GoConvey提供了Convey/So的Skip方法:
- SkipConvey函数表明相应的闭包函数将不被执行
- SkipSo函数表明相应的断言将不被执行
当存在SkipConvey或SkipSo时,测试日志中会显式打上"skipped"形式的标记:
- 当测试代码中存在SkipConvey时,相应闭包函数中不管是否为SkipSo,都将被忽略,测试日志中对应的符号仅为一个"⚠"
- 当测试代码Convey语句中存在SkipSo时,测试日志中每个So对应一个"✔"或"✘",每个SkipSo对应一个"⚠",按实际顺序排列
- 不管存在SkipConvey还是SkipSo时,测试日志中都有字符串"{n} total assertions (one or more sections skipped)",其中{n}表示测试中实际已运行的断言语句数
定制断言函数
我们先看一下So的函数原型:
func So(actual interface{}, assert assertion, expected ...interface{})
第二个参数为assertion,它的原型为:
type assertion func(actual interface{}, expected ...interface{}) string
当assertion的返回值为""时表示断言成功,否则表示失败,GoConvey框架中的相关代码为:
const (
success = ""
needExactValues = "This assertion requires exactly %d comparison values (you provided %d)."
needNonEmptyCollection = "This assertion requires at least 1 comparison value (you provided 0)."
)
我们简单实现一个assertion函数:
func ShouldGt(actual interface{}, expected ...interface{}) string {
if len(expected) == {
return "缺少参数 expected..."
}
val1 := actual.(int)
val2 := expected[].(int)
if val1 <= val2{
return fmt.Sprintf("%d 不大于 %d", actual, expected[])
}
return ""
}
写一个简单的测试:
func TestGt(t *testing.T) {
time.Sleep(time.Second*) //仅仅是测试耗时
Convey("两数相乘是否大于100", t, func() {
So(, ShouldGt, )
So(, ShouldGt, )
})
}
根据ShouldGt的实现,Convey语句中第一个So将断言成功,第二个So将断言失败。
我们运行测试,查看执行结果,符合期望:
=== RUN TestGt 两数相乘是否大于100 ✘ Failures: * /home/zhou/go/src/tttt/zhou_test.go
Line :
不大于 total assertion --- FAIL: TestGt (.00s)
FAIL
exit status
FAIL tttt .002s
要点归纳总结:
- import goconvey包时,前面加点号".",以减少冗余的代码
- 测试函数的名字必须以Test开头,而且参数类型必须为*testing.T
- 每个测试用例必须使用Convey函数包裹起来,推荐使用Convey语句的嵌套,即一个函数有一个测试函数,测试函数中嵌套两级Convey语句,第一级Convey语句对应测试函数,第二级Convey语句对应测试用例
- Convey语句的第三个参数习惯以闭包的形式实现,在闭包中通过So语句完成断言
- 使用GoConvey框架的 Web 界面特性,作为命令行的补充
- 在适当的场景下使用SkipConvey函数或SkipSo函数
- 当测试中有需要时,可以定制断言函数
转载:传送门
转载更好的博客:传送门
golang测试框架--smartystreets/goconvey的更多相关文章
- [Golang] GoConvey测试框架使用指南
GoConvey 是一款针对Golang的测试框架,可以管理和运行测试用例,同时提供了丰富的断言函数,并支持很多 Web 界面特性. GoConvey 网站 : http://smartystreet ...
- golang测试
简述 Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试. go test [-c] [-i] [build flags] [packages] [f ...
- Golang单元测试框架整理
目录 一.单元测试是什么 二.单元测试的意义 三.Golang单元测试框架 3.1 Golang内置testing包 3.1.1 简单的测试 3.1.2 Benchmark 基准测试 3.1.3 运行 ...
- Golang测试技术
本篇文章内容来源于Golang核心开发组成员Andrew Gerrand在Google I/O 2014的一次主题分享“Testing Techniques”,即介绍使用Golang开发 时会使用到的 ...
- Go语言打造以太坊智能合约测试框架(level1)
传送门: 柏链项目学院 Go语言打造以太坊智能合约测试框架 前言 这是什么? 这是一个基于go语言编写的,自动化测试以太坊智能合约的开发框架,使用此框架,可以自动化的部署合约,自动测试合约内的功能函数 ...
- Golang 微框架 Gin 简介
框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用,甚至有的时候,脱离了框架,一些开发者都不会写程序了.成长总不会一蹴而就,从写出程序获取成就感,再到精通框架,快速构造应用,当这些方面都得心应 ...
- golang(gin框架),基于RESTFUL的跨语言远程通信尝试
golang(gin框架),基于RESTFUL的跨语言远程通信尝试 背景: 在今年的项目实训过程中,遇到了这样的问题: 企业老师讲课实用的技术栈是Java springboot. 实训实际给我们讲课以 ...
- phpunit 测试框架安装
PHPUnit是一个轻量级的PHP测试框架.它是在PHP5下面对JUnit3系列版本的完整移植,是xUnit测试框架家族的一员(它们都基于模式先锋Kent Beck的设计).来自百度百科 一.下载wg ...
- 某互联网后台自动化组合测试框架RF+Sikuli+Python脚本
某互联网后台自动化组合测试框架RF+Sikuli+Python脚本 http://www.jianshu.com/p/b3e204c8651a 字数949 阅读323 评论1 喜欢0 一.**Robo ...
随机推荐
- WPF知识点全攻略08- 依赖属性
依赖属性是WPF不得不提,不得不会系列又一 先来看一下,自定义依赖属性的写法 public static readonly DependencyProperty IconProperty = Depe ...
- valgrind测试程序内存泄漏问题
1.用wincap将valgrind放入系统任意路径下,解压 2. 登录主机后台在需要测试程序的路径下运行此行命令: /opt/valgrind/bin/valgrind ./itb(例) 3. 跑 ...
- x220 OS X 10.10.4安装
变色龙安装过程: 1.使用磁盘助手将按照盘写入独立的磁盘分区(AF格式,就是Apple的HPS格式): 2.安装启动时,用-v -f -x参数,分别为显示信息.重新build系统驱动.安全模式: 3. ...
- CSS盒模型总结(一)
一.基本概念 盒子模型是css中一个重要的概念,理解了盒子模型才能更好的排版,盒模型的组成:content padding border margin 二.盒模型的分类 盒子模型有两种,分别是 ie ...
- PAT 乙级 1019
题目 题目地址:PAT 乙级 1019 思路 本题没有考虑到小于1000的情况,当小于1000的时需要给vector的向量中推入0,直到向量中有四位数字,之后再进行排序并进行相关计算 代码 #incl ...
- 【图论 搜索】bzoj1064: [Noi2008]假面舞会
做到最后发现还是读题比赛:不过还是很好的图论题的 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选 ...
- MySQL丨01丨数据库基本概念
以前记录数据可能很少也很简单,比如说老王借了老李半斤肉,这样的数据老李直接就写到墙上就行了. 后来数据多了人们就以表格的方式开始记录,写到一张A4纸上,比如学生的档案,有表头和序号等. 表头里有姓名. ...
- 文件操作-dd
Linux dd命令 用于读取.转换并输出数据. dd可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件.设备或标准输出. 参数说明: if=文件名: 输入文件名,缺省为标准输入.即 ...
- C语言:哲学家吃饭问题
//五个哲学家围坐在一起,两人之间都放有一个叉子,意大利面需要2个叉子吃,哲学家吃饭时候叉子只能拿左右手,哲学家除了吃饭时间其他时间都在思考 #include <stdio.h> #inc ...
- Python9-封装-day26(大年初三)
class Room: def __init__(self,name,length,width): self.__name = name self.__length = length self.__w ...