无论是 Web 系统,仍是移动 APP,先后端逻辑的分离设计已是常态化,相互之间经过 API 调用进行数据交互。在基于 API 约定的开发模式下,如何加速请求 / 响应的 API 测试,让研发人员及早参与到调试中来呢?既然 API 是基于约定开发,为什么不按照这个规范编写测试用例,直接进入待测试状态,使用自动化的方式来推动研发过程的质量改进呢?遵循:测试 -> 重构 -> 测试 -> 重构,这样的闭环,过程产出的质量会更加可控,在重构的同时进行快速的功能回归验证,大大提升效率。下面主要讲解基于 HTTP 协议的 API 测试,从手工测试到平台的演变过程。html
测试团队采用《敏捷脑图用例实践之路》的方式编写测试用例:前端
图 -1- 分计费单元查询带宽面试
优势:算法
要点清晰简洁展示chrome
全部测试故事点通过用例评审,产生质量高,研发参与感强;json
版本同步保持一份后端
API 测试脑图带来的问题:api
脑图用例对测试人员的素质要求至关高数组
完善的脑图用例编写,须要有资深的测试人员,对业务精通、对测试技能精通,很强的思惟能力;若是研发人员仅仅参考这个脑图用例进行测试,每每不少时候须要花费大量的沟通时间,其中有不少测试 API 的过程、措施,在脑图里面没有具体体现,形成一些信息丢失。浏览器
重复执行不变的是规则,变的只是参数,要消灭重复部分
还能够深度优化脑图用例,API 接口规范,再怎么天马行空,也得有个度,应当把重复思考的部分交给工具去作,须要发挥创造力、值得关注部分,交给人工完成;按照这个测试流程,,测试人员编写完用例,去验证 API 接口,若是失败了,打回给研发人员从新修改,可是下一次研发人员提交测试,测试人员又得从新验证一遍,这一遍中实际没有多少有价值的思考,是重复工做,要去挖掘测试价值。另外,若是测试人员请假了,那是否是测试就须要延期了呢?消除等待、消除单点做业,改变是惟一出路,尝试过以下方式:
图 -2-Chrome DHC 组件
组员经过使用 Chrome DHC(是一款使用 chrome 模拟 REST 客户端向服务器发送测试数据的谷歌浏览器插件),进行 API 自动化测试,用例文件保存到本地而且同步到 svn,简单粗暴解决重复请求问题,注意强调的是解决重复请求,并无包括参数和结果的自动化验证的过程,仍是须要人工参与,至少前进了一步,固然咱们也解决了单点问题,其余组员能够更新用例本地运行,还差参数校验,数据校验等等一堆关键业务点要用自动化去突破。
俗话说:术业有专攻,DHC 只是玩玩而已,并不擅长作那么多活,也作很差,更指望的是平台化。
经历了手工测试的繁琐操做,丢弃了简单的 DHC,决定另寻新路,API 测试最简单的场景请求参数组合产生各种别的测试用例。思路很简单,作一个 WEB 平台,登记 API 接口,填写请求参数,对响应结果进行校验,初期进行了技术选型,使用 Django 作 Python Web 开发,后台脚本执行使用开源框架 RobotFramework,RF 优势以下:
是一个通用的关键词驱动自动测试框架;
易于使用的表格数据展示形式,采用关键字驱动的测试方法,使用在测试库中实现的关键词来在测试中运行程序。
是灵活和可扩展的,适合用于测试用户接口;
在这个平台中,RobotFramework 主要用于后台执行 Robot 关键字脚本,而关键字脚本,是平台经过读取 YAML 文件生成,该文件是经过笛卡尔乘积产生的用例,工做原理如图所示:
图 -3- 工做原理
那话说回来,YAML 干什么呢?为何不是 XML 呢?
YAML 的可读性好
YAML 和脚本语言的交互性好
YAML 使用实现语言的数据类型
YAML 有一个一致的信息模型
YAML 易于实现
听起来 YAML 试图用一种比 XML 更敏捷的方式,来完成 XML 所完成的任务。下面经过一段实际例子说明配置生成的 YAML 代码段:
主接口配置界面:
图 -4- 接口配置页面
设置 API 参数:
图 -5- 设置 API 参数
配置文件 byChannelsDaily.yaml(列举一个参数示例):
- byChannelsDaily: # 接口名称 method: get # 与服务器交互的方法 format: json #API 数据格式 url: /reportdata/flux/byChannelsDaily #API 的 URL,与奇台配置文件里面的 host 变量组成整个 URL 的前半部分。 url_path: url_params: #URL 参数部分,固定写法。 username: #API 的参数名。 required: true # 该参数是否必须(true/false)。 value: chinacache # 该参数的值。如此值是从另外一个接口获取的,可在 from_api 设置,此处可不填。若是值是 Boolean,必须加双引号。 type: string # 该参数值的类型。 len: 10 # 该参数值的长度。 max: -100 # 该参数值的最大值。-100 至关于忽略此参数 min: -100 # 该参数值的最小值。-100 至关于忽略此参数 from_api: # 如参数的值是从另外一个接口、global.yaml 中获取的,请设置 from_api,如 global jsonpath: # 可经过 jsonpath 来指定取值范围,如 $.version[2:4] range: response: # 指望结果 verification: success: [] #success 是一个 list, 它的元素也是 list,success[0] = [ RF 关键字 ,验证字段,正则匹配] failure: [] error_msg: [] # 错误信息集合</pre>
测试报告:
图 -6-rf 测试报告
按照这个思路作下来,获得什么收益呢?
自动化
说到这里,其实,真没有带来多少收益,思路对了,可是方向有误差了,主要体如今:
图 -7- 庞大的测试用例文件
败了,就是败了,没什么好找借口,关键问题是:
回到起点,测试要解决什么问题,为何要作 API 自动化测试平台?作这个平台,不是为了知足老板的提倡全民自动化的口号,也不是为了浮夸的 KPI,更不是宣传自动化能够解决一切问题,发现全部 bug。叔本华说过一句话:因为频繁地重复,许多起初在咱们看来重要的事情逐渐变得毫无价值。若是 API 测试仅仅依靠纯手工的执行,很快将会面临瓶颈,由于每个功能几乎都不能是第一次提交测试后就测试经过的,因此就须要反复 bug 修复、验证,以及回归的过程。另外,不少的 API 测试工做手工作起来很是的繁琐,甚至不便,好比针对接口协议的验证、针对返回数据格式的验证,这些都依赖于测试自动化的开展。所以,真正的目的是解放测试人员重复的手工生产力,加速回归测试效率,同时让研发人员在开发过程及早参与测试(自测、冒烟测试),驱动编码质量的提高。
回顾以往,从新梳理头绪,更加清晰的展示:
图 -8-HTTP API 自动化测试图解
HTTP API 传统手工测试
重复请求参数基础校验、正确参数查询返回数据校验,测试工程师没有新的创造价值,不断重复工做,甚至可能压缩其中的测试环节,勉强交付;
HTTP API 自动化测试
重复步骤(请求接口是否有效、参数校验能够做为冒烟测试,研发参与自测)用自动化解决,关键业务步骤数据对比人工参与和 schema 自动化校验;
若是对软件测试、接口测试、自动化测试、性能测试、LR脚本开发、面试经验交流。感兴趣能够175317069,群内会有不按期的发放免费的资料连接,这些资料都是从各个技术网站搜集、整理出来的,若是你有好的学习资料能够私聊发我,我会注明出处以后分享给你们。
最大的收益,重复步骤自动化后,无论是研发人员自测,仍是执行功能回归测试,成本能够很快收回(前提是你这个项目周期长,构建频繁;若是仅仅是跑几个月的项目,真没那个必要凑热闹去自动化,固然有平台的另当别论),测试的关注点会落实到更加关键的业务环节去;
整体规划以下:
[
图 -9-HTTP API 重构规划
技术选型
因为原来的测试平台使用 Python 编写,为了保持风格一致,从界面录入到文件生成处理依然采用 Python、Django,去掉了全对偶组合算法,改成根据测试人员思惟去产生用例;去掉了后台 RobotFramework 框架,采用 Python 的 HTTP 类库封装请求。
HTTP API 项目管理 Web 前台
使用 Python+Django+MySQL 进行开发,分为项目首页、项目配置、API 配置、全局配置四大部分
图 -10- 管理 Web
介绍:列出 API 规范、API 测试用例、定时任务数量,以及某段时间内的测试结果趋势图形。
图 -11- 项目首页
项目配置
重点介绍:全局变量、经常使用方法、验证器。
全局变量
设计思路:在 API 测试过程当中,能够切换生产、测试环境进行对比校验,若是写两套测试用例是冗余,全局变量功能,是一种在执行测试用例时动态改变用例属性的方法。
做用范围:当前项目内
使用方法:{变量名}
能在如下测试用例属性中使用:URL、请求头、请求参数
图 -12- 全局变量配置页
在 API 用例库的 URL 能够直接填写:{host}/reportdata/monitor/getChannelIDsByUserName;当运行测试用例的时候,能够选择不一样的参数套件,后台代码执行会直接替换,这样子能够分别快速验证生产环境和测试环境的 API 接口执行结果的差别。
图 -13- 用例执行页
经常使用方法
√ 设计思路:经常使用方法是一个 Python 函数,对入参进行处理而且返回结果,例如:
gen_md5 做用是生成 MD5,对应代码直接填写:
import hashlib def gen_md5(raw_str): m = hashlib.md5() m.update(raw_str) md5_str = m.hexdigest() return md5_str
√ 应用场景:
在 API 请求中,有些参数例如 pass 须要加密处理,能够经过引入 [经常使用方法] 来解决。
在参数 pass 的值中直接填写:
{{get_apipwd("{123456}","ChinaCache")}}</pre>
图 -15- 接口配置页
验证器
√ 设计思路
验证器是一个 Python 函数,若是函数返回 True,则测试经过;返回 False,则测试失败。平台默认提供一个默认验证器。
默认验证器是验证指望结果与实际结果(response body)是否彻底一致。若是结果不一致则判断为失败,默认验证器只适用于静态的响应结果对比。
自义定验证器,若是默认验证器不能知足某些特殊的测试需求,用户能够在“项目配置 - 验证器”中添加自定义的验证器。
√ 应用场景:在 API 测试的返回结果中,能够添加自定义验证器对数据进行校验,判断测试是否经过。
图 -17- 测试用例验证展现页
API 配置
重点介绍:通用响应配置、API 依赖库、API 用例库、定时任务、测试报告
通用响应配置
图 -18- 通用响应配置列表页
√ 设计思路
在合理的 API 设计中,存在通用的错误响应码,[用户名错误,返回指望响应内容],若是全部 API 的响应结果中都须要重复写是至关繁琐的,做为共同配置调用便可。
√ 应用场景
查询接口遇到用户名密码为空,能够自定义写返回内容,以及选择 [通用响应配置] 下的相关错误类型,例如:用户名密码为空 (计费单元),自动填充指望的返回值:
<BillingIDs> <Result>fail</Result> <DetailInfo>invalid userName or password</DetailInfo> </BillingIDs>
图 -19- 指望返回值校验页
API 依赖库
√ 设计思路 & 应用场景
API-A 的参数 r_id 依赖与 API-B 返回结果的某个参数(多个参数一样道理),这里登记 API-B,而且提取返回参数。除了特有的变量提取器,基本信息与请求,与后面提到的 API 接口一致的
填写方式 :
图 -20- 变量提取器展现页
该接口返回数据以下;
{ "r_id": "567bbc3f2b8a683f7e2e9436" }
经过 [变量提取器],能够获取 r_id 的值,以供依赖 API-A 做为参数使用。
图 -21- 用例中参数包含 r_id 变量展现页
其中请求参数的获取以下:
图 -22- 请求参数变量提取设置
测试结果:
1- 显示依赖接口;2- 显示为须要测试的接口,依赖接口返回的 r_id 会传入做为测试接口的参数;
图 -23- 测试结果中展现运行时变量提取结果
图 -24- 用例库设计脑图
若是对软件测试、接口测试、自动化测试、性能测试、LR脚本开发、面试经验交流。感兴趣能够175317069,群内会有不按期的发放免费的资料连接,这些资料都是从各个技术网站搜集、整理出来的,若是你有好的学习资料能够私聊发我,我会注明出处以后分享给你们。
√ 设计思路
经过自助配置:请求头、请求参数,响应头、响应结果校验,来聚合测试人员平常思考产生的测试用例。
√ 应用场景
支持 HTTP1.1 协议的 7 种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE 和 TARCE。最经常使用的方法是 GET 和 POST:
支持 query(问号后)带参数、path 的 GET|POST 请求
Query:http://192.168.1.11/internal/refresh?username=ChinaCache&password=123456
POST 请求支持 application/json、text/xml
示例以下:
请求头设置:Content-Type:application/json 请求体设置:保存为 JSON 格式 { "username": "ChinaCache", "password": "123456", "task": { "dirs": [ 若是对软件测试、接口测试、自动化测试、性能测试、LR脚本开发、 "" 面试经验交流。感兴趣能够175317069,群内会有不按期的发放免费 ], 的资料连接,这些资料都是从各个技术网站搜集、整理出来的,若是 "callback": { 你有好的学习资料能够私聊发我,我会注明出处以后分享给你们。 "url": "", "email": [] }, "urls": [ "http://www.chinacache.com/news/test.html" ] } }
结果以下:
图 -25-body 参数展现页
支持返回结果的 schema 验证
在返回大量数据的场景下,把数据格式的正确性交给程序去判断,经过以后进行人工干预的数据对比,假如返回几百 K 的数据,你不知道格式是否正确,就开始去作数据对比,这个方向是不对的。
{ "r_id": "567cfce22b8a683f802e944b" } Schema 验证以下: { "$schema": "http://json-schema.org/draft-04/schema#", "required": [ "r_id" ], "type": "object", "id": "http://jsonschema.net", "properties": { "r_id": { "type": "string", "id": "http://jsonschema.net/r_id" } } }
定时任务
√ 设计思路 & 应用场景
定时任务是在计划好的时间点自动执行指定的测试用例。一个项目支持多个定时任务,若是同一时间点有多个测试任务,将依次执行。定时任务有两种类型:定时、循环(间隔:秒,
分钟,小时,天,周)。经过定时任务,能够作到晚上运行,早上查看结果报告分析。
图 -26- 添加定时任务
测试报告 & 邮件通知
√ 设计思路 & 应用场景
每次执行测试用例(包括手动执行和定时任务)以后,都会生成一份测试报告。
报告会详细列出每一个接口的基本信息(名称,请求方法,验证器等),请求信息(URL 和 body 参数),响应信息包括 headers, body, schema, content type, status code 5 部分的测试结果,每一部分都有实际结果、指望结果(失败时显示)以及 DIFF 对比(失败时显示),当在
执行测试时出现错误,也会把错误信息显示出来 。
图 -27- 测试报告列表页
图 -28- 邮件通知
API 实战:324 个用例(包括 GET|POST 请求,参数有加密、依赖场景,返回结果有简单验证数据、错误码验证、schema 验证),运行耗时:8min,猜测下,若是人工去跑,须要多久呢?
若是对软件测试、接口测试、自动化测试、性能测试、LR脚本开发、面试经验交流。感兴趣能够175317069,群内会有不按期的发放免费的资料连接,这些资料都是从各个技术网站搜集、整理出来的,若是你有好的学习资料能够私聊发我,我会注明出处以后分享给你们。
图 -29- 使用 HTTP API 平台改进 API 研发测试过程
改进前:传统手工测试
测试用例掌握在测试人员手里,研发人员没法运行,修复 bug 以后,只能等待测试人员验证,交付过程繁琐、效率低;
改进后:HTTP API 自动化测试
研发、测试协做同步,研发人员能够及早经过平台执行用例,验证功能可用性、正确性,测试人员能够释放部分劳动力,重点关注业务数据正确性;修复 bug 以后,研发人员无需等待,能够自助配置用例执行、查看结果,驱动过程质量的提高,同时作到夜间构建、邮件通知,工做时间 review、bug fix。
问题:什么时候收回投入成本?
API 项目周期不超过半年的,不建议作自动化,有自动化平台基础的另当别论,由于在最初 API 测试用例编写须要投入大量的时间;这种投入,只有不断进行回归验证、屡次运行,成本才能够回收,日后都是收益,这个道理浅显易懂。
“因为频繁地重复,许多起初在咱们看来重要的事情逐渐变得毫无价值”,在提测过程有个重要环节:冒烟测试,可是频繁的去作的话,就是重复性的工做了。
那 HTTP API 接口测试痛点是什么?研发人员提测以后,须要等待测试人员进行验证;测试人员发现 bug,须要等待研发人员 bug fix;这里就产生大量的等待成本(固然,测试人员能够切换到其余项目中去,可是这种上下文的切换成本很高)。经过 HTTP API 自动化测试平台,研发人员在提测以前,首先进行一轮冒烟测试,根据自动化测试用例检查结果,提高提测以前的功能质量;一旦提测以后,测试人员的关注重点落到返回结果对比上,这种研发测试过程的效率会获得很大的提高,或许有人要问,到底提高多少呢?这个每一个团队的痛点不一样,研发、测试人员磨合程度不一样,不能一律而论,大胆迈出一步去尝试,就会发现价值;固然,往深处去想,下一步能够接入性能的自动化测试,喝杯咖啡的时间,等到自动化运行结果报告产出,是有可能的场景。