作者 | intelligents 百度 Geek 说
场景从何而来,是我们首先就要面临的问题,为此还是从测试活动本质去寻找答案。测试活动其实大概可以分为测试输入、测试执行、测试分析、测试定位和测试评估五个步骤。这五步测试活动目标是不一样的,因此不能笼统对整体测试活动进行智能化,容易造成目标混乱,影响落地开展。
我们开展的思路是:某服务的某项测试中的某个测试活动为一个场景为试点,从而形成点线面体的推进方式。如下图所示:
测试输入:找出覆盖足够全、准确的测试行为、数据集合和构建真实的环境,以去覆盖更多的测试场景和更高的代码覆盖,该阶段决定测试活动发现问题能力上限。在传统测试方式中,测试输入的选择很大程度上依赖经验和历史 case。
在智能化测试的探索中,通过智能异常单测用例生成、海量 query 寻找最合理的 query、页面遍历推荐动作集、fuzz 函数或接口的入参等手段,可以进一步完善测试输入,提升测试阶段召回能力。
如测试流量扩流与初筛场景中,通过扩大流量覆盖面,扩大的测试输入范围的同时,通过特征分桶,覆盖率插桩等手段,剔除无效特征数据以及特征去重来实现流量初筛。针对异常场景,基于控制流图,数据建模等思想,针对值类型与路径频率等通过变异策略生成异常用例。在保证测试输入完备性与执行效率的同时,提高测试的覆盖率。
测试执行阶段:结合测试输入集合以及变更详情,以较小的代价,在不降低发现问题能力的前提下有效执行完该执行的质量活动,本质上是效率问题。
传统做法是:将所有确定的测试用例不做筛选优化、对测试过程不做精简全量执行,往往存在用例冗余度高、长尾用例分组异常,最终导致测试执行效率低、资源消耗大;
而智能测试下的做法是: 对测试集合进行精选、相似度去重、分组均衡、资源调度来智能执行测试过程,进而极大的提升测试执行效率,降低成本;在该阶段, 我们通过静态评估 (静态扫描用例内容)、动态评估 (执行用例并结合过程与结果的状态来判断用例质量)、变异测试 (注入源代码异常算子,检测用例是否有效)、Flaky 监测 (检出与剔除源代码不相关的用例) 等手段来确定所有该执行的用例,通过智能取消、跳过、裁剪、排序、组合等策略来保障该执行的用例能在最短时间内有效执行完成。
测试分析阶段是将测试执行的结果进行系统整体的分析判断,确认测试执行的结果是否有问题,尽可能高准召的分析暴露问题,本质上是质量问题,即将测试输入阶段该召回的问题披露出来。
传统的做法是有经验的测试专家,来制定各测试任务是否有问题的标准,包括不限于特定指标是否存在;特定指标的大小和对比;阈值设定等,这种做法比较依赖人的判断能力,随着系统和环境的变化导致抗干扰能力不足。
智能场景是通过测试执行任务的历史表现,智能化进行决策分析,判断测试执行结果是否有问题。
例如 1、数据测试中可使用历史数据的指数平滑计算方法,计算数据大小,行数和内容的合理波动范围,进而在下次测试任务执行时,智能自动判断任务结果是否有问题。
2、业务指标测试场景中,各指标的阈值波动范围,也可以通过借鉴线上的波动范围以及历史测试任务的数据,通过智能计算的方式自动化的产出合理波动范围。
3、通过视觉技术分析前端用例执行过程中,截图内容是否有问题,而不用担心人工判断导致的漏出;
4、通过 DTW 曲线拟合算法判断内存泄露是否存在,而不是传统的阈值方法。
测试定位,主要是快速判断导致测试活动 “失败” 原因,以快速修复,本质上是个效率问题。测试活动中经常会遇到执行失败的情况,常规情况下经常要去排查工具、环境、代码等情况来判断活动失败的原因,最终决策是否进行对应行为,在智能化的探索中,我们希望通过智能定位快速找到测试任务失败的归因,第一步可以找到工具/环境问题来判断是否要进行重新构建或自愈;第二步可以找到代码导致的失败,以协助研发快速定位问题快速修复提升效率。
在该过程中,我们探索了基于决策树的测试失败智能定位,实现了工具失败自动 rebuild 和自愈。在监控领域,我们利用变更墙、线上系统关系知识图谱实现监控问题的范围定位,以协助研发或运维快速做出止损动作。
测试评估,是测试活动最容易忽视的阶段,从业者经常因为某测试任务红/绿灯来判断测试是否通过;而测试评估是结合测试执行和系统变更,整体评估待实施或实施过测试活动的系统风险,以进一步指导我们是否要测试活动,本质上是个质量问题。
测试评估,首先是由历史数据形成风险判断的范式,然后用来评估新项目的风险。形成范式的阶段,我们探索了基于测试全流程数据的质量度模型,需要选取合适的风险因素,建立数据采集和变化感知的体系,采集数据并转化为特征,利用机器学习训练大量真实数据,对特征进行定性(一个因素对风险是正向还是负向)和定量(对风险的影响有多大)分析,得出风险预估模型,将人工的经验转化为客观的判断。项目使用阶段,由于已经建立了数据感知系统,新数据可以直接输入到模型,得到即时的风险结论和特征对风险的影响情况,让质量可见。落地积累的项目数据又能反哺模型,形成有效闭环。
在项目待实施测试活动时,我们先进行一次测试评估,即可决定项目是否需要测、辅助判断如何测。采取了对应的质量活动后,再做一次风险评估,以进一步检验测试结果,发现风险。如此,测试决策将变得更有效、更可积累、更可持续。
测试自动生成,通过将数据、算法、工程等相关技术有机结合,在测试输入阶段自动实现 “高覆盖、高仿真、全校验” 的揭错集合,一般包含测试数据生成、测试用例生成、动作集生成、测试断言生成等方面,在学术界和工业界均有非常优秀的研究和实践。方法论上一般包含基于控制流图、基于数据建模或两者结合的方式。本章节将从多个实践的角度,介绍相关领域的目标、思路、涉及到的技术点、效果,希望能给到大家一定参考。
代码级用例自动生成用于解决 RD 写单测困难、耗时等问题,探索一种可以根据代码结构、代码信息自动生成单元测试代码的方法。
基于 AST 的代码级异常单测用例生成技术是一种近代码感知问题的测试手段,其核心技术包括代码理解、用例数据生成、用例驱动代码生成。
代码理解环节通过静态代码扫描的手段,将代码语言抽象成结构化的函数特征数据,特征数据包含:函数调用方式、变量声明和赋值方式、变量关系、变量字面值、mock 点等信息。
用例数据生成环节,基础数据源包括边界值、随机值、变异值、代码字面值和函数插桩参数值以及一些业务自定义的数据。为了避免用例爆炸,在传统的基于生成法构造用例数据的基础上,除了被测目标接口协议外,结合了高风险变量选择、路径选择、符号执行以及基于搜索的生成算法(例如采用遗传算法,通过适应度公式来评估用例质量好坏)来指导用例数据的生成,保证用例集覆盖更多分支下的代码逻辑,结合覆盖率和问题堆栈信息,反哺用例生成算法,降低对无效用例的生成,在有限测试成本下生成更有价值的用例,保证揭错能力。
用例驱动代码生成环节,依托多语言多测试模板如(gtest 语法要求)建立生成算子集,基于代码结构化数据和用例数据,调用不同的生成算子,结合智能 mock 生成算子,生成可编译执行的测试用例代码。
现已具备 C++/GO/OC 三种语言的用例生成能力,召回 1000+ 异常(core、死循环、panic)等问题。
接口用例自动生成,主要是针对服务接口级自动生成 API 请求来代替人工写用例的场景,解决人写用例不完备、工作量大等问题。
接口 api 一直具有良好的可测性,在各大场景下面,都有相关自动化接口测试的应用,但是使用的越来越多,也会出现新的挑战。比如 case 的人力成本,因为要持续添加新的 case 测试,还要持续维护老旧 case,所以针对 case 这边的人力维护成本也越来越高;自动化 case 的质量,有可能写了很多 case,但是压根就没有多少是有用的,或者无法辨别 case 质量,越积愈多,无法维护。所以针对以上问题,提出接口用例的智能自动生成,主要是思路就是根据定义好的接口格式,包括 api 定义管理工具,业务系统日志,截包等等,都可以拿到各个接口标准的定义,然后加上人工梳理的理解,对一些字段进行一些条件限制,最终可以通过接口的定义和限制条件,自动智能的生成批量的测试 case,可以快速的进行接口契约测试和回归测试。除了接口用例自动生成,在接口的断言也做了自动智能化的升级,主要的思路就是根据历史 case 的运行结果,首先可以自动判断后续所有 case 的返回接口体一致,不会出现结构嵌套的问题。再进一步,也可以根据历史接口返回各个字段的值的特点,自动智能的生成针对每个 value 值的断言,快速判断接口是否有异常。目前接口智能化生成的 case 有 2w+,占整体 case 量级的 80% 以上。
UI 自动化测试可以实现端到端测试,对业务功能进行回归验证,大大提高测试效率。目前该领域存在明显局限性:1、用例书写成本高;2、用例召回能力弱;3、用例维护成本大。但有部分业务 UI 交互并不复杂,如在关注展现样式或浅交互功能的产品中,一方面,QA 需要对数百上千条数据驱动下的页面进行样式校验;另一方面,需要对页面里数十个元素的操作交互进行验证,我们尝试用视觉技术解决此类用例生成用于代替人工。
UI 浅交互 case 生成技术工作,具体包括离线数据挖掘模块和实时任务执行模块:在数据挖掘环节,操作的对象是线上基线产品,我们使用 DNN Object Detection 技术,训练生成控件级和页面级分类和回归任务模型,进而利用 mine 技术录制页面关键 Dom 元素的探索操作,生成带有上下文语景的操作序列,最后把这些 action 和 pic 作为生成的用例步骤;接着在 real-time 任务执行环节,对线下提测模块进行路径回放,并进行 ui-diff 视觉技术校验,来进行 case 的回归验证测试。
整套 UI 用例浅交互生成机制,可以生成低成本、高召回的自动化 case,目前该技术在共覆盖多个产品线,发现有效问题 16 个,在某业务的前置准入流水线,生成 1000+case,试用阶段,已召回 3 例问题。
前面介绍的均是代码、接口、UI 层面的生成技术,本段解决的是动作集自动生成,此类场景在 UI 遍历、巡检、monkey 有非常广泛的应用,即如何探索出一套高效的拟人化遍历解决方案。
GUI 遍历动作集自动生成,核心是在平衡资源与收益前提下,自动生成覆盖率和问题露出率高的动作集。GUI 动作集是指向移动真机或模拟器发送的一系列随机的用户事件流 (如按键操作、触摸屏操作、手势输入等),是模拟真实用户的点击、滑动、输入等操作的集合。核心点在于更快 (相同的召回率,耗时更少)、更多 (相同的操作次数,覆盖率更高)、更准 (相同的机器时长,增量覆盖率更高);传统 Monkey 随机遍历,速度极快但无效操作多资源消耗大,较为智能的做法是基于控件的加权遍历方法, 该方法将页面结构提取成控件树,并对这些控件基于属性、历史操作情况等赋予不同权重,最后将页面抽象为 “点”,控件抽象为 “边”,这样将动作集的生成转化成对有向有环图的遍历问题;这种遍历没有场景对照,且图中存在大量环路极易陷入局部循环,需要在遍历过程中给一定的反馈辅助动作集走出死循环,对此引入基于 Deep-Q-Learning 的智能遍历,以能否进入新的页面作为激励,遍历过程有反馈,并且结合业务加入多种场景,让动作集的生成在反馈机制下自探索自学习,并进一步引入拟人化的思想,通过激励和惩罚机制使得动作集具有一定的逻辑性。与纯随机相比,相同时间内,智能遍历覆盖率提升 33%,相同覆盖率,智能遍历缩短 75% 的测试时间。
撰写测试断言存在不规范、工作量大、不完整等问题,导致很多本该召回的问题未及时报警,本阶段就是为了解决此类问题。
测试断言用于检查被测系统行为的正确性,即通过向被测系统提供输入,并以预期的输出评估结果来处理生成结果是否正确。在前端自动化领域,大量手工测试行为被自动化代替,自动化用例又逐渐趋向于自动生成。如何有效判断执行是否符合预期?关键点在于如何自动地生成完备、合格的断言。主要思路,一是有参照召回,即以历史版本或某机型的当前版本作为正确的参照,将被测版本与正确版本进行对比;二是无参照召回,即预先提取明显问题的特征,检查用例执行后是否命中,如白屏、乱码。在百度的实践中,我们加入了多层级页面理解和特征提取算法,来解决多设备版本的相对位置不同、复杂页面难以识别等问题,实现了端到端的立体校验。目前日均运行数十万次,策略准确率达到 97%+,拦截 bug2000+ 个。
测试执行是指将测试生成的用例集、数据集利用手动和自动化的方式对这些集合运行,测试执行本质上不能提升揭错水平,但如何高效稳定的执行完测试集合也是影响测试效果的关键。
测试执行智能化通过将数据、算法、工程等相关技术有机结合,一般包含测试用例推荐、测试流量筛选、测试任务调度、智能构建、执行自愈等方面,在学术界和工业界均有非常优秀的研究和实践。方法论上一般包含基于覆盖率相关性选择算法、基于数据建模或两者结合的方式。本章节将从多个实践的角度,介绍相关领域的目标、思路、涉及到的技术点、效果,希望能给到大家一定参考。
测试执行,因为代码变化、环境等因素,往往不需要执行全部的用例,如何在用例全集中找到最有可能揭错的用例,是本方向的研究领域,也是业绩研究最多的领域。
手工测试用例推荐主要指通过代码变更推荐出关联手工用例,一个关键目标是希望能精选覆盖度高的用例组合,尽早发现问题。直接使用代码覆盖率关联推荐,会出现公共函数关联的多个用例将被冗余推荐,执行效率低,也不利于问题的及时发现。因此引入基于风险的手工用例推荐,优先根据风险代码推荐用例,更为精准。首先,数字化度量代码,将代码抽象为语法树,抽取了代码环路、分支信等 21 个可以反映设计复杂度和程序开发难度的指标;其次,选取合适的模型进行推理,获取针对代码的有缺陷预测和无缺陷预测,获取关联的用例;最后,排序去重,选取预测有缺陷的结果和无缺陷中重要程度比较高的用例作为推荐结果。其中,缺陷推理可使用贝叶斯分类、SVM、KNN、逻辑回归等算法,也可以向深度学习转移,结合长短期记忆模型(LSTM)和深度神经网络(DNN)进行缺陷预测。落地该方案后,用例推荐比持续下降由 50% 压缩到 20%,回归天数由 3 天降低到 1 天,推荐发现 bug 的用例比例持续提高。
###02 基于并行覆盖率的流量筛选方案
在测试过程中,经常会遇到利用线上流量对系统进行 diff、性能和压测,如何从线上海量的流量选取最合适的流量进行测试,是本课题研究的关键。
并行覆盖率的流量筛选方案,是为了能够从海量的线上流量中,找出覆盖最多测试场景较小的流量集,从而达到测试覆盖场景,减少问题的漏出,保障系统的稳定性的目的。在传统场景下,通常不可能把线上全流量的数据照搬到线下,因为量级太大,所以会有一些筛选方案;最常用的就是根据机房、时间等属性随机抽样,尽量提升抽样的覆盖面,但是这样随机性太强,不确定最终业务和场景的覆盖面。基于并行覆盖率的流量筛选方案主要在覆盖率的指引下,尽量减少流量的量级,提升业务的覆盖。主要分为两个步骤:通过对源日志进行分析,进行流量初筛,经典场景有通过设备,地域,用户属性等,筛选可以覆盖这些场景的最小集,在第一步可以通过日志初筛出大部分有意义的流量。第二步通过对于发压流量的覆盖率进行分析,使用贪心算法,针对不同流量的覆盖率进行分析,通过尽可能少的流量覆盖尽可能多的场景。以上两点,可以从业务实际场景和覆盖率两个方面结合一起提升流量筛选的覆盖面。目前已经多个产品线和模块应用,在覆盖率无损,甚至提升 60% 前提下,流量缩减了一半,提升效率的前提下也保证的流量的覆盖。
智能构建致力于在静态 CI 任务编排中动态执行任务,实现任务精简、任务跳过、任务取消、结果复用、自愈、自动标注等功能,保障测试任务高效稳定构建完成。在日常的变更中,可能经常遇到以下场景:
1、变更仅修改了日志、格式或不重要的一些功能,这时是否有必要回归全量测试任务;
2、代码反复迭代,同一任务执行多次是否有必要;
3、同一次任务在分支和主干阶段是否有必要重复运行。
传统做法是执行全量任务,但会导致测试构建效率低,资源消耗大。
利用智能构建就可以根据变更场景动态调整构建任务,有效缩短构建时间,提升构建效率。具体来说,智能构建可拆分为分析和决策两部分,分析是针对业务代码库,以及本次变更 (如 git diff),利用工具算出进行本次变更的特征分析 (变更代码行数、变更代码的具体函数、变更代码的调用链信息等等);决策任务是否执行/等待/重启/取消等行为,做出最终的决策,比如业务设置业务相关的的白名单,若分析特征全命中白名单则可跳过指定任务;智能构建是在保障测试用例揭错能力的前提下,利用有限的资源满足用户对时效性的需求。目前百度已创建包含策略开发、插件方、业务线在内的智能构建体系,其中策略开发者按照构建系统接口规范开发策略,并将策略注册进入构建系统,构建系统开放策略给业务方使用;插件通过构建策略进行响应操作,如无效任务的取消执行、偶发任务的自愈、流程管控任务的拦截等;业务方则通过构建系统进行流水线上策略的配置;目前智能构建已辐射 3000+ 个模块。
本方向研究的是如何在有限的资源情况下,根据稳定性和揭错能力调度测试任务。
在测试执行阶段,在有限的资源下大量的并行测试任务调度困难,由于用户感知的等待时间是所有测试任务的排队时间和执行时间,不合理的测试调度会导致测试效率的低下。因此探索一种基于任务优先级的算法调度策略用以解决上述问题。
在移动端测试中,针对大量并行任务提交,建立任务优先级队列。根据任务重要程度,等待时间,资源需求,生成了有益于降低重点任务排队时间的优先级公式。基于公式分析结果,优化测试任务调度。在保证平均排队时间的情况,降低重点任务的平均排队时间。
针对单个 case 任务的执行效率,最初我们基于离线历史任务分组的时长,单位时间覆盖率等数据,寻找最优收敛点用以预测任务的最佳停止时间,优化测试任务执行时长。效果上,核心产品线在覆盖率,问题发现数量未退化的情况下,执行时长缩短了 10%,但仍存在无法感知任务实时状态问题,因此在此基础之上,建立停止决策模型,通过实时监控任务的执行情况,基于执行时间,截图数,测试控件覆盖变化率等特征,实时决策任务是否可达到停止状态,并识别出执行效果不佳的任务,提前终止,降低无效执行的耗时。在优化效果上,在测试覆盖率提高 10% 的同时,执行时长减少 12%。
App 自动化用例在执行过程中,上下文环境会遇到各种非预期的复杂情况,如,App 触发升级弹窗、页面加载缓慢出现白屏、页面 xpath 路径变更等。现有自动化运行机制,不具备处理这些异常边界情况的能力,导致 Case 执行中断而失败。这些自动化稳定性问题,带来自动化用例维护成本的增加,大大降低了自动化工作的 ROI。我们分析现有自动化任务 top 失败原因,使用 3 类通用 Case 执行自愈技术,提升 case 执行稳定性,降低维护成本。
1、异常弹窗处理,当自动化执行遇到弹窗而失败后,使用弹窗检测技术去除弹窗后继续恢复执行。面对弹窗种类多样的难点,使用对象检测技术,实现泛化的弹窗及弹窗关闭控件的识别;面对不同语境下推荐动作不一致难点,利用基于页面文案进行弹窗分类的技术,实现不同场景下的弹窗都能够被准确理解,并推荐正确动作去除。
2、原子等待技术,自动化执行过程中的异步加载等待技术属于领域里公认技术瓶颈,我们利用视觉 UI 理解技术,在 Case 执行过程中,使用高效的视频流并行采集,以及图像识别算法对连续图片分析,实现页面稳定态和非稳定态的智能判定,指导 Case 实时的智能延迟等待和智能缩短等待时间,保证 Case 稳定高效执行。
3、通用 Case 自愈技术,提供基于时空上下文的 Locator,去弹窗,图像等识别方式按顺序进行识别自愈,具体来讲,将历史执行成功时刻的 xpath,icon 图片等信息记录下来,当出现失败时,尝试用历史成功过的元素类型依次进行重试。
通过以上 Case 执行自愈的技术,在我们自动化执行实践过程中,实现了 51% 的 Case 自愈修复效果,有效提升自动化用例执行稳定性。
测试分析是指测试活动通过设计测试用例、用例执行完成后,通过观察被测系统的表现,来判断被测系统是否存在问题。测试输入和测试分析两个过程共同决定了测试活动的问题召回能力,用平时常见的活动表示单测中的校验点即为测试分析,无校验点的单测是无效的。测试分析从理论层面可以分为 VE(正确性校验)和 VA(基于表现的校验)。在智能领域 VE 的研究领域更多的是如何正确的生成校验点、评估校验点的正确性和合理性;VA 因为涉及到通过数据统计分析系统分析规律发现问题,研究的领域比较广泛。
测试分析智能化通过将数据、算法、工程等相关技术有机结合,以尽可能召回测试输入覆盖到的场景或问题,一般包含直接的校验点自动生成、基于数据挖掘系统的潜在问题、基于视觉的 UI 召回等方面,在学术界和工业界均有非常优秀的研究和实践。本章节将从多个实践的角度,介绍相关领域的目标、思路、涉及到的技术点、效果,希望能给到大家一定参考。
契约是微服务或系统交互间的一种接口协议的约定,契约测试本质是验证代码的变更是否导致契约失效。契约测试主要包含生成契约、验证契约、更新契约三个过程,其中契约测试的准确性很大程度依赖契约的验证点。校验点的自动生成是在契约已生成的前提下自动生成能保障契约满足每个 consumer(消费方)需求的校验 CASE,并在契约发生变更时能自动检测更新校验点。与传统接口功能测试 CASE 的差别是,基于契约测试的检验 CASE 是消费者驱动由各个 consumer 的需求预期组成多份测试 CASE,而传统的功能接口测试 CASE 仅关注 provider 自身设计正确性,是一份功能测试 CASE。
基于契约测试的检验点自动生成主要思路是,获取不同 consume 的需求形成契约接口的内容,如请求参数、返回等,形成每个 consume 的契约描述。针对不同的契约描述进行流量录制(request、response 等信息),对录制好的信息进行数据预处理识别不同 consume 关联字段、筛选正常返回的响应信息。按照 URI、请求参数组合、response 结构等做分类,完成 schema 的提取与转化,即实现 n*consumer -> n* 枚举组合的接口框架识别;随后将接口框架导入 yapi,对每个组合 mock 数据形成独立检查点,通过 ITP CASE 的形式表达契约,进而用来达成重放契约中的请求,从根本上来说 CASE 的参数从契约定义中来,CASE 的断言为契约中返回数据的 json-schema。之后再通过逆向工程实现契约感知,常用方法之一是走读大量业务代码抽象代码风格,建立契约与代码间的精准关联,从而通过识别代码变更自动化感知契约的变更,一旦感知到契约的变更则同步更新 mock 数据,作为代替被测试程序的实际返回内容,实现检验 CASE 的自动更新。
对于曲线的校验,会应用于测试活动的大部分环节中,检测内存泄露就是典型的一个场景。但是传统的内存泄露检测时间周期长,准确率低,导致内存泄露测试任务转化较低,智能的曲线校验分析可以解决上述问题,主要分为两个方向:
首先是准确率提升。之前的算法是简单的人工经验判断,对测试人员经验要求高。对于这种场景使用 DTW 曲线相似度和 Cart 决策树的分类算法来实现判断是否存在内存泄露。DTW 曲线相似度算法,主要通过点和点之间的差距和时间序列的延生和缩短,计算新旧版本的内存曲线相似度,认为曲线不相似的为有内存泄露。DTW 实现简单,可以快速应用,但是也会存在一些误报警的 badcase。于是继续进行优化,通过 Cart 决策树,将 DTW 曲线计算的距离作为特征输入,再结合别的特征进行训练和预估,最终预测准确率从 75%->98%
另外测试时间缩短,之前的算法是直接使用固定时间,这样会有极大的时间浪费。对于这种场景解决方案是通过曲线的历史数据来预测不同模块需要多久便可以收敛,然后以收敛的点来压缩任务时长,模块应用后节省了 1/3 的测试时长。
性能测试结果准确性与测试环境有着很大的关系。现实中,由于硬件差异,运行时自身环境,第三方环境的差异,导致测试存在波动。因此我们通过设置阈值的方式,即根据性能指标的波动是否超过阈值,来判断是否存在风险。初期阈值都是通过人工经验设定的,但是由于任务运行时,内外部干扰因素太多,根据单次且固定阈值进行评估不现实,也不准确。因此我们建设了基于动态阈值的性能风险分析策略,用以提高测试任务准确性。
动态阈值的思想主要是通过对历史报告各指标数据的分析,实时预测各指标在当前容器下的可信度范围。对比当前指标值与阈值,不在阈值范围内的指标被认定为异常指标。在动态阈值的设定中,针对不同的业务特点,不同的场景,采用不同的计算策略算法。此处简单介绍两种算法。箱式分析法的思想主要是基于我们认为正常的指标在相同 QPS 下,应该是在固定值附近飘动,符合正态分布的。我们根据历史测试结果计算出正态分布的参数,然后在这个分布下圈定合理阈值。这样会使得阈值不受异常值的影响,能够更准确地描绘出数据的离散分布情况。LOF 算法的思想主要是通过比较每个点 p 和其邻域点的密度来判断该点是否为异常点,如果点 p 密度越低,越可能被认定是异常点。由此得到的正常区间,取最小、最大值,作为性能可置信阈值区间。自动态阈值策略接入后,多个模块性能任务黄灯率和重试率大比例降低。
基于功能测试的校验点智能补全,是在自动生成用例的背景下,自动生成更正确、合理、易于理解的断言,主要应用在单元测试用例的生成。在实际项目中,能人工通过业务功能来确认测试断言的函数,占比往往不足 5%,绝大多数的函数即使被覆盖,正确性难以保证。
解决思路是通过应用机器翻译方向的模型,来自动理解被测方法、学习被测方案与开发人员编写的测试用例,来推断出可验证内容,进而生成合理的断言集合。
首先,建立足够的扩充用例生成的数据集,包含大量被测代码和单测用例;然后,建立出被测函数和单测用例及其包含的断言的映射关系;接着,选取合适的机器翻译模型,学习样本中隐含的命名规则、逻辑、校验规则等;最后,根据学习结果输出用例。
理解被测方法是该场景的重点,需要选取合适的机器翻译模型,如 TestNMT,Reformer、transformer 等,并结合结合实际情况不断优化编码方式、切分方式、训练速度等。
我们实践了基于 transformer 的单测生成,解决了部分未登录词(OOV)和罕见词(Rare Words)的问题,断言准确率达到 41%。
基于视觉的有参照召回能力也称为 UI DIFF,主要思想是通过对比本次要校验的页面截图与正确的 UI 截图,指出两者之前的差异区域,生成可视化页面报告,测试工作者能够很方便对报告进行检查。我们针对不同的业务特点,不同的场景,采用不同的 DIFF 策略算法,主要包含:针对网页和 APP 的整页 diff 校验、自定义区域的 diff 校验能力,针对不同分辨率机型的 diff 校验能力,针对主版和矩阵版本(例如:手百和手百大字版)的 diff 校验能力。此外,为了降低满足不同测试场景的需求,我们提供了:高精版的像素级 diff 能力,低精版的布局样式级 diff 能力,连续帧动态区域过滤能力,视频、轮播图过滤能力,高相似度过滤能力等。开源数据集和技术细节详见:https://github.com/RYWei/Cross-Device-UI-Diff-DatasetUI。目前 diff 在部分重点业务线落地,识别准确率达到 90%+,覆盖约 12% 的业务前端项目,每个季度能够召回 100+ 有效问题。
相比于有参照召回,无参照召回无需对比图片,主要针对异常黑、白屏,组件重叠,文本截断,蓝屏花屏,裂图,乱码,null 等页面问题的挖掘。学术和工业界通常采用卷积神经网络实现检测。由于现实中,真实 bug 图片数据非常稀少,我们采用启发式合成技术,来构造训练数据集,解决样本不足的问题。另一方面,模型预测结果包含较多误报,我们进一步设计了后处理流程,针对图像区域干扰较多引起的误召回,通过页面结构树,过滤图片占比过大的数据;其他如广告,悬浮按钮,弹窗,toast,等误召回数据作为新的负样本,加入训练样本。如此重复多次训练,来提高模型鲁棒性。目前我们在重点业务线进行线上监控和巡检工作,异常纯色检测,乱码,裂图等能力实现了 98%+ 识别准确率,季度召回 20+ 线上第三方原因导致的产品体验问题。同时在遍历场景开展组件重叠,文本截断技术试点。