Golang测试包
Golang测试包
golang自带了测试包(testing),直接可以进行单元测试、性能分析、输出结果验证等。简单看着官方文档试了试,总结一下:
目录结构和命令
使用golang的测试包,需要遵循简单的目录结构
测试代码放在待测试代码的目录下(一个包内),以_test.go结尾,例如如下目录结构,MyTest目录下有待测试的代码文件MyTest.go和测试代码MyTest_test.go
.
|-- bin
| `-- main
|-- pkg
| `-- darwin_amd64
| `-- MyTest.a
`-- src
|-- MyTest
| |-- MyTest.go
| `-- MyTest_test.go
`-- main
`-- main.go
直接在MyTest目录下执行go test命令即可,go test包含很多选项,可以参考Golang手册相关部分
基本的测试函数
待测试的MyTest.go源码如下:
package MyTest import (
"fmt"
) type MyStruct struct {
name string
} func GetFieldValue(x *MyStruct) string {
value := x.name
return value
} func SetFieldValue(x *MyStruct, value string) {
fmt.Println("SetFieldValue()")
x.name = value
}
对于MyTest_test.go,首先自然是要导入golang的测试包:
package MyTest
import testing
基本的测试函数以Test开头,后面接的字符串,第一个字符必须是数字或者大写,例如:
func TestMytest(t *testing.T) {
var st MyStruct
SetFieldValue(&st, "hello")
val := GetFieldValue(&st) if val != "hello" {
t.Error("Set Field")
}
}
T是testing包里定义的一个结构体,其包含了名为common的接口,提供了很多格式化输出的功能,golang提供了自动检查与调用测试函数的机制,测试函数的执行逻辑则需要编写者自行完成。
执行go test 结果为:
Call SetFieldValue()
PASS
ok /go/src/MyTest .004s
如果写成Testmytest,运行时会直接忽略掉该函数。得到的结果仍然为Pass,但是不会打印“Call SetFieldValue()”,也就是说测试函数实际没有执行。
修改一下判断条件:
func TestMytest(t *testing.T) {
var st MyStruct
SetFieldValue(&st, "hello")
val := GetFieldValue(&st) if val != "world" {
t.Error("Set Field")
}
}
这个测试用例不会通过, 而Error函数的入参就是测试不通过时打印的信息:
SetFieldValue()
--- FAIL: TestMytest (.00s)
MyTest_test.go:: Set Field
FAIL
exit status
FAIL _/Users/ronghuihe/Documents/code/golang/my/go/src/MyTest .004s
这并不会中断测试程序,这个函数后面的部分仍然会执行,其他的测试函数也会执行。
性能分析函数
testing包还自带了性能分析功能,可评估代码执行性能。性能分析函数也可以放到前面的xxx_test.go文件内,命名以Benchmark开头,如:
func BenchmarkGetFieldValue(b *testing.B) {
var st MyStruct
SetFieldValue(&st, "hello") for i := ; i < b.N; i++ {
GetFieldValue(&st)
}
}
其中b.N的值在执行过程中会自动调整,使得循环可以执行足够多次,以便得到较为准确的单次结果:
性能分析加-bench参数执行,即go test -bench . (不能漏了最后这个点,它表示执行所有的性能测试函数)
BenchmarkGetFieldValue SetFieldValue()
SetFieldValue()
SetFieldValue()
SetFieldValue()
SetFieldValue()
SetFieldValue()
0.55 ns/op
每次循环大约需要0.55ns。这里SetFieldValue()打印了多次,是因为BenchmarkGetFieldValue被调用了多次。
分析testing包的源码benchmark.go里的launch函数和runN函数,可以看到golang会自行调节性能分析函数的调用次数。每次执行runN都会执行一次性能测试函数,而后根据运行时间,会确定后续的内部循环执行次数b.N,直到总的运行时间达到go test -benchtime指定的时间(如果没指定默认为1s)
注意统计时间时,执行的是使用者编写的性能分析函数,如上例中的BenchmarkGetFieldValue,而最后输出的结果,表达的是for循环里函数的性能,因此for循环之前的代码执行时间很长的话,可能导致统计误差比较大,如果需要剔除for之前代码的影响,可以在for循环之前调用ResetTimer()接口重置本次统计的时间值:
func BenchmarkGetFieldValue(b *testing.B) {
var st MyStruct
SetFieldValue(&st, "hello") b.ResetTimer()
for i := ; i < b.N; i++ {
GetFieldValue(&st)
}
}
Golang测试包的更多相关文章
- Golang测试技术
本篇文章内容来源于Golang核心开发组成员Andrew Gerrand在Google I/O 2014的一次主题分享“Testing Techniques”,即介绍使用Golang开发 时会使用到的 ...
- Golang Vendor 包管理工具 glide 使用教程
Glide 是 Golang 的 Vendor 包管理器,方便你管理 vendor 和 verdor 包.类似 Java 的 Maven,PHP 的 Composer. Github:https:// ...
- golang测试
简述 Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试. go test [-c] [-i] [build flags] [packages] [f ...
- Golang ---testing包
golang自带了testing测试包,使用该包可以进行自动化的单元测试,输出结果验证,并且可以测试性能. 建议安装gotests插件自动生成测试代码: go get -u -v github.com ...
- 如何利用Pre.im分发iOS测试包
大众创新万众创业,在移动互联网的风口,移动APP开发与测试发展方兴未艾,受到了越来越多的重视.相较 iOS,Android 的开发环境更加开放.Android 开发者要测试应用时,只需发个 APK 安 ...
- Golang fmt包使用小技巧
h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; te ...
- Xcode9 打包ipa(导出ipa测试包)时总是意外退出
今天用xcode9,打包ipa总是意外退出. 正处在测试阶段,所以打的也是测试包 ,路径是:Product -> Archive -> Export -> Save for Ad H ...
- Golang Vendor 包机制 及 注意事项
现在的 Go 版本是 1.8,早在 1.5 时期,就有了 Vendor 包机制,详情可查看博文:“理解 Go 1.5 vendor”. 遇到的问题 个人在使用 Glide 管理 Vendor 包时(附 ...
- golang reflect包使用解析
golang reflect包使用解析 参考 Go反射编码 2个重要的类型 Type Value 其中Type是interface类型,Value是struct类型,意识到这一点很重要 Type和Va ...
随机推荐
- Java实现进程调度算法(一) FCFS(先来先服务)
一.概述 因为这次os作业对用户在控制台的输入输出有要求,所以我花了挺多的代码来完善控制台的显示. 也因为我这次要实现多个类似算法,所以将一些共性单独提取出来作为一个类. 如果只想要和算法有关的核心代 ...
- Java https认证的坑
https单向认证的服务端证书不是权威机构颁发的,网上找了点代码不对https证书进行认证后,报如下异常 javax.net.ssl.SSLHandshakeException: Received f ...
- hdu 1392 Surround the Trees 凸包模板
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- Linux下ipv6配置系列
Linux下ipv6配置系列一:如何配置Linux系统ipv6环境 Linux下ipv6配置系列二:如何为Nginx添加ipv6模块 Linux下ipv6配置系列三:如何为Nginx配置IPv6端口监 ...
- canvas toDataURL() 方法如何生成部分画布内容的图片
HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI .可以使用 type参数其类型,默认为 PNG 格式.图片的分辨率为96dpi. 如果画布的高 ...
- 利用PIE实现全球云分布图的效果
1.问题背景: 最近项目中获得了一份全球云分布图,客户要求把云显示在全球地图上,出现云的效果,如下图所示: [全球云分布图] [世界地图云示意图] 2.解决思路 咨询专业的业务人员,建议我测试下试试地 ...
- LintCode2016年8月8日算法比赛----等价二叉树
等价二叉树 题目描述 检查两棵二叉树是否等价.等价意思是说,首先两棵二叉树必须拥有相同的结构,并且每个对应位置上的节点上的数据相等. 样例 1 1 / \ / \ 2 2 and 2 2 / / 4 ...
- C++学习笔记(4)----模板实参推断
1. 如图所示代码,模板函数 compare(const T&, const T&) 要求两个参数类型要一样. compare("bye","dad&qu ...
- 数据迁移:MSSQL脚本文件过大,客户端没有足够的内存继续执行程序
在CMD窗口(俗称:黑屏程序) 下输入 SQLCMD 命令 命令格式如下: sqlcmd -U 用户名 -P 密码 -S 服务器地址 -d 数据库名称 -i 你的脚本文件.sql ( ...
- 关于Angular中时间戳的计算
前言 使用的是Moment.js 插件,插件的安装详情请参考官方网址(https://momentjs.com/) 正文 步骤一:引用import * as moment from 'moment'; ...