goconvey

GoConvey是一款针对Golang的测试框架,可以管理和运行测试用例,同时提供了丰富的断言函数,并支持很多 Web 界面特性。
Golang虽然自带了单元测试功能,并且在GoConvey框架诞生之前也出现了许多第三方测试框架,但没有一个测试框架像GoConvey一样能够让程序员如此简洁优雅的编写测试代码。

go get github.com/smartystreets/goconvey
在$GOPATH/src目录下新增了github.com子目录,该子目录里包含了GoConvey框架的库代码
在$GOPATH/bin目录下新增了GoConvey框架的可执行程序goconvey



先写一个正常情况的测试用例,如下所示:



import (
“testing”
. “github.com/smartystreets/goconvey/convey”
)



func TestStringSliceEqual(t *testing.T) {
Convey(“TestStringSliceEqual should return true when a != nil && b != nil”, t, func() {
a := []string{“hello”, “goconvey”}
b := []string{“hello”, “goconvey”}
So(StringSliceEqual(a, b), ShouldBeTrue)
})
}



由于GoConvey框架兼容Golang原生的单元测试,所以可以使用go test -v来运行测试。
打开命令行,进入$GOPATH/src/infra/alg目录下,运行go test -v,则测试用例的执行结果日下:



=== RUN TestStringSliceEqual



TestStringSliceEqual should return true when a != nil && b != nil ✔



1 total assertion



— PASS: TestStringSliceEqual (0.00s)
PASS
ok infra/alg 0.006s



几个要点:



import goconvey包时,前面加点号”.”,以减少冗余的代码。凡是在测试代码中看到Convey和So两个方法,肯定是convey包的,不要在产品代码中定义相同的函数名
测试函数的名字必须以Test开头,而且参数类型必须为testing.T
每个测试用例必须使用Convey函数包裹起来,它的第一个参数为string类型的测试描述,第二个参数为测试函数的入参(类型为
testing.T),第三个参数为不接收任何参数也不返回任何值的函数(习惯使用闭包)
Convey函数的第三个参数闭包的实现中通过So函数完成断言判断,它的第一个参数为实际值,第二个参数为断言函数变量,第三个参数或者没有(当第二个参数为类ShouldBeTrue形式的函数变量)或者有(当第二个函数为类ShouldEqual形式的函数变量)



Web 界面
GoConvey不仅支持在命令行进行自动化编译测试,而且还支持在 Web 界面进行自动化编译测试。想要使用GoConvey的 Web 界面特性,需要在测试文件所在目录下执行goconvey:



$GOPATH/bin/goconvey



在 Web 界面中:



可以设置界面主题
查看完整的测试结果
使用浏览器提醒等实用功能
自动检测代码变动并编译测试
半自动化书写测试用例
查看测试覆盖率
临时屏蔽某个包的编译测试
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 ShouldSummerBeComming(actual interface{}, expected …interface{}) string {
if actual == “summer” && expected[0] == “comming” {
return “”
} else {
return “summer is not comming!”
}
}
我们仍然在slice_test文件中写一个简单测试:



func TestSummer(t *testing.T) {
Convey(“TestSummer”, t, func() {
So(“summer”, ShouldSummerBeComming, “comming”)
So(“winter”, ShouldSummerBeComming, “comming”)
})
}
根据ShouldSummerBeComming的实现,Convey语句中第一个So将断言成功,第二个So将断言失败。



http://goconvey.co/



2.goland中使用convey
1.选中要生成测试的代码
2.file–new–go file
3.取文件名,跟原始文件保持一致,后面加_test.go



4.在新生成的文件中,command+N,然后选择Test
5.写convey测试代码
法1:选中测试函数,右键,run test



法二:



go test -v



go test -v -cover



4.图形界面查看
$GOPATH/bin/goconvey


Category golang