作者 | 戴维德
API 接口自动化测试在服务端分层测试体系中占有重要地位,在持续追求提升研发交付效能的背景下,传统的自动化测试工具面临质量与效率的更高挑战。智能化测试的本质是利用数据和算法相结合赋能质量活动的测试方法,借助智能化测试思维,在 API 测试全生命周期内进行了多环节的针对性优化、形成合力赋能提升测试质效。
1.1 API 的自动化测试特点
API 接口由于具备良好的可测性,很自然的成为服务端程序自动化测试的首选方案:
1、API 的结构化有助于程序实现请求与解析接口,当前以 Json 数据结构为主要的入参、返回结构,可读性强、程序化处理方便。
2、API 的业务逻辑集成度较高,具备较高测试性价比,接口的参数组合具备直接的业务含义,主要的业务场景是可以通过不同参数组合达到覆盖。
3、API 测试执行与维护成本较低,考虑到需要书写的 case 量级、调试与维护的代价,在测试分层的金字塔理念之中,是作为腰部支撑的存在。
1.2 API 自动化测试面对新的挑战
伴随着自动化测试的建设与积累,建成了一站式平台化为主要形式的测试服务,CASE 全周期几乎都是在平台内进行的,平台化的建设集成了丰富的测试能力、减少了重复建设、提高了测试服务的可靠性,从完全手工测试跨越到自动化平台对质效提升有显著意义,但同时也面临新的问题需要解答:
1、测试全周期内,人力投入是否可完全释放:
CASE 书写调试效率:API CASE 由接口定义、参数数据、断言组成,平台建设有编辑管理能力,在自动化发展的初期, CASE 自身的书写准备仍然需要大量人工投入,多数工作集中在了从浏览器复制粘贴接口参数、或者从 API 定义文档中手工录入参数。在初期,CASE 的全自动化生成占比几乎为 0%。
排查分析 CASE 失败原因:按照历史经验,自动化 CASE 失败的原因 70~80% 与被测代码无关,而更多的是平台、CASE、环境、数据等相关,日常排查分析此类问题浪费大量的人力。
2、自动化 CASE 量级急剧膨胀,测试效率开始降低、可维护性变差:
长尾任务增多:随着 CASE 量级增长、维护跟不上导致稳定性变差,开始出现执行耗时变慢,难以达成快速测试的目的,同时也挤占了公共执行资源。比较突出的长尾任务包含上千个 case,整体耗时需要 1 小时。
CASE 存在大量冗余、无法甄别质量:当 CASE 积累到一定阶段后,人工维护的及时性与可行性极速下降,单靠人工去筛选、清理 CASE 变得非常困难。使得测试执行时无法高效有效的筛选出合适的 CASE 来覆盖。
3、自动化 CASE 测试的质量是否可信:
一种情况是,CASE 全部 PASS 造成的测试通过假象:其中可能夹杂这 CASE 并无有效断言来拦截问题、或者覆盖率不足,无法有效的证明 CASE 测试是放心的。
另一种情况是 CASE 有频繁的 FAIL,但是夸大了问题拦截率:更多的是由于平台、CASE、环境、数据等干扰问题导致的 CASE 状态不稳定。
如何理解智能化测试:利用数据和算法相结合赋能质量活动的测试方法,使得每一次测试活动,都用较小的代价、准确判断质量风险。
(1)智能化测试不是一种全新的测试类型;
(2)智能化测试存在传统测试的某个或多个环节中;
(3)传统测试是智能化测试发挥作用最重要的载体。
基于自动化测试的整个生命周期,输入、执行、分析、定位、评估,分别有其相应的数据特征与规律、以及对应的瓶颈问题,智能化测试以提升测试过程各阶段质效为目标,将数据与策略相结合,形成整体合力。
在智能化测试的思维指导下,以 API 自动化测试平台为载体,结合 API 测试各个阶段面临的问题,分而治之。
1、准备 CASE:通过自动化生成的手段快速生成 CASE,智能化策略解决参数组合爆炸问题、断言缺失问题。
2、执行 CASE:通过任务编排的动态并发策略提高测试效率,通过代码覆盖的映射关系精准筛选 CASE 提高测试效益。
3、分析判断结果:通过 Diff 去噪策略保障接口对比测试的调试效率与效果。
4、排查定位原因:通过结合日志 trace 系统、异常错误规则库建设,提高自动排查定位效率。
5、评估测试质量:通过适合的自动化 CASE 评估手段,评价 CASE 的有效性,指导 CASE 优化治理与披露风险。
3.1 自动化 CASE 的「自动化 + 智能化」生成
API CASE 主要由接口定义结构、参数数据、断言三部分组成,前两部分比较好实现自动化,而断言部分因为包含业务逻辑的校验需要更多考虑智能化策略。
1、接口定义 + 参数数据的自动导入生成:扩展多种对接渠道,建立快捷的自动化生成 CASE 机制。
基于 API 定义管理工具:swagger+yapi 用作规范化的 API 定义管理工具,包含了 uri、入参结构与示例、返回结构与示例。测试平台建立对接机制,可一键式导入并监听接口变更信息。
基于业务系统日志:从生产环境摘取 API 的日志片段,经过加工处理之后,解析出 API 结构与参数。测试平台以开放 API 的形式提供给业务线定制化实现对接。
浏览器插件录制请求:建设 pc 浏览器的插件,对页面操作时的后端请求直接录制保存到 CASE,尤其是有顺序要求的 API 请求序列。对于 web 手工回归测试、验收的环节,可同时生成接口 CASE。
其他 API 测试工具导入:postman 作为手工调试 API 的利器,在研发阶段积累了一些 API 的请求,可批量导入为 CASE。另外还有一些代理工具,如 fiddler、charles 其接口请求的数据格式也可支持导入导出。
自动化生成的 API CASE,主要用于两类场景:
契约测试:在微服务系统中是比较重要的用以验证服务之间接口契约一致性的手段,在使用中需要解决二个问题,一是接口结构随着业务发展经常升级变化需要及时更新到 CASE,二是验证契约需要一定量级的参数组合但又要避免参数组合爆炸的问题。前者主要建设了监听 API 定义变化的机制自动刷新 CASE,后者是一个典型的 pairwise 测试组合算法应用场景,即参数俩俩正交组合达到最佳覆盖同时又控制参数组合的量级最少。
回归测试:应用与业务逻辑回归面临的重要问题有三点,一是大部分业务逻辑是一系列 API 组合且有依赖关系的操作序列,因此也需要 CASE 内保持此种关系;二是由于 CASE 内部 API 组合情况增加了复杂度,需要增加前置的规范化预处理机制;三是业务逻辑断言不能够依赖自动化代替,大部分仍需要人工后期修改增加断言,但为避免生成无断言的无效 CASE,至少生成一些基础性的断言,如 json-schema 断言对结构做最基本的检验。
2、接口断言的自动化生成:尽可能的多做一步,为新增 CASE 以及存量 CASE 主动生成与推荐断言。由于 json 为当下 API 主要的数据交换格式,断言生成的部分也主要集中在 json 的处理机制上。
Json-schema 断言:json-schema 定义了一套词汇和规则来描述 Json 数据,即 Json 数据需要遵循的规范,包括成员、结构、类型、约束等。在测试场景下(特别是契约测试),可用于验证 API 返回 json 数据的格式、内容。
对于新生成的 CASE,结合导入的上游渠道中描述的接口定义(包含了接口返回结构),可直接将 json 数据转化为 json-schema。
对于存量 CASE 因书写不规范有断言空白的,起不到任何拦截问题的作用,从成本上考虑高优补充 json-schema 断言。基于 CASE 执行的历史结果数据,提取无异常报错的记录 N 个,转化为 json-schema 集合并计算期间的差异,按照其表现与 CASE 的参数、执行时间对照,经由不同规则确定适合的 json-schema 版本自动回填到 CASE 中。
Json key-value 值断言:json 数据中的键值对,其 value 值为主要的验证点,常用做回归校验。对于新增 CASE 或者存量无断言 CASE,均可以通过基于最近执行结果的 N 条记录,计算 key-value 中 value 的 diff 比例,设定阈值区分固定的 value 值,并回填到 CASE 中作为回归断言点。
经过上述能力建设之后,当前增量 CASE 中,自动化手段生成的 CASE 占比已经提升到了 60% 以上,全年为 30%。
3.2 自动化 CASE 执行更加高效、有效
动态预估:基于可用线程资源、历史性能与稳定性表现,预估可分组数量。
CASE 分组:按历史 N 次平均耗时表现动态分配到不同分组内,保持分组之间的整体耗时相对均等。
分布式执行:采用分布式执行框架,对任务分片分批处理。
熔断止损:分组内监听执行情况,异常导致的耗时明显增长将熔断执行,避免分组成为长尾。
优化执行模型之后,长尾任务的数量减少 40%,并且有益于资源快速释放进而可以消化更多任务,整体测试任务的平均耗时随之降低 30%。
CASE 相关性计算:通过串行执行 CASE 的同时 dump 测试环境的 cov 文件,计算提取其中的函数信息,可获取 CASE 相关的被测函数列表。
筛选 CASE:基本做法即通过提测代码计算 diff,提取出有变更的函数列表,然后查询上一步的对应 CASE 集合。进阶做法是对筛选的策略进行优化,对 CASE 多维度的数据建立分类与排序。
CASE 筛选策略可广泛应用于 CI 流水线的准入测试(冒烟),以自动筛选相关 CASE 取代人工维护,筛选后执行效率相比全量执行可优化 70%。
3.3 分析测试结果的智能化手段
在 API 测试中有这样一类场景,API 的数据结构比较复杂、数据比较多,不论是人工设置断言还是自动化生成的断言,均很难达到较好、较准的覆盖。对于这类接口,衍生出 Diff 测试的方式来进行测试覆盖。
Diff 测试常用于回归测试,其主要方式是采用相同的接口请求参数,分别发往 A/B 两个版本的接口服务,其中一个版本是已交付上线版本并认为是可信的。Diff 测试的优点在于可全流程自动生成、无需编写断言。但 diff 结果情况复杂,一般存在较多随机值、变化值并非验证重点,导致 case 往复调试成本高。
针对 Diff 结果有「噪点」的问题,设定去噪算法消除 diff 结果的不确定性,减少人工调试 case 成本,自适应提高 case 稳定性。当前在接口 CASE 应用到 diff 测试场景时,大部分无需关注断言,可 100% 自动化完成自适应修正,无需人工介入。
3.4 CASE FAIL 原因的智能化分析定位
自动化 CASE FAIL 比较常见,在建设初期、或者维护 case 量级比较大的业务,70%~80% 以上的 FAIL 问题基本属于非代码 bug 原因。这部分排查牵扯的人力成本也是比较高的。通过自动化平台建立自身 + 业务逻辑的排查服务,通过自动定位排查手段能有效的减少这部分人力投入。
1、一级定位:首先排除掉自动化测试工具平台、环境、CASE 规范这类非常明显、且容易出现的问题。这部分的工作依赖的是自动化测试工具自身的日志建设,建立完整的异常错误码机制,对各个环境容易出现的异常进行细致的分类。比如接口请求不通的异常,就需要分为被测服务异常无法访问、或者是 CASE 中的 URL 填写错误等。对于工具而言要解决的一个策略机制问题是,当一次测试出现的异常太多,如何选择 1 个 root cause 作为主要根因反馈到测试结果中。此处的过滤策略,先对 CASEID+ERROR 为 Key 存储到缓存,过滤掉同一个 CASE 重复的报错;根据执行测试流程对 ERROR 发生的时机建立优先级顺序,同一个 CASE 有不同的 ERROR 报错信息时,按照先后顺序高优推荐首条错误原因;当批量 CASE 均有多个 ERROR 报错信息时,对 ERROR 计数再区分,选择比重最高的作为错误原因。如此一来可自动化的排除掉 CASE FAIL 问题的 20% 无需介入排查。
2、二级定位:相对于一级定位,其他 FAIL 原因则更多的是与测试环境、测试数据紧密相关。比如被测系统调用第三方的 API 超时无返回,体现在 CASE 结果上是断言不通过,那么希望是能定位到这个原因上,也可以大大缩短定位的路径。做到这个层面的自动定位分析,需要解决二个问题。第一是将自动化 CASE 与业务系统的日志串联起来,业务系统首先建立起日志的 trace 机制,可通过唯一 ID 串联起一次 API 请求的过程。第二是针对业务日志常见逻辑异常的报错,建立错误信息规则库,FAIL 的 CASE 透传关联 ID 到日志这边时,根据已有的错误信息规则库去检测日志范围内的匹配结果。这样可继续自动化排除掉 60~70% 左右的 FAIL 问题。
3.5 自动化 CASE 的有效性评估
在测试工作中对于测试交付的质量经常会有如下困扰:自动化 CASE 的测试拦截效果如何?每次测试都 Pass 是否可以高枕无忧?需要证明自动化 CASE 能有效发现 bug,才能使得测试行为有信心,此即为测试有效性的含义。
如上为典型的一个有效性不足的 CASE,即验证点覆盖不足,会遗漏对业务逻辑的校验。在业界用以做有效性评估的手段多数为变异测试,学术界也有对比分析语句覆盖率、分支覆盖率与变异测试评估的效果。
结合实际测试工作经验,可划分为四个评估的方向:
1、静态分析评估:根据自动化 case 自身的书写特点进行的设计合理性的检查评估,是最为基础的手段之一。
2、动态分析评估:根据 case 运行之后的结果评估执行效果。
3、变异测试评估:是一个研究非常多且有一定难度的评估手段,通过源代码生成变异体之后,检测 case 是否能发现变异,多用于白盒测试。
4、揭错能力评估:实际工作中,case 存在特殊的问题,即存有较多同质化的 case 带来额外的执行开销,同时也有脆弱不稳定的 case 干扰测试结果,进而有需要评估治理。
对于 API 测试而言,测试覆盖流程较长而不便于做代码程度的变异与检测。但可以先从基础的体现 CASE 本质的几大因素来评估,即综合了上述静态 + 动态的分析手段:
1、CASE 规范性:基础的因素即断言,断言体现的是测试验证的覆盖,否则将出现只有代码覆盖率数据但没有检验点覆盖率。
2、代码覆盖率:代码覆盖率虽然不能作为检验测试质量的唯一标准,但它是基础,代码覆盖率低必然 CASE 覆盖程度薄弱。
3、CASE 稳定性:CASE 设计考虑不周全导致错误频发、性能波动较大意味着不可靠,稳定性差将非常打击测试结果的可信度。
4、CASE 活跃度:被运行的频度、被暂停搁置的周期、被更新编辑的次数等等,表明了某个 CASE 是否已经不再活跃,变成了闲置 CASE。
5、CASE 复杂度:CASE 组成内容过于复杂时,维护的代价、运行的稳定性风险都比较高。
综合上述数据特征,按不同权重对每一项进行评分,加总后给出 CASE 的评分。用于两个方面,一是 CASE 数据评估供后期维护 CASE 参考,二是测试报告实时披露 CASE 的质量风险。
回顾 API 自动化测试的智能化改造实践历程:由痛点问题出发、从点到线、全面覆盖,全方位优化 API 测试流程的效率与质量,为 API 测试作为主流的功能回归测试能力形成有力保障。
经过智能化测试的改造,API 的测试全流程更加精益求精,各个环节形成合理,全方位提升测试过程效率、测试质量。