Golang下如何写单元测试?官方提供的testing package略显简陋,不过好在我们有Gocheck。

什么是好的单元测试?

在进入正题前,先来温习下前人总结的单元测试几条原则:
http://www.atatech.org/articles/2523

1   单元测试应该在最低的功能/参数上验证程序的正确性
...
3    单元测试过后,机器状态保持不变
...
6    独立性,单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性。

好的单元测试,应该遵循上面的原则;好的单元测试框架,应该为我们践行这些原则提供方便。

gocheck,简单好用

gocheck官网:http://labix.org/gocheck

Golang官方的testing package算是很弱的了:居然连assert都不支持。Gocheck在testing库之上,丰富了很多功能,带我们脱离Golang官方测试框架下无尽的“if…else…"苦海。尤其好用的特性包括:

  1. assert断言 + 丰富的判断动词: deep multi-type 对比, 字符串比较(甚至支持正则匹配!)。
  2. 按suite组织测试用例,支持suite级别的setup()和teardown()。
  3. 创建、删除临时文件/目录。

示例1:文件操作相关的单元测试

“单元测试过后,机器状态保持不变”的原则告诉我们,如果单元测试要读写文件,单元测试结束后要清理创建的临时文件。

gocheck可以创建一个临时目录,在测试结束时自动删除它,省去了手动清理的步骤。

示例:

package hello_testimport ("testing""io/ioutil""io". "gopkg.in/check.v1"
)const txt = "adfagaggafaf"// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }type MySuite struct {dir string   // 测试用的临时目录f   string   // 测试用的临时文件
}var _ = Suite(&MySuite{})// Setupsuite 准备测试用的临时文件
func (s *MySuite) SetUpSuite(c *C) {dir := c.MkDir()    // Suite结束后会自动销毁c.MkDir()创建的目录tmpfile, err := ioutil.TempFile(dir, "")if err != nil {c.Errorf("Fail to create test file: %v\n", tmpfile.Name(), err)}err = WriteFile(tmpfile.Name(), txt)if err != nil {c.Errorf("Fail to prepare test file.%v\n", tmpfile.Name(), err)}s.dir = dirs.f = tmpfile.Name()
}func (s *MySuite) TestFoo(c *C) {// ... 实际测试代码c.Assert(bkpName, Matches, s.f+".ops_agent_bkp.+")
}

示例2:Mock web api相关的单元测试

“独立性”的原则告诉我们,对于需要调用外部api的功能,最好mock数据。利用gocheck的SetUpSuite()和TearDownSuite()方法,可以新建一个http test server,结束时关闭它。

示例:

package hello_testimport ("fmt""net/http""net/http/httptest""testing". "gopkg.in/check.v1"
)const (resp1 = `{"data" : {"cluster" : "*****","hostname" : "xxxxx"},"err_code" : 0,"err_msg" : ""
}
`resp2 = `{"data" : [{"hostname" : "e18h13551.XXX","ip" : "100.22.33.44","state" : "GOOD"},{"hostname" : "dddd","ip" : "101.14.12.55","state" : "GOOD"}],"err_code" : 0,"err_msg" : ""
}
`
)// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }type MySuite struct {ts *httptest.Server
}func (s *MySuite) SetUpSuite(c *C) {h := http.NewServeMux()h.HandleFunc("/machine", func(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, resp1)})h.HandleFunc("/batch", func(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, resp2)})s.ts = httptest.NewServer(h)
}func (s *MySuite) TearDownSuite(c *C) {s.ts.Close()
}var _ = Suite(&MySuite{})func (s *MySuite) TestFoo(c *C) {// 实际测试代码....clusterName, err := getClusterName(s.ts.URL, "/machine")c.Assert(err, IsNil)c.Assert(clusterName, Equals, "MiniLVSCluster-5e87-2384205713506559")
}

其他

Gocheck其他好用的特性,比如强大的checker 就不在此列举。可以在官网上翻翻,让写单元测试更简单。

