
正文
go语言做接口测试 go语言接口自动化
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
gRPC服务开发和接口测试初探「Go」
之前写过了Grpc服务开发和接口测试初探【Java】,中间耽搁了一些时间,Go版本的gRPC测试开发实践才有时间学习使用。其中也是由于自己Go语言不够熟悉导致的。之前有段时间想暂时放弃Go语言的学习,导致了Go的生疏,原因是从Groovy到Java性能。
回归正题,Go语言版本的gRPC实践相对Java来说是比较简单的,但是总体的工具链是比较复杂的,可能是因为Go生态目前相比Java还是比较匮乏吧。下面我先简述一下大致的步骤:
以上步骤亲自操作可能会遇到一些小问题,我本人搜到的教程什么的也是乱七八糟,踩了一些坑。我没有整理出一个亲自实践之后的可行的教程,原因有二:
Go语言的gRPC的 proto 编写跟Java大致一致,只有一个报名的参数不太一样。下面是我的 Hello.proto 内容:
这里主要 go_package 网上搜到的配置方式有些不一样,我没有全都尝试,大家在搜索的资料时候,尽量先看看 syntax 这个参数的值,以及文章教程写作的时间,如果距离现在太久了,我建议直接关掉。搜索引擎有过滤功能,可以过滤掉过时的教程。
这里Go语言gRPC的一点优势,就是在一个项目中即可实现,Java需要先弄一个SDK这样。Go语言的gRPC的代码可以通过生成代码命令中的参数实现指定路径。我是放在了和 proto 文件的同级目录。
服务端代码也是比较格式化的内容,如下:
其中 pb.RegisterHelloServiceServer(s, Ser{}) 如果报错,请检查自己安装的工具 protoc-gen-go 或者 protoc-gen-gofast 版本,一般提取报错 message 搜索也能得到解决办法。
下面是客户端的代码,由于学艺不精,其中大部分参数的含义目前我也不是很清楚,特别是基于 stream 的请求响应的方式使用。后面我先把Java的学完,再回过头来看Go的,按照这个顺序学习和分享。
服务端输出:
忘记打日志了。没有输出
客户端输出:
Go语言的gRPC测试开发实践已经完事儿,大概率上我不会在工作中使用Go作为主力gRPC测试语言,后面测试实践内容还是会以Java为主。
相关问答
Q1: golang reflect反射(一):interface接口的入门(大白话)
这是它的优点,因为编译器在编译时不去确定你传的到底是什么类型,你传一个string,它能接收,你传一个对象struct,它也能接收,它只有一个要求,实现我要求实现的方法!
既然interface是不限定类型,是通用类型,这是一种开放表现,这种开放怎么实现的呢?方法就是不去检验你的类型,既然不检验那也不去记录你的类型!!!!注意interface不记录你的类型,所以不管你是string,struct,int,我都不管,我都不记录,我只记录你的地址,结果是编译器在编译时也不知道你是什么类型,你有什么字段!
但是现在有一个问题,编译器也没办法确定一个interface以前是什么类型!(编译时)这就是因果关系:为了达到通用,interface不做确定工作,结果就是interface也不知道以前的类型。
一个类型转接口的过程,就是放弃自我类型的过程,变成了没有类型。
这样做有什么好处呢,很显然是:通用,如果把一个函数的传入参数设置为空接口(interface{}),那么任何类型当做参数都能够调用该接口,最好的例子就是:
它就是一个很标准的例子,println传入参数可以是任何类型,都能打印出它的值。
当然你可以说你记得,因为是你把它转换成interface,你理所当然的记得,可编译器不知道啊,interface不包含类型,也就是说你没有让它去记录,所以它不知道。
针对这个问题,go语言给了一个解决方案,断言,当将一个interface转换成它原来类型的时候,在它后面指明它的原来类型,这样编译器就知道该按照什么类型去解析了。(其实说白了,这就是通过人的记忆,编译器不知道是什么类型,你告诉编译器就可以了)
断言其实是先获取interface的动态类型,然后与你指定的类型做判断,如果一致,将它转换成你指定的类型。如果不知道动态类型,可以看这篇文章:
从报错可以看出, 不能直接转换,需要对接口先进行断言
通常情况下,一个变量在确定类型的情况下编译器知道他有哪些功能(注意,这里是针对编译时),比如一个int类型,编译器在编译时知道能对他加减int,不能加减float,如果你这么做我就给你报错。一个struct包含哪些字段,不包含哪些字段,我定义一个user结构体,里面只有name和age两个字段,那么你只能取我这两字段的值,你如果取height,我就给你报错。
这些都是正常情况下的,但是对于一个接口呢,编译器会变成瞎子!在编译的时候它不知道你原来是什么类型,所以它也没法确定你包含什么字段,同样是之前那个user结构体,当把它转换成接口以后,编译器就对它的类型一无所知了,你获取name字段,这有接口有没有呢?编译器不知道!你请求height字段,这个泛型有没有呢?编译器仍然不知道。所以你编译时不能修改接口里的数据,既然编译时 不能修改,那就只能在运行时修改了。
这个时候就该反射登场了,它能够在运行时修改接口的数据,通过追根溯源,获取接口底层的实际数据和类型,让你能够对接口的源数据进行操作。
换一种大白话的说法,反射就是刨根问底,获取这个接口究竟是怎么产生的,因为哪怕一个类型转变成接口时放弃了自己的类型,但是它的本质不会变的,就像赵本山的小品里所说:小样,别以为你脱掉马甲我就不认识你了!对,它的底层里仍然存储了它的数据类型,只是藏的比较深,一般手段拿不到,但我们仍然能够通过反射(这个包根问底的工具)来确定你究竟包含哪些字段和值,确定你究竟是蛇还是脱了马甲的乌龟!
Q2: Go语言使用gorm对MySQL进行性能测试
之前写过了Go语言gorm框架MySQL实践,其中对gorm框架在操作MySQL的各种基础实践,下面分享一下如何使用gorm框架对MySQL直接进行性能测试的简单实践。
这里我使用了一个原始的Go语言版本的 FunTester 测试框架,现在只有一个基本的方法,实在是因为Go语言特性太强了。框架设计的主要思路之一就是利用Go语言的闭包和方法参数特性,将一个 func() 当做性能测试的主题,通过不断运行这个 func() 来实现性能测试。当然还有另外一个思路就是运行一个多线程任务类,类似 Java 版本的 com.funtester.base.constaint.ThreadBase 抽象类,这样可以设置一些类的属性,绑定一些测试资源,适配更多的测试场景。
下面演示select的性能测试,这里我用了随机ID查询的场景。
这里我使用从35开始递增的ID进行删除。
这里使用了select的用例部分,随机ID,然后更新name字段,随机10个长度的字符串。
这里用到了 FunTester 字段都是随机生成。
到这里可以看出,性能测试框架用到的都是gorm框架的基础API使用,这里MySQL连接池的管理工作完全交给了gorm框架完成,看资料说非常牛逼,我们只需要设置几个参数。这个使用体现很像 HttpClient 设置 HTTP 连接池类似,这里我们也可以看出这些优秀的框架使用起来都是非常简单的。
PS:关于gorm的基础使用的请参考上一期的文章Go语言gorm框架MySQL实践。
Q3: Golang入门到项目实战 | golang接口
接口像是一个公司里面的领导,他会定义一些通用规范,只设计规范,而不实现规范。
go语言的接口,是一种新的类型定义,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
语法格式和方法非常类似。
在接口定义中定义,若干个空方法。这些方法都具有通用性。
下面我定义一个USB接口,有读read和写write两个方法,再定义一个电脑Computer和一个手机Mobile来实现这个接口。
USB接口
Computer结构体
Mobile结构体
Computer实现USB接口方法
Mobile实现USB接口方法
测试
运行结果
下面我们定义一个OpenClose接口,里面有两个方法open和close,定义个Door结构体,实现其中一个方法。
Q4: 轻松使用Locust & 与Jmeter对比
在做接口性能测试go语言做接口测试的时候也使用过几个工具go语言做接口测试:AB、Jmeter、Locust、Vegeta。
这几个工具中go语言做接口测试,应该当属Jmetergo语言做接口测试的功能最强大go语言做接口测试,使用的人也最多,但使用上也比较繁琐,如果测的接口比较单一,需要得到的值也就是并发量、每秒请求数、响应时间这三个的话,那就推荐使用个简单点儿的工具。在这儿主要介绍Locust,原因无非是使用简单,另外在web界面能实时显示性能测试情况,可以随时调整参数,也支持分布式。
使用Locust也需要编写脚本,对于不熟悉Python的人来说,又是一个障碍。为此笔者编写了一个工具 Easy-Locust ,Locust的几种使用方式都有,并且参数和Locust也保持一致,需要操作的就是在Excel中编辑好参数就行。
GitHub: Easy-Locust
执行下面命令会自动安装easy-locust及locustio=0.13.5的版本
此处只介绍和Locust不同的地方,如果想了解详细参数,请查阅: Locustio
一共4个sheet页,逐一进行介绍
除了可以从Header中获取token外还可以从json中获取,格式为 Json: body.token ,获取到的值会在调用接口时填充到header中,这个地方在Excel demo文件中无法配置,如果要改的话,可以生成locustfile文件,然后小改一下locustfile文件即可。
注意:需要指定 -d 参数才可生效;各压测机中需要提前安装好相同版本的locustio=0.13.5
如果希望使用多个用户信息随机进行压测则可以使用此功能。
这篇比较的文章比较不错,贴一下: 性能测试工具Locust和JMeter比较 ,文章中提到并发用户数那,jmeter和locust实现的机制不一样,所以测得的值也是有差别的,一般同样并发数下jmeter的每秒请求数更高一些。
Locust开启服务只占用一个进程,如果机器是多核的,则可以开启master-slave模式,开一个master,剩下几核就开启几个slave,充分利用机器性能。下图是在本地笔记本(虚拟4核)上执行的 普通模式 和 master-slave模式 的对比:
master-slave模式下RPS最高值达到了2600,最低值1300,大概稳定在1900左右。
下面是使用Jmeter的一个测试数据:
Throughput峰值达到了3000,最低值1900,后续稳定在2200左右,但出现了报错,不过服务端那并没有报错。
上面三张图对比,可以看出在单核机器上如果使用Jmeter和Locust的话测得的数据应该相差不大,多核机器上Locust需要使用master-slave模式才能达到Jmeter的性能。不过说到底,两者之间对并发用户数的实现是不同的,测得的数据必定有差值。
性能调优或测个粗指标的话,十八般工具都可以用,只要保证一直使用同一个工具测就行了。如果测精细指标的话,还得是工业级别的工具/测试仪来完成。
另外Locust + Boomer在相同并发数的情况下,RPS比Jmeter还要高,得益于Go语言天生的优势,可以直接使用Boomer示例中的client文件,获取编译好的文件及简单使用方法点击下面链接:
;sub=683B4DBECED3468CACFC386E51F8B33E
Q5: GO语言(十八):模糊测试入门(下)-
Reverse为了解决这个问题,如果输入不是有效的 UTF-8 ,让我们返回一个错误。
a.在您的文本编辑器中,将现有Reverse函数替换为以下内容。
如果输入字符串包含无效的 UTF-8 字符,此更改将返回错误。
b.由于 Reverse 函数现在返回错误,因此修改main函数以丢弃额外的错误值。将现有main功能替换为以下内容。
这些调用Reverse应该返回一个 nil 错误,因为输入字符串是有效的 UTF-8。
c.您将需要导入错误和 unicode/utf8 包。main.go 中的 import 语句应如下所示。
d.修改reverse_test.go文件检查是否有错误,如果返回产生错误则跳过测试。
除了返回之外,您还可以调用t.Skip()以停止执行该模糊输入。
a.使用 go test 运行测试
b.使用go test -fuzz=Fuzz进行模糊测试,几秒钟后,停止用ctrl-C模糊测试。
除非您通过-fuzztime标志进行限制,否则模糊测试将一直运行,直到遇到失败的输入。如果没有发生故障,默认是永远运行,并且可以使用 中断该过程ctrl-C。
c. 使用go test -fuzz=Fuzz -fuzztime 30s。如果没有30 秒发现失败,它会在退出模糊测试。
模糊测试通过了!
做得很好!您刚刚学习了在 Go 中进行模糊测试。
— main.go —
— reverse_test.go —
关于go语言做接口测试和go语言接口自动化的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。






