golang分层测试之单元测试-gocheck使用

前言

  • 话说上回讲到用testing package来进行golang的单元测试,但testing也是有其限制性,靠使用者不断地写if else来判断显然麻烦,那么今天就讲一下gocheck这个单元测试框架的使用

gocheck框架使用

  • gocheck作为golang的一种测试框架,可以直接继承go test使用,他允许之前基于testing框架的测试平滑迁移到gocheck框架而不会发生冲突,gocheck API与testing也有很多相似的地方

安装运行

  • 第一步当然还是安装啦,执行命令
go get -u gopkg.in/check.v1
  • 这样能够获取到最新版本的gocheck框架,然后我们参考实例 gocheck_test.go
package hello_test

import (
    "testing"
    "io"

    . "gopkg.in/check.v1"
)

func Test(t *testing.T) { TestingT(t) }  //继承testing的方法,可以直接使用go test命令运行

type MySuite struct{}  //创建测试套件结构体

var _ = Suite(&MySuite{})  

func (s *MySuite) TestHelloWorld(c *C) {  //声明TestHelloWorld方法为MySuite套件的测试用例
    c.Assert(42, Equals, "42")
    c.Assert(io.ErrClosedPipe, ErrorMatches, "io: .*on closed pipe")
    c.Check(42, Equals, 42)
}
  • gocheck拥有丰富的断言api,比如例子中的 AssertCheck
  • gocheck单元测试代码最基本的结构如例子所示,声明一个测试套件,在测试套件下写测试方法,即测试用例
  • 直接使用go test在测试文件当前路径下运行,运行结果
E:\go_project>go test

----------------------------------------------------------------------
FAIL: gocheck_test.go:17: MySuite.TestHelloWorld

gocheck_test.go:18:
    c.Assert(42, Equals, "42")
... obtained int = 42
... expected string = "42"

OOPS: 0 passed, 1 FAILED
--- FAIL: Test (0.00s)
FAIL
exit status 1
FAIL    _/E_/go_project 0.441s
  • Assert判断出42整型和“42”字符串不是相同,所以运行FAIL,将其中一个改过了,如
    c.Assert(42, Equals, 42)
  • 运行测试则通过
E:\go_project>go test
OK: 1 passed
PASS
ok      _/E_/go_project 0.290s

前置后置操作

  • 除了最基本的结构,当然少不得我们熟悉的测试用例前置后置操作,用于满足用例执行前的准备,以及执行完成后清理环境等方法
func (s *SuiteType) SetUpSuite(c *C) - 在测试套件启动前执行一次
func (s *SuiteType) SetUpTest(c *C) - 在每个用例执行前执行一次
func (s *SuiteType) TearDownTest(c *C) - 在每个用例执行后执行一次
func (s *SuiteType) TearDownSuite(c *C) - - 在测试套件用例都执行完成后执行一次
  • 我们尝试用以下代码来执行
package hello_test

import (
    "testing"
    "io"
    "fmt"
    "strconv"
    . "gopkg.in/check.v1"
)

var a int =1

// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }

type MySuite struct{}

var _ = Suite(&MySuite{})


func (s *MySuite) SetUpSuite(c *C) {
    str3:="第1次套件开始执行"
    fmt.Println(str3)

}

func (s *MySuite) TearDownSuite(c *C) {
    str4:="第1次套件执行完成"
    fmt.Println(str4)
}

func (s *MySuite) SetUpTest(c *C) {
    str1:="第"+strconv.Itoa(a)+"条用例开始执行"
    fmt.Println(str1)

}

func (s *MySuite) TearDownTest(c *C) {
    str2:="第"+strconv.Itoa(a)+"条用例执行完成"
    fmt.Println(str2)
    a=a+1
}

func (s *MySuite) TestHelloWorld(c *C) {
    c.Assert(42, Equals, 42)
    c.Assert(io.ErrClosedPipe, ErrorMatches, "io: .*on closed pipe")
    c.Check(42, Equals, 42)
}

func (s *MySuite) TestHelloTerry(c *C) {
    c.Assert("terry", Equals, "terry")
    c.Assert(io.ErrClosedPipe, ErrorMatches, "io: .*on closed pipe")
    c.Check(42, Equals, 42)
}

最后输出的结果为

E:\go_project>go test
第1次套件开始执行
第1条用例开始执行
第1条用例执行完成
第2条用例开始执行
第2条用例执行完成
第1次套件执行完成
OK: 2 passed
PASS
ok      _/E_/go_project 0.502s
  • 通过执行输出证明,上面方法可满足用例在执行时的前置后置操作

选择执行指定用例

  • 当然我们在执行用例的时候未必需要全部执行,那就需要通过一些选择性的API来选择部分用例执行,如跳过用例或用例套件使用skip
func (s *MySuite) SetUpSuite(c *C) {
    str3:="第1次套件开始执行"
    fmt.Println(str3)
    c.Skip("Skip TestSutie")  //在测试套件启动前跳过整个测试套件的用例
}
//其余代码参考上文
  • 其运行结果为
E:\go_project>go test
第1次套件开始执行
第1次套件执行完成
OK: 0 passed, 2 skipped
PASS
ok      _/E_/go_project 0.272s
  • 如果在跳过套件中的测试用例
func (s *MySuite) TestHelloWorld(c *C) {
    c.Skip("Skip TestCase")  //跳过当前测试用例
    c.Assert(42, Equals, 42)
    c.Assert(io.ErrClosedPipe, ErrorMatches, "io: .*on closed pipe")
    c.Check(42, Equals, 42)
}
  • 其运行结果
E:\go_project>go test
第1次套件开始执行
第1条用例开始执行
第1条用例执行完成
第2条用例开始执行
第2条用例执行完成
第1次套件执行完成
OK: 1 passed, 1 skipped
PASS
ok      _/E_/go_project 0.304s
  • 除了跳过还有选择测试用例执行
$ go test -check.f MyTestSuite   //选择测试套件
$ go test -check.f "Test.*Works"  //选择测试方法
$ go test -check.f "MyTestSuite.Test.*Works"  //选择套件中的方法
  • 执行如下
E:\go_project>go test -check.f TestHelloTerry
第1次套件开始执行
第1条用例开始执行
第1条用例执行完成
第1次套件执行完成
OK: 1 passed
PASS
ok      _/E_/go_project 0.293s
E:\go_project>go test -check.f MySuite.TestHelloTerry
第1次套件开始执行
第1条用例开始执行
第1条用例执行完成
第1次套件执行完成
OK: 1 passed
PASS
ok      _/E_/go_project 0.319s

小结

  • 综合比对使用,gocheck比testing满足更多的测试场景,也提供更多的API,让测试人员更方便的使用golang进行单元测试,单元测试环节基本讲到这里,下一节开始讲API测试啦,谢谢大家继续关注

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容