安利一个好用的Golang单元测试框架:gocheck相关推荐

  1. Golang 单元测试框架 gocheck 使用介绍

    什么是好的单元测试框架? 单元测试应该在的功能和参数上验证程序的正确性:单元测试过后,机器状态应该保持不变:单元测试的运行.通过.失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性. Go ...

  2. catch2:一个好用的C++单元测试框架

    文章目录 为什么需要catch 简单易用 命令行选项 Sections BDD-style Assertion Macros Floating point comparisons Exceptions ...

  3. golang单元测试框架GoConvey

    GoConvey是一个非常非常好用的Go测试框架,它直接与go test集成,提供了很多丰富的断言函数,能够在终端输出可读的彩色测试结果 安装 go get github.com/smartystre ...

  4. golang单元测试框架实践

    一.简介 单元测试主要是通过模拟业务中的参数,调用我们的函数,然后获取执行结果,再判断结果是否符合规则:同时还可以对某一个方法进行性能分析 在Go 标准库中有一个叫做 testing 的测试框架, 可 ...

  5. 玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架

    一.前言 上一篇我们分析了gtest的一些内部实现,总的来说整体的流程并不复杂.本篇我们就尝试编写一个精简版本的C++单元测试框架:nancytest ,通过编写这个简单的测试框架,将有助于我们理解g ...

  6. python单元测试框架unittest介绍和使用_Python+Selenium框架设计篇之-简单介绍unittest单元测试框架...

    前面文章已经简单介绍了一些关于自动化测试框架的介绍,知道了什么是自动化测试框架,主要有哪些特点,基本组成部分等.在继续介绍框架设计之前,我们先来学习一个工具,叫unittest. unittest是一 ...

  7. 玩转Google开源C++单元测试框架

    玩转Google开源C++单元测试框架Google Test系列(gtest)(总) 前段时间学习和了解了下Google的开源C++单元测试框架Google Test,简称gtest,非常的不错. 我 ...

  8. c语言的自动测试工具,C语言单元测试框架--check工具

    C语言单元测试框架--check工具 虽然在UNIX上用C语言做开发已经有一段时间了,但是我不得不承认,自己单元测试做的并不好.恰好最近有新的开发任务,就学习了一些关于测试驱动开发的知识,准备改进自己 ...

  9. 关于单元测试框架GoogleTest——参考《百度文库》、大量博客

    本文章集齐百家之所长(又臭又长),读者可根据自己的需求自取: 一.关于测试 1.1 为啥要测试? 1.2 测试的分类 1.3 [单元测试-参考web[song]的博客] 1.3.1.为什么单元测试? ...

最新文章

  1. iOS原生与html交互 使用第三方WebViewJavascriptBridge
  2. java的object如何转为具体的类_佛山个体户如何转为公司?
  3. 2021年中国计算机视觉人才调研开启啦,诚邀各位开发者们参与~
  4. 快速排序的原理以及Java代码
  5. redis 命令行 操作
  6. [Python入门及进阶笔记]Python-魔术方法小结(方法运算符重载)
  7. H3C 典型数据链路层标准
  8. 中国囊虫病治疗市场趋势报告、技术动态创新及市场预测
  9. 60. cache
  10. php httputils,Android 自定义网络加载工具类 HttpURLConnectionUtils
  11. Delphi组件介绍
  12. vscode 搭建SSM项目环境
  13. 微服务网关Spring Cloud Gateway
  14. plc与计算机通信方式,PLC通信方式介绍
  15. recyclerview简单使用
  16. HTML5页面显示本地图片,h5使用FileReader读取本地上传的图片文件并显示到浏览器...
  17. .DOT COMMON-斯科特·汉塞尔曼(Scott Hanselman)的一首节拍诗
  18. 一些简单的shell实例
  19. chp02-01文本文件的读写
  20. 社区健康管理系统、健康管理系统的设计与实现

热门文章

  1. Linux 建立用户和修改用户UID,GID
  2. SolidWorks添加GB铝型材库要注意的问题
  3. 如何解决PHP-FPM报错: server reached max_children
  4. 均方根误差,均方误差,均方根,均方差,方差的区别
  5. 微信分享(ShareSDK)个人经验总结
  6. BuildCommDCB 参数错误
  7. 通信不稳定,信号反射问题?图解 过冲、下冲、振铃!解决方案。附:C#串口固件升级软件 V1.0.0-企业版
  8. Android自定义view原理及自定义View示例
  9. JavaScript——除指定区域外点击任何地方隐藏DIV
  10. 如何获得个人免费空间