go测试--进阶
前言
go test有非常丰富的参数,一些参数用于控制测试的编译,另一些参数控制测试的执行。
有关测试覆盖率、vet和pprof相关的参数先略过,我们在讨论相关内容时再详细介绍。
控制编译的参数
-args
指示go test把-args后面的参数带到测试中去。具体的测试函数会根据此参数来控制测试流程。
-args后面可以附带多个参数,所有参数都将以字符串形式传入,每个参数作为一个string,并存放到字符串切片中。
// TestArgs 用于演示如何解析-args参数
func TestArgs(t *testing.T) {
if !flag.Parsed() {
flag.Parse()
}
argList := flag.Args() // flag.Args() 返回 -args 后面的所有参数,以切片表示,每个元素代表一个参数
for _, arg := range argList {
if arg == "cloud" {
t.Log("Running in cloud.")
} else {
t.Log("Running in other mode.")
}
}
}
执行测试时带入参数:
$ go test -run TestArgs -v -args "cloud"
TestMain setup.
=== RUN TestArgs
--- PASS: TestArgs (0.00s)
unit_test.go:28: Running in cloud.
PASS
TestMain tear-down.
ok gotest 0.353s
通过参数-args指定传递给测试的参数。
-json
-json 参数用于指示go test将结果输出转换成json格式,以方便自动化测试解析使用。
如下输出
$ go test -run TestAdd -json
{"Time":"2019-02-28T15:46:50.3756322+08:00","Action":"output","Package":"gotest","Output":"TestMain setup.\n"}
{"Time":"2019-02-28T15:46:50.4228258+08:00","Action":"run","Package":"gotest","Test":"TestAdd"}
{"Time":"2019-02-28T15:46:50.423809+08:00","Action":"output","Package":"gotest","Test":"TestAdd","Output":"=== RUN TestAdd\n"}
{"Time":"2019-02-28T15:46:50.423809+08:00","Action":"output","Package":"gotest","Test":"TestAdd","Output":"--- PASS: TestAdd (0.00s)\n"}
{"Time":"2019-02-28T15:46:50.423809+08:00","Action":"pass","Package":"gotest","Test":"TestAdd","Elapsed":0}
{"Time":"2019-02-28T15:46:50.4247922+08:00","Action":"output","Package":"gotest","Output":"PASS\n"}
{"Time":"2019-02-28T15:46:50.4247922+08:00","Action":"output","Package":"gotest","Output":"TestMain tear-down.\n"}
{"Time":"2019-02-28T15:46:50.4257754+08:00","Action":"output","Package":"gotest","Output":"ok \tgotest\t0.465s\n"}
{"Time":"2019-02-28T15:46:50.4257754+08:00","Action":"pass","Package":"gotest","Elapsed":0.465}
-o
-o 参数指定生成的二进制可执行程序,并执行测试,测试结束不会删除该程序。
没有此参数时,go test生成的二进制可执行程序存放到临时目录,执行结束便删除。
如下:
$ go test -run TestAdd -o TestAdd #编译成二进制文件
TestMain setup.
PASS
TestMain tear-down.
ok gotest 0.439s
$ TestAdd # 直接使用二进制文件运行测试
TestMain setup.
PASS
TestMain tear-down.
本例中,使用-o 参数指定生成二进制文件”TestAdd”并存放到当前目录,测试执行结束后,仍然可以直接执行该二进制程序。
控制测试的参数
-bench regexp
go test默认不执行性能测试,使用-bench参数才可以运行,而且只运行性能测试函数。
其中正则表达式用于筛选所要执行的性能测试。如果要执行所有的性能测试,使用参数-bench .或-bench=.。
此处的正则表达式不是严格意义上的正则,而是种包含关系。
比如有如下三个性能测试:
- func BenchmarkMakeSliceWithoutAlloc(b *testing.B)
- func BenchmarkMakeSliceWithPreAlloc(b *testing.B)
- func BenchmarkSetBytes(b *testing.B)
使用参数-bench=Slice,那么前两个测试因为都包含Slice,所以都会被执行,第三个测试则不会执行。
对于包含子测试的场景下,匹配是按层匹配的。举一个包含子测试的例子:
func BenchmarkSub(b *testing.B) {
b.Run("A=1", benchSub1)
b.Run("A=2", benchSub2)
b.Run("B=1", benchSub3)
}
测试函数命名规则中,子测试的名字需要以父测试名字作为前缀并以/连接,上面的例子实际上是包含4个测试:
- Sub
- Sub/A=1
- Sub/A=2
- Sub/B=1
如果想执行三个子测试,那么使用参数-bench Sub。如果只想执行Sub/A=1,则使用参数-bench Sub/A=1。如果想执行Sub/A=1和Sub/A=2,则使用参数-bench Sub/A=。
-benchtime s
-benchtime指定每个性能测试的执行时间,如果不指定,则使用默认时间1s。
例如,执定每个性能测试执行2s,则参数为:go test -bench Sub/A=1 -benchtime 2s。
-cpu 1,2,4
-cpu 参数提供一个CPU个数的列表,提供此列表后,那么测试将按照这个列表指定的CPU数设置GOMAXPROCS并分别测试。
比如-cpu 1,2,那么每个测试将执行两次,一次是用1个CPU执行,一次是用2个CPU执行。
例如,使用命令go test -bench Sub/A=1 -cpu 1,2,3,4 执行测试:
BenchmarkSub/A=1 1000 1256835 ns/op
BenchmarkSub/A=1-2 2000 912109 ns/op
BenchmarkSub/A=1-3 2000 888671 ns/op
BenchmarkSub/A=1-4 2000 894531 ns/op
测试结果中测试名后面的-2、-3、-4分别代表执行时GOMAXPROCS的数值。 如果GOMAXPROCS为1,则不显示。
-count n
-count指定每个测试执行的次数,默认执行一次。
例如,指定测试执行2次:
$ go test -bench Sub/A=1 -count 2
TestMain setup.
goos: windows
goarch: amd64
pkg: gotest
BenchmarkSub/A=1-4 2000 917968 ns/op
BenchmarkSub/A=1-4 2000 882812 ns/op
PASS
TestMain tear-down.
ok gotest 10.236s
可以看到结果中也将呈现两次的测试结果。
如果使用-count指定执行次数的同时还指定了-cpu列表,那么测试将在每种CPU数量下执行count指定的次数。
注意,示例测试不关心-count和-cpu参数,它总是执行一次。
-failfast
默认情况下,go test将会执行所有匹配到的测试,并最后打印测试结果,无论成功或失败。
-failfast指定如果有测试出现失败,则立即停止测试。这在有大量的测试需要执行时,能够更快的发现问题。
-list regexp
-list 只是列出匹配成功的测试函数,并不真正执行。而且,不会列出子函数。
例如,使用参数”-list Sub”则只会列出包含子测试的三个测试,但不会列出子测试:
$ go test -list Sub
TestMain setup.
TestSubParallel
TestSub
BenchmarkSub
TestMain tear-down.
ok gotest 0.396s
-parallel n
指定测试的最大并发数。
当测试使用t.Parallel()方法将测试转为并发时,将受到最大并发数的限制,默认情况下最多有GOMAXPROCS个测试并发,其他的测试只能阻塞等待。
-run regexp
根据正则表达式执行单元测试和示例测试。正则匹配规则与-bench 类似。
-timeout d
默认情况下,测试执行超过10分钟就会超时而退出。
如,我们把超时时间设置为1s,由本来需要3s的测试就会因超时而退出:
$ go test -timeout=1s
TestMain setup.
panic: test timed out after 1s
设置超时可以按秒、按分和按时:
- 按秒设置:-timeout xs或-timeout=xs
- 按分设置:-timeout xm或-timeout=xm
- 按时设置:-timeout xh或-timeout=xh
-v
默认情况下,测试结果只打印简单的测试结果,-v 参数可以打印详细的日志。
性能测试下,总是打印日志,因为日志有时会影响性能结果。
-benchmem
默认情况下,性能测试结果只打印运行次数、每个操作耗时。使用-benchmem则可以打印每个操作分配的字节数、每个操作分配的对象数。
// 没有使用-benchmem
BenchmarkMakeSliceWithoutAlloc-4 2000 971191 ns/op
// 使用-benchmem
BenchmarkMakeSliceWithoutAlloc-4 2000 914550 ns/op 4654335 B/op 30 allocs/op
此处,每个操作的含义是放到循环中的操作,如下示例所示:
func BenchmarkMakeSliceWithoutAlloc(b *testing.B) {
for i := 0; i < b.N; i++ {
gotest.MakeSliceWithoutAlloc() // 一次操作
}
}
go测试--进阶的更多相关文章
- SpringBootTest单元测试实战、SpringBoot测试进阶高级篇之MockMvc讲解
1.@SpringBootTest单元测试实战 简介:讲解SpringBoot的单元测试 1.引入相关依赖 <!--springboot程序测试依赖,如果是自动创建项目默认添加--> &l ...
- [译] Go语言测试进阶版建议与技巧
阅读本篇文章前,你最好已经知道如何写基本的单元测试.本篇文章共包含3个小建议,以及7个小技巧. 建议一,不要使用框架 Go语言自身已经有一个非常棒的测试框架,它允许你使用Go编写测试代码,不需要再额外 ...
- Python测试进阶——(1)安装Python测试相关模块
安装python 安装pip yum -y install epel-release yum -y install python-pip 安装psutil 参考:https://www.cnblogs ...
- Python测试进阶——(7)动手编写Bash脚本启动Python监控程序并传递PID
如下: #./cf_workload_functions.sh function timestamp(){ # get current timestamp sec=`date +%s` nanosec ...
- Python测试进阶——(6)Bash脚本启动Python监控程序并传递PID
用HiBench执行Hadoop——Sort测试用例,进入 /HiBench-master/bin/workloads/micro/sort/hadoop 目录下,执行命令: [root@node1 ...
- Python测试进阶——(5)Python程序监控指定进程的CPU和内存利用率
用Python写了个简单的监控进程的脚本monitor190620.py,记录进程的CPU利用率和内存利用率到文件pid.csv中,分析进程运行数据用图表展示. 脚本的工作原理是这样的:脚本读取配置文 ...
- Python测试进阶——(4)Python程序监控、存储、分析并可视化CPU和内存利用率
monitor190617.py 监控cpu和内存利用率信息,组织成json格式,并写入到 record.txt 文件中: import psutil import time import json ...
- Python测试进阶——(3)编写Python程序监控计算机的服务是否正常运行
用python写了个简单的监控进程的脚本,当发现进程消失的时候,立即调用服务,开启服务. 脚本的工作原理是这样的:脚本读取配置文件,读取预先配置好的调用系统服务的路径和所要监控的服务在进程管理器中的进 ...
- Python测试进阶——(2)配置PyCharm远程调试环境
新建一个Python项目 配置Deployment,用于本地文件和远程文件的同步,在pycharm的菜单栏依次找到:Tools > Deployment > Configuration 点 ...
随机推荐
- POJ1417 True Liars 题解
通过读题,容易发现,当回答为yes时 \(x,y\) 必属于同类,当回答为no时二者必为异类(并且当 \(x=y\) 时,回答必为yes,不过这题不用这个性质). 于是先按关系维护连通块,然后求出每个 ...
- mysql常用sql语法
一.创建主键的三种方式 1. CREATE TABLE user( uid INT PRIMARY KEY, uname VARCHAR(10), address VARCHAR(20) ) 2. C ...
- 华为视频编辑服务(Video Editor Kit),助力开发者高效构建应用视频编辑能力
视频编辑服务(Video Editor Kit)是华为开放给开发者快速构建视频编辑能力的服务,提供视频导入.编辑处理.特效渲染.视频导出.媒体资源管理等一站式视频处理能力.视频编辑服务为全球开发者提供 ...
- JavaScript关于对象的一些小知识
javascript的对象 javascriot(之后用js代替)中基本数据类型之一,是复合类型的数据. 对象在js中应用十分广泛,几乎所有的的事物都是做对象,js的对象拥有自己的属性和方法的数据 在 ...
- 又一本springmvc学习指南 之---第22篇 springmvc 加载.xml文件的bean标签的过程
writedby 张艳涛,今天看spring mvc 学习指南的第2章,特意提下这个作者是how tomcat works 俩个作者之一, 喜欢上一本书的风格,使用案例来讲述原理, 在做第一个案例的时 ...
- AAAI 2021 最佳论文公布
作者:Synced 翻译:仿佛若有光 第三十五届 AAAI 人工智能会议 (AAAI-21) 以虚拟会议的形式拉开帷幕.组委会在开幕式上公布了最佳论文奖和亚军.三篇论文获得了最佳论文奖,三篇被评为 ...
- JIT in MegEngine
作者:王彪 | 旷视框架部异构计算组工程师 一.背景 什么是天元 旷视天元(MegEngine)是一个深度学习框架,它主要包含训练和推理两方面内容.训练侧一般使用 Python 搭建网络:而推理侧考虑 ...
- noip模拟测试10
T1 这道题在考场上想到了二维前缀和,就是自己算前缀和的方式有点麻烦,导致花的时间较长,但还是成功搞了出来. 因为暴力计算的话需要不停枚举左上角和右下角的 i ,j, 时间复杂度为 n^4 ,我当时就 ...
- SQL语句(六)分页查询和联合查询
目录 一.分页查询 语法格式 应用 二.联合查询 语法和作用 特点 应用 UNION和UNION ALL的区别 一.分页查询 语法格式 SELECT 查询列表 FROM 表 WHERE ... GRO ...
- Vue-Router 详细解析学习
首先还是先创项目 然后选择vue-router 再创建 再敲代码学习前,我们先了解什么是路由? 路由有一个非常重要的概念就是路由表: 本质就是一个映射表,决定数据的指向. 我们生活中常常听到的路由器, ...