作者 | intelligents
上一篇,介绍了测试活动测试输入、测试执行、测试分析、测试定位和测试评估五个步骤中测试执行智能化研究和实践,本章节重点介绍测试分析环节的智能化实践。
测试分析是指测试活动通过设计测试用例、用例执行完成后,通过观察被测系统的表现,来判断被测系统是否存在问题。测试输入和测试分析两个过程共同决定了测试活动的问题召回能力,用平时常见的活动表示单测中的校验点即为测试分析,无校验点的单测是无效的。测试分析从理论层面可以分为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的自动更新。
二、基于时间分片的C++内存泄露检测
对于曲线的校验,会应用于测试活动的大部分环节中,检测内存泄露就是典型的一个场景。但是传统的内存泄露检测时间周期长,准确率低,导致内存泄露测试任务转化较低,智能的曲线校验分析可以解决上述问题,主要分为两个方向:
首先是准确率提升。之前的算法是简单的人工经验判断,对测试人员经验要求高。对于这种场景使用DTW曲线相似度和Cart决策树的分类算法来实现判断是否存在内存泄露。DTW曲线相似度算法,主要通过点和点之间的差距和时间序列的延生和缩短,计算新旧版本的内存曲线相似度,认为曲线不相似的为有内存泄露。DTW实现简单,可以快速应用,但是也会存在一些误报警的badcase。于是继续进行优化,通过Cart决策树,将DTW曲线计算的距离作为特征输入,再结合别的特征进行训练和预估,最终预测准确率从75%->98%
另外测试时间缩短,之前的算法是直接使用固定时间,这样会有极大的时间浪费。对于这种场景解决方案是通过曲线的历史数据来预测不同模块需要多久便可以收敛,然后以收敛的点来压缩任务时长,模块应用后节省了1/3的测试时长。
三、基于动态阈值的性能diff检测
性能测试结果准确性与测试环境有着很大的关系。现实中,由于硬件差异,运行时自身环境,第三方环境的差异,导致测试存在波动。因此我们通过设置阈值的方式,即根据性能指标的波动是否超过阈值,来判断是否存在风险。初期阈值都是通过人工经验设定的,但是由于任务运行时,内外部干扰因素太多,根据单次且固定阈值进行评估不现实,也不准确。因此我们建设了基于动态阈值的性能风险分析策略,用以提高测试任务准确性。
动态阈值的思想主要是通过对历史报告各指标数据的分析,实时预测各指标在当前容器下的可信度范围。对比当前指标值与阈值,不在阈值范围内的指标被认定为异常指标。在动态阈值的设定中,针对不同的业务特点,不同的场景,采用不同的计算策略算法。此处简单介绍两种算法。箱式分析法的思想主要是基于我们认为正常的指标在相同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-Dataset。目前UI diff在部分重点业务线落地,识别准确率达到90%+,覆盖约12%的业务前端项目,每个季度能够召回100+有效问题。
相比于有参照召回,无参照召回无需对比图片,主要针对异常黑、白屏,组件重叠,文本截断,蓝屏花屏,裂图,乱码,null等页面问题的挖掘。学术和工业界通常采用卷积神经网络实现检测。由于现实中,真实bug图片数据非常稀少,我们采用启发式合成技术,来构造训练数据集,解决样本不足的问题。另一方面,模型预测结果包含较多误报,我们进一步设计了后处理流程,针对图像区域干扰较多引起的误召回,通过页面结构树,过滤图片占比过大的数据;其他如广告,悬浮按钮,弹窗,toast,等误召回数据作为新的负样本,加入训练样本。如此重复多次训练,来提高模型鲁棒性。目前我们在重点业务线进行线上监控和巡检工作,异常纯色检测,乱码,裂图等能力实现了98%+识别准确率,季度召回20+线上第三方原因导致的产品体验问题。同时在遍历场景开展组件重叠,文本截断技术试点。
———- END ———-
推荐阅读【技术加油站】系列: