微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Go语言开发十九、GoConvey测试框架

Go语言开发(十九)、GoConvey测试框架

一、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
结果如下:

Go语言开发(十九)、GoConvey测试框架

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