模板匹配

模板匹配

在 app 开发中,测试人员需要对新开发的功能进行各种测试,其中有个重要环节是对 app 页面进行一条链路的回归测试。比如在测试支付宝切换账号登录的操作是否正常时,就要人工依次点击(假设当前页面已在支付宝首页):“我的”,“设置”,“退出登录”,“换个账号登录”,输入新账号,“下一步”,输入密码,“登陆”,如果一切正常就能重新回到支付宝首页,这就是一条测试换账号登录功能的完整回归链路。一个很显然的思路就是预先将一条链路中要点击的区域抠成图像块(模板),然后利用图像块在当前页面去匹配,一旦命中,就触发点击行为,进入下一页;继续这种模板匹配的操作,直到完成整个链路,就能自动化地完成了回归测试。所以抽象出来,这其实就是计算机视觉中经典的模板匹配问题。

实际上,模板匹配方法无非就是用模板去和被匹配图像的局部像素块进行相似度计算,选择相似度高的局部像素块作为命中区域,达到匹配定位的目的。传统特征工程,提取的浅层特征无法准确表达模板和局部像素块的信息,导致计算的相似度误差很大。为此,我们对模板和局部像素块分别提取深度特征,通过计算深度特征之间的相似度来进行匹配识别,准确度大大提升。考虑到图像局部像素块的数目巨大,为了提升匹配速度,我们先对整个页面做一个热区检测。将模板匹配问题转化为了先对 app 页面的热区进行检测提取,再用预先抠出的模板和这些热区进行深度特征比对的问题。

热区检测

利用深度学习进行目标检测,需要一个打标的热区数据集。为此,我们尝试 android 系统工具辅助生成打标框,得到 app 中页面所有控件的坐标,作为热区坐标的备选项;再利用人工过滤和辅助标框的方式,得到热区坐标,构成了热区数据集。 我们将测试任务划分成一条条的回归链路,每条回归链路中的每个节点处运用匹配定位方法进行匹配,一旦匹配正确,就在热区触发点击操作,进入下一个节点,依次下去,直到最后一个节点,代表整个链路回归测试成功;一旦匹配错误,就直接报错,链路中断,测试失败

热区检测

对热区数据集分析发现,热区尺寸变化幅度较大,小的很小,大的很大,长宽比不一。我们选择了相对耗时,但准确度很高的经典 MaskRCNN 网络,其结构如图所示:

同时,因为数据集比较小,我们采用预训练模型进行迁移学习,提升热区检测准确度。

相似度匹配

基于 two channel 的相似度匹配算法

以制作训练数据集,利用深度学习方法训练相似度模型的方式来解决匹配问题。我们借鉴了发表于 2015 年这篇文章《Learning to Compare Image Patches via Convolutional Neural Networks》的思路。

基于预训练深度特征的相似度匹配算法

为了更充分地利用好深度特征,我们利用迁移学习的方法,将在 imagenet 数据集上训练的模型作为我们的预训练模型,在自己的数据集上重新 finetune 网络,得到深度特征提取器。在此之前,我们尝试直接用 imagenet 上预训练的模型去计算深度特征,再进行相似度比对,发现效果非常不错,基本满足了实际需求。

图像匹配与光学字符匹配的策略融合

仔细分析 app 页面数据,会发现文本信息非常丰富,为了更好地把这些信息利用起来,我们同时加入了光学字符识别(OCR)技术。对于那些含有文本信息的模板,我们直接将模板里的文字提取出来作为待匹配的模板字符串。再调用 ocr 服务得到每个热区的 ocr 结果,作为热区字符串。将模板字符串和热区字符串做比对,即能匹配上带识别的热区。

我们将图像匹配的结果和光学字符匹配的结果做个加权融合,能进一步提升热区识别的精准度,使得这个回归测试的问题基本得到了很好地解决。

异常页面与悬浮窗的检测识别

在回归流程中,预期的当前页面往往被一些异常情况所替代,如系统异常、加载失败、悬浮窗等等,导致自动化流程回归的失败。在实测中发现,这一现象还是非常普遍的。仅仅根据自动化回归提供成功或者失败两种结果,往往仍然会花费测试同学大量精力去定位失败原因。

根据测试需求,我们把这些异常情况划分成了两类。一类是我们只要识别出异常类型即可,比如属于系统异常,还是属于加载失败,我们称之为“异常页面问题”;另一类主要表现为弹窗,这些弹窗只要点击窗口旁边的关闭按钮就能消失,恢复到该节点预期的页面,我们称之为“悬浮窗问题”。很显然,在计算机视觉中,前者就是个简单的分类问题;后者由于不仅需要识别出当前页面是否属于该类弹窗,还要定位出让该弹窗关闭的按钮,所以这是一个单目标分类加回归的问题。

异常页面问题

解决异常页面分类问题,主要分成异常页面数据集的制作和异常页面模型训练两方面。

数据集

通过深度学习解决异常页面的分类问题,首先面临的就是如何获取到打标的异常页面数据集。我们结合了人工打标和数据增强两种手段来制作数据集。针对人工打标,首先模拟各种异常情况发生的测试环境(比如断网、弱网、各类账号登陆等)爬取大量的异常截屏数据,如下图所示,然后人工分开每种异常数据;针对数据增强,首先将出现的异常数据中的明显特征区域截取出来,然后合成到实际页面数据中,得到分类数据。将这两种手段获取到的数据以一定比例混合,作为最终的异常页面数据集。

模型训练

在获取到异常页面数据集之后,接下来就是对分类模型的训练。鉴于数据集中每类的数据量也就几千的量级,所以可以利用迁移学习方法,将 imagenet 上训练的 mobilenetv2 模型作为预训练模型,再在自身数据集上微调训练。最终得到了一个泛化能力还不错的异常页面模型。

悬浮窗问题

相对于异常页面,悬浮窗问题不仅仅需要对当前页面是否属于该类弹窗进行分类,还需要定位出让悬浮窗关闭的按钮。我们采用多任务模型,通过分类分支判断是否为悬浮窗;通过回归分支找到让悬浮窗关闭的按钮。

数据集

数据集分成分类数据集和回归数据集两个方面。分类数据集的制作,类似于异常页面数据集获取的方式。通过造账号,人工爬取和打标获取原始数据集;然后通过数据增强的方法得到最终的数据集。回归数据集是在分类数据集的基础上,人工打标上五个点,即悬浮窗四个点和关闭按钮一个点。

模型训练

根据模型设计方案,训练分成两部分。第一部分,先训练悬浮窗初步定位模型,由于是单目标,这里只要回归出悬浮窗四个顶点就可以了;第二部分,在悬浮窗初步定位模型基础上,得到悬浮窗的位置,在悬浮窗局部区域回归出让悬浮窗消失的关闭按钮,同时在分类分支输出该局部区域是否为该类悬浮窗。另外,考虑到数据规模小,我们训练中依然采用了迁移学习。这样最终得到悬浮窗模型。