一、GoConvey简介
1、GoConvey简介
GoConvey是一款针对Golang的测试框架,可以管理和运行测试用例,同时提供了丰富的断言函数,并支持多种Web界面特性。
官方地址:
https://github.com/smartystreets/goconvey
安装:go get github.com/smartystreets/goconvey
2、GoConvey的特点
GoConvey支持 go test,可直接在终端窗口和浏览器上使用。GoConvey特点如下:
A、直接集成go test
B、巨大的回归测试套件
C、可读性强的色彩控制台输出
D、完全自动化的Web UI
E、测试代码生成器
二、GoConvey测试用例编写
1、GoConvey标准断言
官方文档:
https://github.com/smartystreets/goconvey/wiki
GoConvey自带大量的标准断言函数,可以通过So()使用。
(1)通用相等比较
So(thing1,ShouldEqual,thing2)
So(thing1,ShouldNotEqual,ShouldResemble,thing2)
用于数组、切片、map和结构体的深度比较
So(thing1,ShouldNotResemble,ShouldPointTo,ShouldNotPointTo,ShouldBeNil)
So(thing1,ShouldNotBeNil)
So(thing1,ShouldBeTrue)
So(thing1,ShouldBeFalse)
So(thing1,ShouldBeZerovalue)
(2)数值比较
So(1,ShouldBeGreaterThan,0)
So(1,ShouldBeGreaterThanorEqualTo,ShouldBeLessthan,2)
So(1,ShouldBeLessthanorEqualTo,2)
So(1.1,ShouldBeBetween,.8,1.2)
So(1.1,ShouldNotBeBetween,2,3)
So(1.1,ShouldBeBetweenorEqual,.9,1.1)
So(1.1,ShouldNotBeBetweenorEqual,1000,2000)
So(1.0,ShouldAlmostEqual,0.99999999,.0001)
带容差比较,默认容差为0.0000000001
So(1.0,ShouldNotAlmostEqual,0.9,.0001)
(3)数据集合比较
So([]int{2,4,6},ShouldContain,4)
So([]int{2,ShouldNotContain,5)
So(4,ShouldBeIn,...[]int{2,6})
So(4,ShouldNotBeIn,...[]int{1,3,5})
So([]int{},ShouldBeEmpty)
So([]int{1},ShouldNotBeEmpty)
So(map[string]string{"a": "b"},ShouldContainKey,"a")
So(map[string]string{"a": "b"},ShouldNotContainKey,"b")
So(map[string]string{"a": "b"},ShouldNotBeEmpty)
So(map[string]string{},ShouldBeEmpty)
So(map[string]string{"a": "b"},ShouldHaveLength,1)
支持map、切片、通道、字符串
(4)字符串比较
So("asdf",ShouldStartWith,"as")
So("asdf",ShouldNotStartWith,"df")
So("asdf",ShouldEndWith,ShouldNotEndWith,ShouldContainSubstring,"sd")
So("asdf",ShouldNotContainSubstring,"er")
So("adsf",ShouldBeBlank)
So("asdf",ShouldNotBeBlank)
(5)异常比较
So(func(),ShouldPanic)
So(func(),ShouldNotPanic)
So(func(),ShouldPanicWith,"") // or errors.New("something")
So(func(),ShouldNotPanicWith,"") // or errors.New("something")
(6)类型检查
So(1,ShouldHaveSameTypeAs,ShouldNotHaveSameTypeAs,"asdf")
(7)时间比较
So(time.Now(),ShouldHappenBefore,time.Now())
So(time.Now(),ShouldHappenOnorBefore,ShouldHappenAfter,ShouldHappenOnorAfter,ShouldHappenBetween,time.Now(),ShouldHappenOnorBetween,ShouldNotHappenOnorBetween,ShouldHappenWithin,duration,ShouldNotHappenWithin,time.Now())
2、测试用例编写
官方推荐使用导入GoConvey的辅助包以减少冗余的代码:. "github.com/smartystreets/goconvey/convey"
GoConvey包导入在工程代码中如下:
import ( "testing" . "github.com/smartystreets/goconvey/convey" )
每个单元测试的名称需以?Test?开头,并需要接收一个类型为?*testing.T?
的参数。
每个测试用例需要使用Convey函数包裹起来,第一个参数为string类型的测试用例描述;第二个参数一般为?*testing.T
;第三个参数为不接收任何参数也不返回任何值的函数(通常以闭包的形式书写)。
Convey语句可以无限嵌套,以体现各个测试用例之间的关系,只有最外层的?Convey?需要传入*testing.T
类型变量,内层嵌套的Convey不需要传入。
func TestAdd(t *testing.T) { Convey("将两数相加",t,func() { So(Add(1,2),3) }) }
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}表示测试中实际已运行的断言语句数。
3、测试用例示例
Operator.go文件:
package Operator 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 == 0 { return 0,errors.New("Divisor is 0") } return a / b,nil }
Operator_test.go文件:
package Operator import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func TestAdd(t *testing.T) { Convey("将两数相加",3) }) } func TestSubtract(t *testing.T) { Convey("将两数相减",func() { So(Subtract(1,-1) }) } func TestMultiply(t *testing.T) { Convey("将两数相乘",func() { So(Multiply(3,6) }) } func TestDivision(t *testing.T) { Convey("将两数相除",func() { Convey("除以非 0 数",func() { num,err := Division(10,2) So(err,ShouldBeNil) So(num,5) }) Convey("除以 0",func() { _,0) So(err,ShouldNotBeNil) }) }) }
4、定制断言函数
So的函数原型如下:
func So(actual interface{},assert assertion,expected ...interface{}) 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)." )
定制断言函数如下:
func ShouldSummerBeComming(actual interface{},expected ...interface{}) string { if actual == "summer" && expected[0] == "comming" { return "" } else { return "summer is not comming!" } }
单元测试如下:
func TestSummer(t *testing.T) { Convey("TestSummer",func() { So("summer",ShouldSummerBeComming,"comming") So("winter","comming") }) }
根据ShouldSummerBeComming的实现,闭包中第一个So将断言成功,第二个So将断言失败。
三、测试结果查看
1、命令行测试结果查看
GoConvey兼容Go原生的单元测试,可以直接使用Go命令来执行测试。
在测试代码目录下运行go test命令:?go test -v?
测试执行结果如下:
=== RUN TestAdd 将两数相加 ? 1 total assertion --- PASS: TestAdd (0.00s) === RUN TestSubtract 将两数相减 ? 2 total assertions --- PASS: TestSubtract (0.00s) === RUN TestMultiply 将两数相乘 ? 3 total assertions --- PASS: TestMultiply (0.00s) === RUN TestDivision 将两数相除 除以非 0 数 ?? 除以 0 ? 6 total assertions --- PASS: TestDivision (0.00s) PASS ok GoExample/GoConvey 0.002s
2、Web界面测试结果查看
查看goconvey用法goconvey -h
-cover:开启覆盖率统计功能
-depth int:扫描目录的深度,-1:扫描无穷深度,0:扫描当前目录
-excludedDirs string:将某些目录排除在扫描外,多个目录使用逗号分割
-host string:指定开启HTTP服务的主机
-launchbrowser:触发自动开启浏览器,默认为true
-port int:指定HTTP服务的端口
-workdir string:指定工作目录,默认为当前目录
在测试用例源码目录下运行goconvey:goconvey -port 8081
在浏览器打开:
http://localhost:8081
结果如下:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。