自动生成测试脚本方案浅析
自动生成测试脚本方案浅析
转载自 www.sohu.com/a/224590187_748431
自动生成测试脚本方案浅析
原标题:自动生成测试脚本方案浅析
文:玉婷
本文原创,转载请注明作者及出处构想篇
作为一名接口自动化测试工程师,日常面临最多的工作就是编写接口自动化测试脚本,那么,在 coding 的过程中最让你觉得枯燥和乏味事情有哪些?
痛点
- 每次拿到新接口,我们要手动参照文档在脚本中生成一份接口类,参数越多花费时间越多
- 需求不同,但健壮性和部分业务用例重复性高
- 想重构脚本,接口数据和用例这块纯编写的工作量就会让人望而怯步
每天都要花上30%的时间去写那些不太需要思考的脚本,这真不够自动化!
解决方案
- 解析文档
- 梳理适合自动生成的脚本
- 通过工具生成这部分脚本
预期目标
解放双手,降低纯手力劳动占比,进而给自己提供更多的时间去思考、理解产品和设计更多“聪明”的用例
实践篇 自动化获取接口信息 分析接口自动化脚本结构和内容
自动化测试脚本结构图
筛选工作量大又有规律可循的脚本
此处规律不宜太过于复杂,可先选逻辑简单的部分,我们主要选取以下两部分
- 接口类,工作时间占比30%~50%,特点:结构特定、数据来源于其它平台
接口类结构图
- 用例部分,工作时间占比30%~50%,特点:重复度高于80%左右、生成逻辑可描述
用例结构图
解析接口文档
接口信息来源于接口文档,目前市场上比较主流的几个接口文档管理工具有Swagger、RAP、WIKI 或者其他普通文档工具。
下面以解析接口文件为目的分析比较下几款工具的区别:
.
分类 | Swagger | RAP | WIKI |
---|---|---|---|
描述 | 用于生成、描述、调用和可视化RESTful风格的Web服务的框架 | 可视化接口管理工具 | 可供多人协同创作的超文本系统 |
格式 | json | json | html |
规范 | 各个参数、返回值的具体结构、类型有统一规范 | 同swagger | 需要自己约定规范 |
成本 | 直接嵌入项目中,通过开发时编写注释,自动生成接口文档,成本较低 | 需要开发按照平台规则手动输入,成本较高 | 需要按照约定规范,手动输入,成本较高 |
如果有条件,大家可以根据开发成本和解析接口文件的难易程度来综合考虑,确定使用哪个平台管理接口
我们项目是 Swagger 和 WIKI 混合使用,由于日常测试看 WIKI 居多,因此早期采用 Python 爬虫利器 BeautifulSoup 来解析WIKIhtml页面
- from bs4 import BeautifulSoup
- soup = BeautifulSoup(html_doc)
- title_string = soup.title.string
- # 后面继续解析其他需要用到的接口内容
使用下来发现通过wiki来获取接口信息的一些弊端
- 完全靠人工来约束书写规则不靠谱
- 对于复杂的嵌套参数,稍有不按照规范来的,就会导致脚本解析错误,很大程度上造成了解析的难度
- 在html上准确的定位信息远比在json上难度大,兼容性差
于是,尝试解析Swagger返回的json来获得接口信息为后面生成脚本做准备
- {
- "swagger": "2.0",
- "host": "xxx",
- "basePath": "/",
- "tags":[
- {"name":"xxx-controller","deion":"xxx"},
- ...
- ],
- "paths": {
- "<接口地址1>": { ... },
- "<接口地址2>": { ... },
- ...
- },
- "definitions": {
- "<实体类1>": { ... },
- "<实体类2>": { ... },
- ...
- }
- }
使用以下方式拿到json结果后,就可以直接按照处理字典的方式来获取需要的内容。
- graph LR
- json-->ApiObj
对于swagger.json的解析和代码生成官方也提供了一些可供使用的库swagger-codegen (java),由于编程语言的限制,我们使用了python自己解析
现在,我们已拿到生成代码所需要的信息
自动生成代码 代码生成工具
- class CodeGeneratorBackend():
- def begin(self, tab="t"):
- self.code = []
- self.tab = tab
- self.level = 0
- def end(self):
- # return string.join(self.code, "")
- return "".join(self.code)
- def write(self, string):
- self.code.append(self.tab * self.level + string)
- def indent(self):
- self.level = self.level + 1
- def dedent(self):
- if self.level == 0:
- raise SyntaxError("internal error in code generator")
- self.level = self.level - 1
- """调用方法,开始生成代码"""
- c = CodeGeneratorBackend()
- c.begin(tab=" ") # 定义缩进方式
- c.write("def function(self):n")
- c.indent() # 缩进
- # 方法体
- c.dedent() # 回退上一次缩进
接口类部分脚本生成规则
由于我们接口属于是存储在类结构中,因此根据当前脚本的API Object接口进行遍历替换即可
接口用例部分代码生成规则
特殊值用例
给每个参数生成为0、None、空字符串这样特殊值的用例
定位参数类型
通过接口参数给出的类型,生成符合该类型的值,和一些不符合参数类型的值(健壮性),赋值后生成用例,如下代码示例
定位特定关键词参数
- 遇到page相关参数可生成分页用例,具体分页测试用例细节就不赘述
- 遇到类似starttime,endtime参数,可生成两个时间参数和当前时间前后比较的用例,两个时间参数前后比较的用例
该生成规则需要和开发约定一些基本原则,另外也需要我们在日常测试中多归纳总结,找出那些有固定规律的用例,想办法定位生成这类用例
定位接口类型
- 查询类接口:可生单参数查询、组合参数查询、全参数查询等用例
- 更新类接口:可生成单条更新每个参数,组合更新,全量更新等用例
自动生成测试脚本工具介绍 框架流程图
工具扩展性
- 用例生成规则可扩展,从框架图中可以看到,用例规则这快自成独立模版,可单独维护,便于后续新规则的加入
- 代码模版可扩展,不同团队对于代码规范、基础模版的样式都不一样,可自定义生成模版的样式,增加了工具的灵活性
- 支持多种数据类型转换,后续可扩展生成API对象、参数字典或其他数据模式
成果和后续行动 效率提升
以一个优惠券需求为例,大约新增/更新了10个接口(约150个参数请求参数,100个返回参数),包含增删改查几种类型,编写加调试脚本在使用工具前后所花费时间对比,如下:
类型 | 工作量描述 | 不使用工具 | 使用工具 | 效率提升 |
---|---|---|---|---|
接口类 | 约250个参数 | 2日/人 | 1小时内 | 94% |
健壮性用例 | 约1000条用例 | 2日/人 | 1日/人 | 50% |
平均 | --- | --- | --- | 74% |
从上例可以看出使用脚本后的效率提高了近一半,而从设计到编写完第一版工具仅花费了2~3个工作日,还是非常值得一做的。
聚焦测试
- 脚本编写工作量的减少,会增加产品测试思考的时间,完善用例,检查覆盖面等
统一规范
- 统一了接口类输写规范,便于团队内部维护和理解脚本
- 统一基本用例生成思路,规避测试工程师在设计基本用例设计时有所遗漏;统一用例输出格式,便于他人理解和维护用例
重构利器
- 如果有计划做脚本重构,使用工具后可以成倍的节省编写接口信息和用例部分脚本的时间
后续迭代优化点
- 目前用例的生成思路大多还局限在单参数上,多参数的生成思路还较少,后续会通过头脑风暴等形式来扩展更多的用例的生成思路
- 通过实际调用接口,获取结果,提高自动生成用例期望结果的准确性,继而节省更多对部分期望结果做调整的时间投入
最后想说的是,这个小工具的设计思路远比实现更重要,无论使哪种语言或库都可以实现解析文件和代码的生成,重要得是按照怎样的思路去生成脚本,在这部分上后续我们也有很多需要摸索的地方。
手把手教你开发一个 Webpack Loader
Android.Arch.Paging: 分页加载的新选项
React Native 网络层分析
如何实现VM框架中的数据绑定
探索自动化测试的高效执行返回搜狐,查看更多