2019年10月26日,由Testin主办的第二届NCTS中国云测试行业峰会在京召开,主题为“AI+未来”为主题,汇聚国内外测试领域知名专家学者、企业决策龙头、高层技术管理者、媒体从业者等,共同探讨高端云测试技术,助力测试从业者了解最前沿的行业趋势和最新的行业动态。实践。会上,北京大学计算机系博士生李元春作了主题演讲《强化学习在自动测试中的应用》。李元春介绍了GUI测试相关的研究并指出,“强化学习应用于GUI测试的难点主要在于状态的表示和奖励函数的设计,即如何将多模态特征如交互界面中的图像和文本。有效的编码,以及如何将测试目标转化为对测试输入的奖励。”以下为李元春演讲实录:大家好!很荣幸在这里分享我在GUI测试方面的工作,我叫李元春,我研究的方向是移动应用的隐私和安全。在做隐私和安全的时候相关分析,我经常使用静态分析或者动态分析技术,在动态分析中,如何对应用进行动态测试,让应用能够覆盖足够多的代码触发足够多的隐私安全敏感行为,这直接决定了隐私安全的完整性分析结果。因此,在接触到GUI测试的研究方向时,我也做了一个小小的探索性工作。今天分享给大家的内容更多的是技术实现。首先介绍一下GUI测试的背景,基于软件的图形界面,生成交互动作序列作为测试用例,应用场景主要有两种,一种是GUI遍历测试,即h下面来全面探索软件的功能。二是功能测试,比如测试一个应用的登录功能。生成的测试用例可以输入账户名,输入密码,点击登录。基于这两种场景,我分别使用深度学习和强化学习技术对其进行了探索。第一个是基于深度学习的GUI遍历测试。自动GUI遍历测试有两种主流策略。一种是随机策略。比如Android官方工具Monkey就是随机策略。这些工具就像猴子一样无法理解具体的GUI和代码来生成完全独立于代码内容的测试用例。第二个是基于模型的策略。对代码进行静态分析或动态分析,建立一个模型,用这个模型来指导输入。例如右图在学术论文中有一些工具。通过分析代码的执行路径,使用符号执行求解路径到达法,可以生成针对性更强的测试用例。这些方法的共同点是在测试的易用性和测试效率之间做出权衡。比如Monkey就是在牺牲效率来追求易用性。它可以快速测试任何应用程序,但它的缺点也特别明显。很难解释、扩展和重现随机测试用例。基于模型的策略通过分析代码生成用例。主要缺点是需要分析代码。现在很多应用的代码都异常复杂,混合了很多语言,利用了各种高级语言的特性,使得静态分析变得非常困难。另外,黑盒测试时无法获取源代码,或者代码被加密。在这种情况下,很难使用基于模型的静态分析方法。目前主流的方法是两者的平衡,也是基于模型来生成测试用例,但这种模型不是对代码进行分析和建模,而是对应用程序执行过程中的接口转换关系进行建模,即只作为记忆的功能,避免后面生成测试用例时输入无效。这就是刚才说的第三种方法,一种常用的界面转换图模型。例如,在这个模型中,每个节点就是界面的状态,每条边就是状态之间的转换关系。这样的模型之后,就可以测试应用程序了。右图是我之前做的一个工具DroidBot,可以黑盒子的为任何应用构造界面转换图。基于界面转换图,任何人都可以编写遍历测试策略,例如设计深度优先、广度优先、随机检测或启发式规则等。但是,使用这些简单的规则探索应用功能的效率往往很低不高,算法往往不能快速到达应用中的重要接口和功能。我们想到一个很奇妙的点。在进行手动测试时,无论是真正的测试人员还是用户,虽然对代码没有任何了解,但往往可以非常高效地探索应用程序界面。我们思考了其中的原因。主要有两点。首先,不同应用程序的GUI交互方式具有共同的特点。信息流的结构,即使在功能上没有相似之处,交互方式也是相似的。第二个原因是很多人虽然之前没有测试经验,但是用过很多应用,下意识的学习了各种交互方式。那么,我们就想,能不能用机器学习的方法来学习人们使用应用的交互方式,用这种交互方式形成机器学习模型,用这个模型来指导自动测试号的生成。当然,这里有很多挑战,比如如何对软件GUI的状态和动作进行机器化;如何设计一个模型来有效地捕获GUI的这些交互模式,等等。基于这样的想法,我们做了一个作品叫Humanoid。主要结构如下。首先,在离线学习阶段,假设收集了大量真实的用户交互数据。这些交互数据不是来自被测应用程序,而是可以来自任何应用程序。从线下用户交互记录数据中学习,将学习到的东西捕捉到交互模型中,然后用这个模型不断地指导和测试UI交互数据的生成。这就是我们如何解决Humanoid中的界面状态和动作表示。每个UI状态都表示为一个UI结构图。我们忽略了UI中的图片和文字信息,只有每个UI上的文字区域是哪个,图片区域是什么。这样做的目的是在有限的数据中收集更多更简化的UI特征,在机器学习中更容易泛化。在表达交互动作时,我们由两部分组成。首先是交互动作的类型,包括点击、滑动、输入等。第二个元素是交互动作的位置。交互动作在界面上发生的位置也直接用X、Y坐标表示,但往往需要将孤立用户点击的点转化为以该点为中心的分布,学习时每个数据点并不是孤立的但分布式,更容易学习。通过以上两种表示,明确了模型输入输出的映射关系。当前界面上下文包括面对面界面S和最近的几个交互。输出是两个概率分布,包括交互位置概率分布和交互动作类型概率分布。基于这两个概率分布,可以计算出每个交互动作的概率。这就是我们用来捕捉界面情境和界面交互关系的深度学习模型。可以看到界面上用了很多CNN来抓取图像信息。我们使用了4个交互序列。除了当前的交互界面状态,我们还使用了之前的三个交互历史。我们将这四个交互动作输入到一个LSTM中,提取界面交互特征后,将这个特征重新映射到原始交互输入上要产生交互动作的位置的概率分布。这是我们在模型训练后实际使用的伪代码。测试时,我们随机选择探索,或者使用模型。如果我们探索的话,用刚才的模型生成交互动作,然后执行交互动作。如果使用,请根据界面转换图导航回上一界面。人形实验评估,我们使用Rico数据集,涉及很多用户在使用应用时的交互记录。我们使用这些数据来训练UI转换模型。我们比较了6个有代表性的工具,一个是Monkey,还有PUMA等。学习交互模式的效果。该模型可以预测更高概率的真实用户交互动作。我们的模型可以将真实用户使用的交互动作排在前面,表明我们的模型已经有效地学习了交互信息。将该模型应用到真实测试中,虽然这些测试工具的覆盖率差异不是很大,但Humanoid可以做到最高的代码行覆盖率,对于市场上流行的应用也能做到比较高的接口覆盖率。这是Humanoid和其他工具的覆盖率提升速度的评估结果。可以看出红线是Humanoid的结果,可以比较快的达到较高的覆盖率,而且这条曲线有持续上升的趋势。第二部分是基于强化学习的UI功能测试。首先介绍一下UI功能测试的背景。我们的目的是生成一系列的UI交互动作来验证软件的具体功能。比如刚才说的登录例子,测试用例第一行是打开App,第二行是输入一个邮箱地址,下面一段代码是在密码框输入密码,最后点击登录按钮.人工编写测试用例费时费力,还需要人工进行测试修复,存在很大的效率问题。右侧展示了主流的工具和手工测试的示例,比如这个Sikuli工具,已经让写测试用例变得非常简单,但是对于没有测试经验的人来说,写这样的代码还是比较复杂的。我们要追求的是,??给定一个测试用例的文字描述,根据这个文字描述自动生成测试脚本。例如,对于Lyft/Uber网站,测试用例描述可能是“估算从一个位置到另一个位置的出租车费用”。我们希望通过理解自然语言和理解软件界面来生成右下角的测试脚本。在强化学习的问题中,有一个测试执行环境,它包括一个网络浏览器和一个奖励模型,以及一个用于强化学习的代理,它与测试执行环境一起交付,最后得到最终的测试脚本。强化学习中最重要的事情之一就是强化学习环境环境。强化学习环境给出了执行任务的初始状态,并告诉模型代理在当前状态下可以执行哪些动作。当代理在当前状态下执行一个动作时,返回该动作的奖励。奖励和新状态。强化学习应用于GUI测试的难点主要在于状态的表示和奖励函数的设计,即交互界面中如何对图像、文本等多模态特征进行有效编码,以及如何将测试目标变成一对测试回车奖励。在测试中,agent观察到的状态是当前界面的UI结构,可执行的动作是当前界面中所有可行交互输入的集合。测试环境需要允许代理执行一个动作并返回该动作的奖励。在设计强化学习环境的奖励函数(rewardfunction)时,设计目标是将更高的Reward分配给正确的动作序列,让强化学习找到正确的测试用例。我们在这里的观察是,如果一个交互序列是一个正确的测试用例,它通常满足以下三个指标:一是动作应该与任务参数相匹配。比如刚才说的A到B,两个点的打车费用,AB是这个任务的参数,我们必须有两个动作匹配这两个参数。二是UI的文字和描述的句子重叠。三是动作顺序需要符合真实用户的交互习惯。比如生成测试用例的时候,不能说点击页面底部,点击中间,跳来跳去。这很可能是不正确的。我们需要添加一些约束,使代理能够在测试期间与UI正确交互。目前主流的强化学习算法之一是Q网络,它使用深度神经网络来估计Q函数。Q函数以当前状态s和选择的动作a为参数,返回在当前状态s下执行动作a的值。在我们的模型中,状态s和交互动作a分别用于提取图像信息和文本信息,并作为Q网络的输入进行交叉融合,最终估计出Q值。这是强化学习算法生成的最终示例。从A到B的出租车费用测试用例可以生成三个脚本,每个脚本都有一些最终的奖励积分。我们评估了基于强化学习的测试输入生成方法,选取了十类网站,共计73个网站,在这些网站上定义了41个测试描述,比如“bookingatablefor4at8pminBoston”就是一个测试案例描述,将这些作为测试用例,然后我们得到172个测试用例描述和网站的组合。我们的目标是为每个组合生成一个测试脚本。最后我们评估的时候,让我们的强化学习算法针对每个测试用例描述和网站运行一个小时,得到最高的交互训练,然后进行人工评估。这是我们最终的评估结果。top1准确率为65.7%,top5准确率为76.6%。我们将其与常见的搜索算法进行了对比,可以看出强化学习能够取得比较高的优势。最后总结一下,虽然深度学习和强化学习在测试中的应用前景广阔,但要实现大规模实用化还有很长的路要走。难点包括:首先,考这道题本来就很复杂。目前的深度学习主要以图片或文字作为输入,而UI是一种比较复杂的信息,既包括视觉信息,也包括文本信息。捕捉UI特征的良好模型或方法。第二个问题,强化学习算法成功的领域往往是游戏。比如强化学习可以很好的解决围棋。一个重要的原因是,在游戏领域,Reward是比较明确的,但是在测试中,想评价一个测试用例的好坏,并没有一个准确的指标。经过最终的评估,每个测试用例,无论是正确的还是错误的,都会得到非常相似的Rewards,这使得强化学习模型很难区分正确的。和错误。要解决这些问题,一方面有研究上的挑战,另一方面也有很多工程问题需要解决,需要学术界和工业界的共同努力来解决。今天的演讲就到这里,谢谢!
