开头
中秋节突发奇想,尝试说能不能搞出通用点的游戏协议测试的工具,撸了一天代码。 越写越感觉少了什么,由于本人工作经验较浅,所以希望大佬指教一波
这边在开发过程,产生了一些问题:
1、各位大佬,平常在做游戏接口测试是怎么做的呢?我在想要不直接走 jmeter,然后自己这边选择开发波插件会不会更加容易接入呢?大佬们,你们在选择这类工具中会注重的是什么呢?我这边的考虑就是说尽量避免增加开发的工作量,只要开发给 proto 文件和编解码方法,剩下的就让我们自生自灭即可
2、因为游戏接口除了方式不一样外,其实和 http 接口测试没啥差别,可能需要再考虑下服务端会主动推协议和预期协议的捕获这类的。写的工具也参考了 Python 那一块接口测试的东西
3、最后问一个非常实际的问题,有没有大佬在实际工作中开展过,游戏接口自动化测试,然后比较成功的那种。我怎么总觉得收益不大,游戏版本迭代太快了,真的有必要搞么?文章源自玩技e族-https://www.playezu.com/239506.html
游戏接口测试
- 正常情况,游戏接口测试都是走 TCP 协议,数据传输类型应该大多数都是 Protobuf 格式才对,应该只有些历史项目会用 JSON 或 xml 之类的吧 (没做过调查,单纯的猜测),自定义格式的话,应该只有极少极少数会这么搞吧就不考虑了。目前我这边目前就只考虑 Protobuf 格式,tcp 链接。
- 每个公司都会有自己的一个数据传输规范,但既然走 TCP 和 Protobuf,就一定逃不掉 TCP 的头部要带有请求协议的协议 ID(能够让服务端知道后边的这一条数据对应的 proto 消息是哪一条的 id),及包体长度,序列号等 (我想了很久,tcp 头部必须带请求协议的协议 id 这应该是绕不掉的,如果还有其他的特殊情况,大佬给告知一下)。除此之外,服务端需要对数据做相应编解码。
故综上所述,这款工具接入准备有:文章源自玩技e族-https://www.playezu.com/239506.html
- proto 文件
- 编解码方法
- 请求协议和协议 id
github 地址:https://github.com/OwnSecurityGuard/gameProtoTest
目前只是个 demo,比较粗糙文章源自玩技e族-https://www.playezu.com/239506.html
先直接说一下,我这工具的两个设想:文章源自玩技e族-https://www.playezu.com/239506.html
- web 项目, 一开始是打输直接搞成 web 项目,在 web 页面操作,在浏览器上输入协议名,及其对应参数,后台去维护一条连接的方式,但后边实操下来,操作略微繁琐 (对前端要求较高,但这边也简单实现了一版,使用 postman 的 websocket 也搞一波,但操作起来比较难)
- 脚本形式 后边想了想就搞成了以 yaml 配置文件的方式来进行。可以通过在 Yaml 上做配置,依赖 goconvey 自带的 web 页面来实现接口测试和管理
工具的基本逻辑:
解析 yaml 文件的数据, 加载 Proto 文件,依据协议名,还有参数,先使用参数构造 json 数据,再将 json 数据转为 protobuf 格式,发送。以单测的形式运行,去生成对应的用例,不用编写单测,只需编写 yaml 即可构造用例,而且 goconvery 功能非常好用,可以以 web 的形式展示用例,和运行。目前这一块断言还没有完全完成,估计得到国企才有空 了。。。
实现方法 (永远的调包侠,yyds)文章源自玩技e族-https://www.playezu.com/239506.html
- 使用第三方库 github.com/jhump/protoreflect 对 proto 消息进行一个动态的解析,即把 json 数据和 proto 数据的一个互转,依据协议名称得到协议结构等等
- 使用第三方库 github.com/traefik/yaegi ,动态加载编解码方法,原本是打输用动态链接的方式实现,这样其他语言只要使用对应的方法格式,编译成对应的文件,golang 能够动态调用,但奈何 go 的这一块的东西目前还不完善,无法做到类似热更新的方式(我要是用 java 就好搞了。。。)。
编解码方法的格式我这边定为了文章源自玩技e族-https://www.playezu.com/239506.html
Encode func(data [] byte, mesId int32, seqId int32,s ...string)([] byte,error) 编码方法
文章源自玩技e族-https://www.playezu.com/239506.html
Decode func(conn net.Conn)(tarData [] byte, seqId int32,msgId int32) 解码方法
非常粗略,感觉抽象程度不够,还不够通用,之后还细化一下,但感觉应该能满足需求了
github 地址:文章源自玩技e族-https://www.playezu.com/239506.html
使用说明
安装 go 1.16
安装 goconvey
go get github.com/smartystreets/goconvey
项目根目录 go mod tidy 一下
一切就绪后,
1、修改 first.yaml 文件的文件路径,建议改成绝对路径,所需文件均在 service 目录下。
2、 修改 tcp.go 文件中的 YamlFilePath,改为项目中的 first.yaml 的绝对路径
3、 运行 service 下 testSec 的 main.go 文件,可直接在改文件目录下,go run main.go
4、 在目录下,直接运行 goconvey, 进入页面 127.0.0.1:8080.即会开始加载 yaml 进行测试
目前这边工具使用了 Go 语言开发文章源自玩技e族-https://www.playezu.com/239506.html
ProjectName: "firstTest" ## 项目名,目前什么用都没有,
ProtoPath: "testSec" ## proto文件存放目录路径 建议修改成绝对路径
MesIdPath: "data.csv" ## 协议名对应协议id
CodecPath: "debugCodec.txt" ## 编解码方法
ServerHost: "127.0.0.1:9791" ## 服务器地址
Proto:
-
name: LoginReq ## 测试协议的协议名
param:
name: "username1" ## 参数 若是有嵌套关系,可 a.m: 23 == {"a":{"m":23}}
password: "password2"
asserts: # 断言 ,目前未实现
-
ProtoName: LoginResp # 响应的协议
Check:
-
key: greet
expectVal: 1234
最后还成功搞出个 Bug(看来得国庆再来修一波了。。。)
未知地区 2F
protobuf 自带 json 转换的
未知地区 1F
首先呢,游戏既然是软件,就同样遵循软件的测试方法和流程。
1.平常在做游戏接口测试是怎么做的呢?我在想要不直接走 jmeter,然后自己这边选择开发波插件会不会更加容易接入呢?
直接使用 JMeter,不做别的开发。
2.因为游戏接口除了方式不一样外,其实和 http 接口测试没啥差别
是的,和 http 接口测试差别不大,除了协议可能不一样。
3.我怎么总觉得收益不大,游戏版本迭代太快了,真的有必要搞么?
游戏版本迭代快,只要是新需求引起的而不是已有需求频繁变更引起的,自动化测试可能收益更大 (迭代快则脚本执行轮数多)。是否有必要搞自动化,需要对软件所处阶段、团队自动化测试技术能力、预期收益及公司支持力度进行综合考虑。