go test 上篇
前言
Go语言本身集成了轻量级的测试框架,由go test命令和testing包组成。包含单元测试和压力测试,是保证我们编写健壮Golang程序的有效工具。
演示环境
$ uname -a
Darwin 18.6. Darwin Kernel Version 18.6.: Thu Apr :: PDT ; root:xnu-4903.261.~/RELEASE_X86_64 x86_64
$ go version
go version go1.12.4 darwin/amd64
示例
老规矩,我会用一个简单的示例演示go test的用法,让大家有一个直观的感受。
$ ls
my.go my_test.go
$ go test -v
=== RUN TestAbs
--- PASS: TestAbs (.00s)
PASS
ok mytest .006s
my.go文件内容:
package mytest
func Abs(a int) int {
if a < {
return -*a
}
return a
}
my_test.go文件的内容:
package mytest
import "testing"
func TestAbs(t *testing.T) {
result := Abs(-)
if result != {
t.Errorf("Abs(-1) = %d; want 1", result)
}
}
可以看出,测试文件是以_test.go结尾的文件,包含函数名TestXXX的文件签名func (t *testing.T)。测试框架会按函数定义的顺序依次执行Test开头的函数。如果测试函数调用错误函数,比如t.Error,t.Fail,那么测试就会认为是失败的。但是不会强制退出,测试程序还是会接着往下运行,除非调用t.Fatal,就会打印错误信息,并且强制退出。go test会自动编译运行_test.go结尾的文件,go build不会编译_test.go结尾的文件,所以不用担心test文件和正式文件定义为同一个包导致包大小增大。
详细用法
go test执行时会编译_test结尾的文件,执行文件中以Test,Benchmark,Example 开头的测试函数。建议_test.go文件和源文件声明为同一个包。单元测试函数TestXXX的参数是testing.T,BenchmarkXXX的参数是testing.B,函数内以b.N作为循环次数,其中N会动态变化。可以通过testing.T的Error,Errorf,Fail,Fatal,Fatalf 来说明测试不通过。
表格驱动测试
上述的示例单元测试用了-1这个测试用例来演示测试用法,但是在实际生产中我们编写一个测试函数肯定会有多种测试用例,各种边界条件,那这种情况应该怎么办呢?难道要每个测试用例拷贝一份上述的测试函数吗,显然是不合适的。这就介绍接下来的表格驱动测试(table driven test):
package mytest
import "testing"
func TestAbs(t *testing.T) {
var testcases = []struct {
in int
out int
}{
{-, },
{, },
{, },
{, },
{-, -},
}
for _, tc := range testcases {
result := Abs(tc.in)
if result != tc.out {
t.Fatalf("Abs(%d) = %d; want %d", tc.in, result, tc.out)
}
}
}
表格的每一项是一个完整的测试用例,包含输入信息和期望的输出结果,有时候还包含测试用例名称等额外信息。这样我们就可以在表格里面编写各种测试用例场景,包括常规场景,边界场景,和一些异常场景。运行结果为:
$ go test -v
=== RUN TestAbs
--- FAIL: TestAbs (.00s)
my_test.go:: Abs(-) = ; want -
FAIL
exit status
FAIL mytest .005s
性能测试
性能测试函数以是Benchmark开头,格式为:
func Benchmark(b *testing.B)
go test 默认是不会运行_test.go文件中的Benchmark函数,需要通过-bench选项开启。演示代码:
package mytest
import "testing"
func BenchmarkAbs(b *testing.B) {
for i := ; i < b.N; i++ {
result := Abs(i)
if result != i {
b.Errorf("benchmark faild, abs(%d) result %d, except %d", i, result, i)
}
}
}
运行结果:
$ go test -bench=".*"
goos: darwin
goarch: amd64
pkg: mytest
BenchmarkAbs- 0.26 ns/op
PASS
ok mytest .553s
-bench后面跟的是正则表达式,我们可以指定需要匹配运行的benchmark函数,示例中的.*表示运行所有的benchmark函数。
上述结果显示总共运行了0.553s,一共运行了2000000000次,平均每次运行的时间是0.26纳秒。
总结
文章介绍了Go语言自带的go test测试框架的单元测试和性能测试方法。下篇将会讲解gomock模拟实际的生产接口。
参考
https://golang.org/pkg/testing/
https://github.com/golang/go/wiki/TableDrivenTests
https://golang.org/doc/code.html#Testing
go test 上篇的更多相关文章
- 看看C# 6.0中那些语法糖都干了些什么(上篇)
今天没事,就下了个vs2015 preview,前段时间园子里面也在热炒这些新的语法糖,这里我们就来看看到底都会生成些什么样的IL? 一:自动初始化属性 确实这个比之前的版本简化了一下,不过你肯定很好 ...
- .Net开发笔记(十四) 基于“泵”的UDP通信(接上篇)
上一篇中说到了“泵”在编程中的作用以及一些具体用处,但没有实际demo,可能不好理解,这篇文章我分享一个UDP通信的demo,大概实现了类似“飞鸽传书”在局域网中文本消息和文件传输的功能.功能不全也不 ...
- ASP.NET Core的配置(4):多样性的配置来源[上篇]
较之传统通过App.config和Web.config这两个XML文件承载的配置系统,ASP.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配置源的支持.我们可以将内存变量.命 ...
- ASP.NET Core的配置(3): 将配置绑定为对象[上篇]
出于编程上的便利,我们通常不会直接利用ConfigurationBuilder创建的Configuration对象读取某个单一配置项的值,而是倾向于将一组相关的配置绑定为一个对象,我们将后者称为Opt ...
- 谈谈基于OAuth 2.0的第三方认证 [上篇]
对于目前大部分Web应用来说,用户认证基本上都由应用自身来完成.具体来说,Web应用利用自身存储的用户凭证(基本上是用户名/密码)与用户提供的凭证进行比较进而确认其真实身份.但是这种由Web应用全权负 ...
- Sass-也许你想和CSS玩耍起来(上篇)
我们努力,我们坚持,共勉! 众所周知,css其实不是一门编程语言,熟悉的人都知道css全称Cascading Style Sheets(层叠样式表)是一种用来表现HTML(标准通用标记语言的一个应用) ...
- Aoite 系列(04) - 强劲的 CommandModel 开发模式(上篇)
Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.CommandModel 是一种开发模式,我把它成为"命令模型",这是一 ...
- 那些年我们写过的T-SQL(上篇)
在当今这个多种不同数据库混用,各种不同语言不同框架融合的年代(一切为了降低成本并高效的提供服务),知识点多如牛毛.虽然大部分SQL脚本可以使用标准SQL来写,但在实际中,效率就是一切,因而每种不同厂商 ...
- 用MVVM做了一个保存网页的工具-上篇
前言: 你是否有过收藏了别人博客或文章,当想用的时候却找不到?你是否有过收藏了别人博客或文章,却因为没有网络而打不开网页?OK,下面是我做的一个工具,有兴趣的同学们可以download 玩下,哈哈^. ...
- 【Remoting】.Net remoting方法实现简单的在线升级(上篇:更新文件)
一.前言: 最近做一个简单的在线升级Demo,使用了微软较早的.Net Remoting技术来练手. 简单的思路就是在服务器配置一个Remoting对象,然后在客户端来执行Remoting ...
随机推荐
- idea 快速生成代码的快捷键
psvm 加ab键 mian方法快速生成 sout 加tab键 输出打印快捷键 alt+insert 快速生成get set 方法 itar 生成array for代码块 fo ...
- hdu 5056(尺取法思路题)
Boring count Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 构建更好的HashMap
在7月份的那期 Java理论与实践(“并发集合类”)中,我们简单地回顾了可伸缩性的瓶颈,并讨论了怎么用共享数据结构的方法获得更高的并发性和吞吐量.有时候学习的最好方法是分析专家的成果,所以这个月我们将 ...
- Oracle数据库搭建
- Using Find_Alert and Show_Alert in Oracle Forms
Show_alert is used to display model window messages in Oracle Forms and Find_alert searches the list ...
- Drawable 添加过滤色,改变图片颜色
/** * 更改图片颜色 * @param drawable * @param color * @return */ public Drawable getDrawable(Drawable draw ...
- [置顶]
zabbix告警信息-lykchat信息发送系统
lykchat信息发送系统 lykchat信息发送系统是Python3开发的,通过模拟微信网页端,基于个人微信号,为系统管理人员提供信息发送工具. 实现的功能有用户登录管理.微信登陆管理和微信信息发送 ...
- DotnetBrowser入门教程-(1)浏览器控件使用
先简单介绍下DotnetBrowser作为基本浏览器控件的使用: 1.创建基于.net 4.0的桌面项目,如下所示: 2.首次使用的时候在工具栏里添加dotnetbrowser控件,如下图所示: 3. ...
- C#面试基础知识2
1.C#三层架构 C#三层架构急表示层(UI,User Interface),业务逻辑层(BLL BusinessLogicLayer),数据访问层(DAL Data Access Layer).三层 ...
- Android WiFi开发教程(一)——WiFi热点的创建与关闭
相对于BlueTooth,WiFi是当今使用最广的一种无线网络传输技术, 几乎所有智能手机.平板电脑和笔记本电脑都支持Wi-Fi上网.因此,掌握基本的WiFI开发技术是非常必要的.本教程将围绕一个小D ...