一, API 测试的基本步骤
通常来讲, API 测试的基本步骤主要包括以下三大步骤:
1, 准备测试数据;
2, 通过通用的或自己开发的 API 测试工具发起对被测 API 的 request;
3, 验证返回结果的 response.
常用的 API 测试工具有命令行工具 cURL, 图形界面工具 Postman 或 SoapUI, 支持 API 性能测试的 JMeter 等.
二, API 复杂场景举例
通过使用基础的测试工具, 可以做简单场景的 API 测试; 而项目进行过程中, 为了解决实际的一些问题, 我们会设计更加复杂的测试场景, 下面列举几个实际项目中的典型场景.
场景一: API 串联调用
以协议支付为例, 我们知道, 三方公司接入网联后, 用协议支付取代代扣, 而协议支付的流程中需要用户输入银行返回的验证码完成绑卡. 从接口层面上看, 顺序是先调用协议签约 API, 返回状态成功且获取到短信验证码后, 再使用此短信验证码作为输入参数调用代扣 API. 协议签约和代扣两个 API 是顺序调用, 而且在两次调用中间有获取手机上的短信验证码, 这些过程都需要通过程序自动化实现以提高效率.
场景二: API 接口加密
为保证 API 接口安全, 系统间和系统内模块间互相访问需要进行加密处理, 常用的加密方式有 DES,AES,RSA,MD5 等, 各系统的加密方式并不一样(接口调用方和接口提供方约定好即可), 意味着 API 测试需要支持多种自动化加密方式程. 某些系统还会返回加密的响应报文, 也需要识别并解密.
场景三: 异步 API 测试
异步 API 指请求发出后后收到一个同步响应, 但并不是最终处理结果, 最终结果通过回调或者主动查询获得. 对于这样的 API, 同步响应的验证只是第一步, 后续还得继续验证 DB 中的值, MQ 中的值, 以及异步回调是否成功等. 对于异步回调, 我们可以模拟回调地址来验证成功与否; 而对于主动查询, 我们就得通过查看 DB 中的状态值来验证了, 但是查询到结果的时间点不确定, 几分钟到几小时都有可能, 这就得有一个定时 DB 查询任务去验证.
场景四: API 测试中的外部依赖
APIA 调用 APIB 且 B 不可用, 此时如何测试 APIA 需要考虑. 比如支付系统对三方支付通道, 对银行的依赖, 并不是所有的三方都支持测试环境, 解决此问题的核心思路是搭建 MockServer, 而且尽量做到通用性, 我们开发了一套 Mock 系统 -aMock, 通过页面录入接口信息, 保存在数据库内, 通过 Nginx 访问配置好的 Mock 接口, 后台统一处理请求信息, 然后通过 URL 和报文特性去匹配特定的响应信息.
三, API 测试平台
我们的 API 测试平台是要基于业务场景的, 即要支持各业务的共性需求, 又要针对不同业务的个性特点加以开发来丰富 API 测试能力; 而且, 对用例也要有很好的规划, 结果有清楚的展示, 测试平台架构如下图:
BIT: 业务接口测试(BusinessInterfaceTest)
SUT: 被测系统(SystemUnderTest)
TestCaseManagement: 测试用例管理, 包括从测试用例到测试用例集, 再到测试任务的数据关系的建立和维护. 测试用例是最小单位, 测试用例集是从某一维度对用例进行的归集, 测试任务即测试执行, 可立即触发也可定时执行, 只能执行测试用例集.
Util: 工具类封装, 主要提供数据加解密, 数据类型转换, 配置文件读写, 数据字典的缓存服务等.
Validator: 接口响应字段和数据库字段的验证封装.
RiskManagement: 风控处理, 因为会涉及支付真实资金, 需要内置风控规则来保证资金安全, 风险可控.
Timer: 定时任务服务, 包括
串联 API 用例中, 前置用例的状态判断;
异步 API 的数据库校验;
超时 API 用例的失效状态判断;
定时执行的任务计划.
MockServer: 用例依赖的外部系统 Mock 服务.
Portal:API 测试平台门户网站, 包括测试用例的录入, 维护, 测试任务的执行, 结果查看, 导出等都通过门户进行操作.
DB: 存储测试用例数据以及相应的测试任务, 测试报告数据, 还有项目配置等.
目前 API 测试平台上各项目维护用例总结 1200 多条, 以回归用例为主, 且还在不断增加中, 随着用例的不断添加, 平台也历经了一系列优化, 下面就谈谈这个过程中的一些思考.
四, 测试数据准备
对于大量 API 用例的执行, 需要数据驱动测试, 也就是说可以将测试数据和测试代码分离解耦, 这样便于测试数据的维护同时也保证了数据的准确性, 用例设计格式是这样
- <accountName>
- ${accountName}
- </accountName>
- <accountNo>
- ${accountNo}
- </accountNo>
- <identNo>
- ${identNo}
- </identNo>
几个关键数据节点由 DataProvider 提供, 为了增加测试覆盖度, 数据库相似的测试数据有多条, 比如多条四要素 (银行卡号, 手机号, 身份证号, 姓名) 数据, 当大量用例需要读取时, 可采用缓存方式存储并读取到 cList 里面, 通过循环遍历, 使每条测试数据都可以被均匀读取, 下面是替换关键数据节点的一段代码, 将 cList 数据依次赋给对应变量.
五, 测试执行的逻辑控制
很多情况下的测试是场景化 API 测试, 涉及用例的顺序调用. 如下图,"签约 - 成功 - kftn - 协议" 依赖于 "签约 - 成功 - kftn 短信" 的执行; 在添加用例时配置好关联关系.
执行时, 会根据用例属性将此两条依据有无前置条件划分为两类, 分别存放于两个 list 里, 无前置条件的用例可以马上执行, 有前置条件的用例, 设置 TestStatus 为 0, 等待定时任务轮询触发执行. 分类执行代码如下图
定时任务每分钟执行一次, 下面一段是判断前置 API 的执行状态, 只有 "0000" 代表成功, 当前 API 才能执行, 执行时, 需要读取前置用例的结果数据并传入; 如果前置 API 失败, 则停止任务执行, 多条 API 用例顺序执行也是同样的道理; 即使有外部依赖的用例, 比如短信验证码, 我们也可以通过写一段手机 App 程序自动上传短信验证码到服务器, 然后触发延迟获取验证码, 得到后通过 DB 记录用例执行的状态和结果, 并传给下一个 API 使用, 就完成了多用例的顺序执行. 此外, 测试任务的执行封装成 restful 接口, 可以更加灵活地和目前团队正在开发中的 CICD 系统结合一起.
六, 测试结果的验证
通过分析业务, API 的结果校验大致分为两种类型, 响应校验和数据库校验. 响应校验是针对 response 报文字段的校验, 可精确匹配也可通过正则表达式模糊匹配; 数据库校验是基于定时任务的, 需要在用例里面根据约定格式设置校验方法, 比如下面的 sql 检验条件, 会在准生产环境通过指定单号以及其他条件去查询返回字段, 并判断 status 是否为 7, 从而判断用例是否成功.
- PreOnline.3|,|SELECTtb.outer_batch_no,tb.status,bs.send_statusFROM
- bs_outpay.trans_batchtbleft joinbs_outpay.es_business_sendbsontb.business_batch_no=bs.entity_uuidandbs.entity_status<>2 WHEREtb.outer_batch_noin (?) order bytb.CREATED_TIMEDESC|,|{
- "status":"7"
- }
用例状态分为成功, 失败, 处理中, 超时四种状态, 分别通过配置相应 SQL 查询条件去映射, 成功和失败是终态, 处理中则是需要定时任务继续查询, 超时, 是我们内部设定的一个状态, 目前是超过一个小时未返回终态设为超时, 此 API 用例失效并报警, 需要人工参与查看. 所有这些规则都是在用例建立和编辑的时候添加的, 如下图, 一条用例包括了响应校验 (值校验, key 校验) 和数据库校验, 通过这种比较灵活的设计, 基本能够满足复杂 API 测试场景. 需要指出一点是, 很多应用不允许外部测试平台直接访问数据库, 我们的解决办法是写一个数据查询服务部署在系统环境中, 只提供查询功能, 并且有加密验证保证通讯双方 (测试平台和数据查询服务之间) 可信.
通常来说, 测试平台或框架可以从某种层面上理解为工具链的串联, 开发此平台的过程中, 我们使用的技术栈有 springmvc+herbinate 做逻辑控制, amazingUI 做用例管理, echart 做结果展示, 还使用 Jenkins 做任务调度等, 用户就是各业务线测试人员, 他们不需要了解具体代码的实现, 但是需要对系统结构以及用例规则有很好的理解, 这样才能设计出符合测试场景的用例.
任何测试平台的设计还是要基于业务的, 后续我们对 API 平台的推进策略是, 继续增加场景化功能以支持更多业务类型的测试, 比如清结算系统中日终, 日间的跑批任务, 对账文件的数据检验等, 增加大并发能力并和性能测试工具相结合.
来源: https://www.cnblogs.com/yixinjishu/p/11471349.html