A Deep Learning based Approach to Automated Android App Testing
Abstract
自动输入生成器广泛用于移动应用程序的大规模动态分析和测试。这样的输入生成器必须不断地选择与其交互的UI元素以及如何与其交互,以便在有限的时间预算下实现高覆盖率。目前,大多数输入生成器采用伪随机或强力搜索策略,这可能需要很长时间才能找到可以将应用程序驱动到新的重要状态的正确输入组合。在本文中,我们提出了Humanoid,一种基于深度学习的自动Android应用程序测试方法。我们的见解是,如果我们可以从人类生成的交互跟踪中学习,则可以基于当前UI状态和最新状态转换中的视觉信息生成类似人类的测试输入。我们设计并实现了一个深度神经网络模型,以了解最终用户如何与应用程序进行交互(具体来说,与哪些UI元素进行交互以及如何进行交互),并表明我们可以基于以下任何新UI成功生成类似人类的输入学习的模型。然后,我们将该模型应用于Android应用程序的自动化测试,并证明它能够比最先进的测试输入生成器获得更高的覆盖率和更快的速度。
Index Terms—Software testing, automated test input generation, graphical user interface, deep learning, mobile application
relevant information | |
---|---|
作者 | Yuanchun Liy, Ziyue Yangy, Yao Guoz, Xiangqun Chen |
单位 | Key Laboratory of High Confidence Software Technologies (Ministry of Education) Peking University |
出处 | arXiv |
原文地址 | https://arxiv.org/abs/1901.02633 |
源码地址 | |
发表时间 | 2019年 |
1. 简介
移动应用程序(简称应用程序)近年来得到了广泛采用,在Google Play和Apple App Store中可以下载超过300万个应用程序,同时已经累积了数十亿次下载[1],[2]。这些应用程序需要在发布之前进行充分测试,以便希望确保其应用程序正常运行的应用程序开发人员以及希望阻止恶意应用程序发布的应用程序市场。但是,由于快速的发布周期和有限的人力资源,开发人员和审计人员很难在短时间内手动构建测试用例。因此,移动应用程序的自动测试输入生成器已在学术界和工业界广泛研究。
移动应用程序的测试输入通常由与应用程序的图形用户界面(GUI)的交互来表示。具体地,交互可以包括点击,滚动或输入文本到GUI元素,例如按钮,图像或文本块。输入生成器的工作是为受测试的应用程序(AUT)生成一系列交互,可用于检测软件问题,例如错误,漏洞和安全问题。测试输入生成器的有效性通常通过其测试覆盖率来衡量。给定无限时间,可以尝试所有可能的交互序列和组合以实现完美的测试覆盖。但是,在实际情况下,测试时间有限且AUT可能包含数百个GUI状态和每个状态中的数十个可能的交互,测试输入生成器只能选择一小部分交互序列来探索。
自动化测试输入生成器成功的关键是为给定的UI(测试期间的当前UI)选择正确的交互,以便所选择的交互可以达到新的和重要的UI状态,这反过来将导致额外的UI状态。因为机器很难理解GUI布局和GUI元素内的内容,所以也难以确定点击哪个按钮或应该输入什么。因此,大多数现有的测试生成器[3] - [6]忽略了各种类型的UI元素之间的差异,并应用随机策略来选择一个与之交互。甚至其中一些可能维护应用程序的GUI模型,该模型仅用于记住已探索的状态和交互以避免重复探索。虽然随机策略也可以进一步优化,但它具有固有的局限性,使得难以选择最有效的路径来找到可以在短时间内将应用程序驱动到重要状态的交互。
与随机输入生成器相反,人类测试人员可以轻松识别值得与之交互的UI元素,即使对于他们以前从未见过的新应用程序也是如此。原因是人类测试人员本身就是应用程序用户,因此他们已经获得了有关各种移动应用程序的一些经验和知识。因此,人类测试人员知道在哪里点击以及输入什么,以便获得更高的覆盖率,并且花费更少的时间。我们要在本文中研究的关键问题是:我们可以教一个自动测试输入生成器,使其表现得像人类一样吗?
本文提出了Humanoid,一种自动GUI测试生成器,能够了解人类如何与移动应用程序交互,然后使用学习模型指导测试生成作为人类测试人员。利用从人工交互轨迹中学到的知识,Humanoid可以根据GUI页面的重要性和意义来确定GUI页面上可能的交互的优先级,从而生成可以更快地导致重要状态的测试输入。
我们可以使用图1中所示的GUI页面作为激励示例。可以在该页面上执行20多个操作,但大多数操作无效或与AUT的核心功能无关,例如在当前页面上向左滑动(实际上不可滚动)或单击广告底部。虽然随机输入生成器可能必须尝试所有可能的选择(包括那些无效的选择),但Humanoid能够增加单击菜单按钮的概率,这更有可能将AUT驱动到其他重要的GUI状态。
Humanoid的核心是一个深度神经网络模型,它预测UI页面上的真实用户更有可能与哪些UI元素进行交互以及如何与其进行交互。模型的输入是当前UI状态以及最近的UI转换,表示为一堆图像,而输出是可能的下一个动作的预测分布,包括动作类型和屏幕上的相应位置坐标。通过将预测分布与UI页面上的所有可能动作进行比较,Humanoid能够为每个动作分配概率,并选择具有较高概率的动作作为下一个测试输入。
我们实现了Humanoid,并使用从大规模众包源的UI交互数据集Rico中提取的304,976个人类交互来训练交互模型[7]。只需更换输入选择逻辑,即可轻松将模型与其他测试工具集成。
为了评估Humanoid,我们首先检查了Humanoid是否可以通过使用它来为交互跟踪数据集中的每个UI状态的可能操作划分优先级来学习人类交互模式。结果表明,对于交互痕迹中的大多数UI状态,根据人形预测概率,人类执行的动作在所有动作中排名前10%,这明显优于预期为50%左右的随机策略。
为了评估交互模型在app测试中的有效性,我们将Humanoid与六个最先进的测试生成器进行了比较。用于测试的应用程序包括从AndroTest [8]数据集获得的68个开源应用程序,这是一个广泛使用的基准数据集,用于评估Android测试生成器。我们还测试了来自Google Play的200个热门应用,看看Humanoid在更复杂的应用中是否也有效。根据实验,Humanoid能够为开源应用程序实现43.1%的线路覆盖率,并为市场应用程序实现24.1%的活动覆盖率,在相同的时间内,这显着高于使用其他测试生成器实现的最佳结果(38.8%和19.7%)。
本文的主要贡献如下:
- 1)据我们所知,这是第一部通过挖掘GUI交互跟踪来介绍通过深度学习生成类人测试输入的想法,以改进自动化移动应用程序测试。
- 2)我们提出并实现Humanoid,一种基于深度学习的方法,通过学习人类交互痕迹来生成类似人类的测试输入。
- 3)我们使用开源应用程序和流行的市场应用程序来评估Humanoid。结果表明,Humanoid能够比最先进的方法获得更高的测试覆盖率和更快的速度。
II.背景和相关工作
A.Android UI
对于移动应用,用户界面(UI)是人与机器之间发生交互的地方。应用程序开发人员设计UI以帮助用户了解其应用程序的功能,并且用户可以通过UI与应用程序进行交互。图形用户界面(GUI)是大多数移动应用程序最重要的UI类型,其中应用程序在屏幕上显示内容和可操作的小部件,用户使用点击,滑动和文本输入等操作与小部件交互。
移动应用程序中显示的GUI页面(或屏幕截图)通常使用树状结构布局。例如,在Android应用程序的屏幕截图中,所有UI元素都是使用View和ViewGroup对象构建的,并组织为tree。视图是一个叶节点,它在屏幕上绘制用户可以看到和交互的内容。 ViewGroup是一个父节点,它包含其他节点以定义接口的布局。UI状态可以被识别为当前UI树中的结构和内容的快照,并且UI树中的节点被称为UI元素。
可以将应用程序视为许多GUI状态及其之间转换的组合。每个GUI状态提供不同的功能或呈现不同的内容。应用程序用户通过与UI元素交互在UI状态之间导航。
B.自动GUI测试生成
自从移动应用程序普及以来,自动GUI测试生成已经成为一个活跃的研究领域。大多数研究工作都针对Android平台,部分原因是Android应用程序的普及,以及Android设备和操作系统版本的碎片化。
在Android中,测试工具以与人类相同的方式与应用程序交互:将模拟手势发送到应用程序的GUI。由于UI状态中可接受的手势是有限的,因此不同测试生成器之间的主要区别在于它们用于确定这些操作的优先级的策略。主要有三种策略:随机,基于模型和目标。
使用随机策略的典型示例是Monkey [3],这是Android中自动应用程序测试的官方工具。 Monkey将随机类型的输入事件发送到屏幕上的随机位置,而不考虑其GUI结构。 DynoDroid [4]也使用随机策略,而DynoDroid发送的输入比Monkey更聪明:许多不可接受的事件根据应用程序中的GUI结构和注册事件监听器被过滤掉。 Sapienz [9]利用遗传算法优化随机测试序列。 Polariz [10]提取并重用人类测试者获得的图案,以帮助生成随机测试序列。
其他几个测试工具构建并使用应用程序的GUI模型来生成测试输入。这些模型通常表示为存储应用程序窗口状态之间转换的有限状态机。这种GUI模型可以动态构建[5],[6],[11] - [17]或静态[18]。基于GUI模型,测试工具可以生成快速将应用程序导航到未探测状态的事件。基于模型的策略可以以各种方式进行优化。例如,Stoat [14]可以基于现有的探索迭代地改进测试策略,DroidMate [15]可以通过从其他应用程序挖掘来推断UI元素的可接受动作。
目标策略旨在解决某些应用行为只能通过特定测试输入显示的问题。例如,恶意应用程序可能只在收到某个广播时发送短信[19]。这些测试工具[20] - [22]通常使用复杂的技术,如数据流分析和符号执行,来找到可以导致目标状态的交互。但是,它们的有效性很容易受到应用程序代码的复杂性以及将代码映射到UI元素的困难的影响。
现有测试生成器的一个主要缺点是它们忽略了UI元素的可视信息,这是人类用户或测试人员在探索应用程序时的重要参考。在Humanoid中,我们尝试通过了解应用程序的GUI如何影响用户与其交互的方式来指导测试生成。
C.软件GUI分析
GUI是包括Android在内的大多数主要平台上不可或缺的软件部分。分析应用程序的GUI是许多研究人员和从业者非常感兴趣的。该领域主要有两个研究领域。一个是从软件工程的角度理解应用程序的行为。另一种是从人机交互的角度来分析用户界面设计。
如前所述,许多自动化测试工具构建并使用GUI模型来指导测试输入生成。与主要使用UI状态之间的转换来抽象应用程序行为的模型不同,还有一些方法侧重于分析每个UI状态中的信息。例如,Huang等人 [23]和鲁宾等人 [24]提出通过比较实际行为与UI来检测Android应用程序中的隐秘行为。 PERUIM [25]提取了应用程序对其UI的权限之间的映射,以帮助用户理解为何请求每个权限,而AUDACIOUS [26]提供了一种基于UI组件控制权限访问的方法。陈等人[27]引入了一种基于机器学习的方法,从UI图像中提取UI骨架,以便于GUI开发。
在人机交互研究中,软件GUI主要用于挖掘UI设计实践[28],[29]和交互模式[30]。挖掘的知识可以进一步用于指导UI和UX(用户体验)设计。为了促进移动应用程序设计挖掘,Deka等人收集并发布了一个名为Rico [7]的数据集,其中包含大量UI屏幕和人工交互。
我们的工作在于软件工程与人机交互之间的交叉:我们提出了一种深度学习方法,用于从Rico数据集中挖掘人类交互模式,并使用学习模式来指导自动化测试。
III.我们的方法
为了在移动应用程序上运用人类知识来增强移动应用程序测试,本文提出了Humanoid,一种新的自动化测试输入生成器,能够根据人类生成的应用程序交互跟踪中自动学习的知识生成类似人类的测试输入。与许多现有测试工具类似,Humanoid使用GUI模型来理解和探索被测试应用程序的行为。但是,与传统的基于模型的方法不同,传统的基于模型的方法随机选择在探索UI状态时要执行的操作,Humanoid会优先考虑更有可能与人类用户交互的UI元素。我们希望这种类似人类的探索能够比随机策略更快地将应用程序推向重要状态。
A.方法概述
图2显示了Humanoid的概述。 Humanoid的核心是一个机器学习模型,它学习人类如何与应用程序交互的模式。基于交互模型,整个系统可以分为两个阶段,包括用于生成具有人类生成的交互轨迹的模型的离线阶段和用于指导测试输入生成的在线阶段。
在离线学习阶段,我们使用深度神经网络模型来学习GUI上下文和用户执行的交互之间的关系。 GUI上下文被表示为当前UI状态和最新UI转换中的视觉信息,而交互被表示为动作类型(触摸,滑动等)和动作的位置坐标。在从大规模人类交互轨迹中学习之后,Humanoid能够预测新UI状态的动作类型和动作位置的概率分布。然后可以使用预测的分布来计算每个UI元素与人交互的概率以及如何与其交互。
在在线测试阶段,Humanoid为被测应用程序(AUT)构建一个名为UI转换图(UTG)的GUI模型。 Humanoid使用GUI模型和交互模型来决定要发送的测试输入。 UTG负责指导Humanoid在已探索的UI状态之间导航,而交互模型则指导探索新的UI状态。
B.交互跟踪预处理
首先,我们需要一个带有人工交互跟踪的大型数据集(Rico [7])来训练用户交互模型,这是Humanoid中的关键组件。因为Rico中的人工交互痕迹不是为我们的目的而设计的,所以我们首先需要预处理交互痕迹。
原始人类交互轨迹通常是发送到屏幕的连续运动事件流[7],其中每个运动事件由何时(时间戳)和光标(用户的手指)进入的位置(x,y坐标)组成,移动,离开屏幕。由于动画和动态加载的内容,状态更改也是连续的。
我们模型可接受的输入是一组用户交互流程。每个交互流程由一系列UI状态<s~1~, s~2~, s~3~……,s~n~>和在相应的UI状态中获取的一系列动作<a~1~, a~2~,a~3~……,a~n~>组成。要将原始交互跟踪转换为我们模型可接受的格式,我们需要分割光标移动并从中识别用户操作。
我们在Humanoid中考虑七种类型的用户操作,包括touch,long_touch,swipe_ up / down / left / right和input_text。每个操作都由操作类型和屏幕上的目标位置表示。为了从原始光标跟踪中提取用户操作,我们首先将光标移动聚合到交互会话中。
交互会话定义为光标进入屏幕和光标离开屏幕之间的时间段。我们将会话开始和会话结束的时间戳表示为time~start~和time~end~,将光标位置表示为loc~start~和loc~end~。然后我们根据启发式规则列表将交互会话映射到用户操作,如表I所示。
一旦我们提取了行动序列<a~1~, a~2~,a~3~……,a~n~>,我们能够将UI状态更改与基于操作时间戳的操作相匹配。我们使用在a~i~ 的时间戳之前捕获的UI状态作为s~i~来形成状态序列<s~1~, s~2~, s~3~……,s~n~>。状态序列和动作序列一起表示用户交互流,其将用作我们的人交互模型的训练数据。
C.模型训练
本节详细介绍了我们如何使用机器学习模型从人类交互痕迹中学习人类交互模式。最终用户根据他们想要对应用程序执行的操作以及他们在GUI上看到的内容与应用程序进行交互。由于不同的应用程序通常共享通用的UI设计模式,因此直观的是人类与GUI交互的方式可以在不同的应用程序中进行推广。交互模型的目标是捕获这种可推广的交互模式。
我们引入了一个概念UI上下文来模拟人们在与应用程序交互时引用的内容。 UI上下文 context~i~ 包括当前UI状态s~i~和三个最新UI转换(s~i-1~, a~i-1~), (s~i-2~, a~i-2~), (s~i-3~, a~i-3~)。当前UI状态表示用户在执行操作时看到的内容,而最新的UI转换用于在当前交互会话期间对用户的潜在意图进行建模。
图3显示了我们如何在模型中表示UI状态和操作。每个UI状态表示为双通道UI骨架图像,其中第一个通道(红色通道)呈现文本UI元素的边界框区域,第二个通道(绿色通道)呈现非文本UI的边界框区域元素。我们使用UI骨架而不是原始屏幕截图的原因是屏幕截图上的大多数字符不会影响人类与应用程序的交互方式。例如,同一应用程序的UI样式(字体大小,按钮样式,背景颜色等)可能会在不同的操作系统和应用程序版本中发生变化,而用户使用应用程序的方式则保持不变。有些应用甚至提供“夜间模式”等功能,允许用户在内部更改UI样式。这样的UI样式字符可能会给我们的模型带来噪声并影响模型的泛化能力,因此我们将它们从输入表示中排除。
每个动作由其动作类型和目标位置坐标表示。动作类型被编码为三维向量,其中每个维度映射到前面描述的七种动作类型之一。操作目标位置编码为热图。热图中的每个像素是像素在动作目标位置的概率。我们使用热图而不是原始坐标来表示动作位置,因为原始坐标是高度非线性的并且更难以学习[31]。
总之,UI上下文的表示,即我们的交互模型的输入特征,是一堆图像,包括用于当前UI状态的一个2通道图像和用于三个最新UI转换的三个3通道图像(每个转换包括一个用于UI状态的双通道图像和一个用于动作的单通道图像)。所有图像都缩放到180x320像素的大小。为了便于学习,我们还为当前UI状态添加了一个零填充通道。最后,UI上下文表示为4x180x320x3向量。
给定UI上下文向量,交互模型的输出是可能由人在当前状态下执行的“动作”。请注意,预测的“动作”不是当前UI状态中的实际可接受动作。相反,它是预期的类人行为的类型和位置的概率分布。具体而言,该模型的目标是学习两个条件概率分布:
1)p~type~(t | context~i~)其中t ∈ {touch, long_touch;swipe_up,…… },意思是给定当前UI 上下文的情况,下一个动作a~i~的类型的概率分布t。
2)ploc(x, y | context~i~)其中0 <x <screen_width和0 <y <screen_height,表示在给定当前UI上下文的情况下,下一个动作a~i~的目标位置x,y的概率分布。
图4显示了用于学习上面定义的两个条件概率分布的深度神经网络模型。它接受当前UI上下文 context~i~ 的表示作为输入,并输出a~i~的位置和类型分布。该模型由五个主要部分组成:卷积层,残余LSTM模块,去卷积层,完全连接层和 损失函数。
卷积层。卷积网络结构已经成为一种流行的图像特征提取方法,因为它已被证明在大型真实世界数据集上的计算机视觉任务中非常强大[32]。在我们的模型中,我们使用具有RELU激活的5个卷积层来从UI骨架图像和动作热图提取特征。在每个卷积层之后,有一个stride-2 max-pooling层,它将输入的宽度和高度减少到一半。池化层还有助于模型识别具有相同形状但环境不同的UI元素。
剩余的LSTM模块。 LSTM(长短期记忆)网络在序列建模问题中被广泛采用,例如机器翻译[33],视频分类[34]等。在我们的模型中,从历史转换中提取特征也是序列建模问题。我们在最后3个卷积层的每一个之后插入残余LSTM模块,以便捕获不同分辨率级别上的UI转换序列特征。在残余LSTM模块中,输入的最后一维和正常LSTM的输出通过剩余路径直接相加。
这种残留结构使神经网络更容易优化[35],并提示动作的位置应位于UI元素内。为了降低模型复杂度,我们还在每个残余LSTM模块之前添加了1x1卷积层,以减少特征维度。
去卷积层。该组件用于从残余LSTM模块的低分辨率输出生成高分辨率概率分布。有几种方法可以实现这一点,例如双线性插值,反卷积等。我们使用反卷积层,因为它更容易与深度神经网络集成,并且比插值方法更通用。将不同分辨率级别的特征组合在一起,以提高生成热图的质量[36]。接下来使用softmax层来标准化生成的热图,使得热图中的所有像素总和为1,这是动作位置的概率分布。
完全连接的层。使用softmax的单个完全连接层用于生成动作类型的概率分布。
损失函数。该模型将行动位置和行动类型预测为概率分布。因此,它们对地面事实(由人类执行的动作)的交叉熵损失适合于模型优化。我们使用这两个损失的总和和层权重正则化器作为训练过程中的最终损失函数。
在训练期间,交互流中的每个动作ai(<s~1~, s~2~, s~3~ ……, s~n~>,<a~1~, a~2~, a~3~…… a~n~>)将转换为以下概率分布:
和
$$
p_{loc}(x, y)= f(x - a_i.x, y - a_i.y)
$$
其中f是方差= 20的高斯分布的密度函数,我们使用高斯分布来逼近实际屏幕的概率分布当多个人多次交互相同的UI元素时,设备识别的坐标。
类似地,在应用模型时,我们使用当前UI状态的表示来提供它,以预测下一个动作的概率分布p~type~(t)和p~loc~(x, y)。由于预测的分布不能直接用于指导测试生成,我们需要进一步将它们转换为可以在当前状态下执行的操作的概率。为此,我们首先遍历UI树以查找当前状态中的所有可能操作,每个操作包含操作类型(表示为action.type)和操作目标元素(表示为action.element)。然后我们根据模型预测的分布计算每个动作的概率:
$$
p(action) = p_{type}(action.type) ∗ \sum_{x,y在action.element}p_{loc}(x, y)
$$
动作概率可能最终用于指导下一步的测试输入生成。
D.引导测试生成
在本节中,我们将描述如何应用人类交互模型来生成类似人类的测试输入。
Humanoid生成两种类型的测试输入,包括探索和导航。探索输入用于发现应用程序中看不见的行为,而导航输入将应用程序驱动到包含未探测操作的已知状态。当从探索输入中选择时,测试生成器不知道每个测试输入的结果,并且基于人类交互模型的指导做出决定(传统的测试生成器通常随机选择输入)。当生成导航输入时,测试生成器知道输入的目标状态,因为它已经保存了转换的存储器。
与许多现有的测试生成器类似,Humanoid使用GUI模型来保存转换的内存。我们使用的GUI模型表示为UI转换图(简称UTG),它是有向图,其节点是UI状态,边是导致UI状态转换的动作。 UTG是在运行时构造的:每次测试生成器观察到新的状态si时,它都会添加一个新的边<s~i-1~; a~i-1~; s~i~>到UTG,其中s~i-1~是最后观察到的UI状态,a~i-i~是在s~i-1~中执行的动作。图5显示了UTG的一个例子。使用UTG,测试生成器可以通过遵循状态路径导航到任何已知状态。
为了在探索和导航之间做出决定并生成输入动作,Humanoid采用了一种简单但有效的策略,如算法1所示。在每个步骤中,Humanoid检查当前状态中是否存在未探测的动作。如果存在未探测的动作,Humanoid会选择探索(第8行),如果完全探索当前状态,则选择导航(第10行到第12行)。导航过程很简单。在探索过程中,Humanoid获取交互模型预测动作的概率,并基于概率进行加权选择。由于人类将采取的行动将被赋予更高的概率,因此人类生物体作为测试输入被选择的机会更高。因此,Humanoid生成的输入比随机选择的输入更像人类。
与现有的测试工具相比,Humanoid的主要特征(以及不同基于模型的测试生成器之间的主要区别)是如何选择探索输入(第8行)。 Humanoid基于交互模型对勘探中更有价值的行为进行优先级排序,交互模型已经从人类交互痕迹进行了训练。此功能可以更快地发现正确的输入序列,从而将应用程序驱动到重要的UI状态,从而提高测试覆盖率。
IV.评估
我们主要通过以下几个方面评估Humanoid:
- 1)Humanoid能否学习人类交互模式?具体而言,交互模型能否以高精度预测UI状态下的用户操作?
- 2)Humanoid需要多长时间才能使用交互模型?具体而言,训练模型和预测行动概率需要多长时间?
- 3)当训练好的交互模型用于指导测试生成时,Humanoid可以实际上实现更高和更快的覆盖吗?
我们进行了两次实验来回答这些问题。首先,我们使用人类交互痕迹的数据集来训练和测试交互模型。我们研究了该实验中的模型精度和时间效率。其次,我们将在数据集上训练的模型集成到测试生成器中,并使用测试生成器对两组不同的Android应用程序进行测试。我们测量了Humanoid的测试覆盖率和测试进度,并将结果与几种最先进的测试工具进行了比较。
A.实验设置
我们用于训练和测试Humanoid模型的数据集是从Rico [7]处理的,Rico [7]是人类交互的大量人群源数据集。我们通过识别动作序列和状态序列从原始数据中提取交互流。最后,我们获得了12,278个属于10,477个应用程序的交互流程。每个交互流平均包含24.8个状态。每个UI状态中可能的动作数量的累积分布函数(CDF)如图6所示。平均而言,每个UI状态有50.7个可能的动作候选者,而超过10%的UI状态包括100多个动作候选者。
我们用来训练和测试交互模型的机器是一个带有两个Intel Xeon E5-2620 CPU,64GB RAM和一个NVidia GeForce GTX 1080 Ti GPU的工作站。该机器的操作系统是Ubuntu 16.04。该模型采用Tensorflow [37]实施。
在测试覆盖率评估实验中,我们使用了4台计算机,其硬件和软件与上述相同。我们在每台机器上运行了4个Android模拟器实例,以并行测试应用程序。我们用于测试的应用程序包括从AndroTest [8]获得的68个开源应用程序,这是一个用于评估Android测试输入生成器的常用数据集,以及从Google Play下载的200个流行商业应用程序。在测试开源应用程序时,我们使用Emma [38]来测量行覆盖率。对于没有源代码的商业应用程序,我们使用活动覆盖率(达到的活动的百分比)来衡量测试性能。
B.交互模型的准确性
在这个实验中,我们在现有的人类交互痕迹上训练和测试了我们的交互模型,以了解该模型是否能够了解人类如何与应用程序交互。
我们从数据集中随机选择了100个应用程序,并使用它们的交互跟踪进行测试。其余10,377个应用程序的交互痕迹用于训练。总的来说,我们有302,382个用于训练的UI状态和用于测试的2,594个UI状态。对于测试集中的每个UI状态,我们使用交互模型来预测所有可能操作的概率,并按预测概率的降序对操作进行排序。人类所采取的行动被视为基本事实。
表II示出了在每个UI状态中对人类执行的动作进行优先级排序时Humanoid人交互模型的准确性。具体而言,我们计算了地面实况(人类执行的动作)按照交互模型预测的动作顺序排在前N(N = 1,3,5,10)内的概率。为了比较,我们还计算了随机策略的topN准确度,即如果动作是随机顺序,则地面实况排名前N的概率。根据结果,我们的交互模型可以更准确地识别人类生成的行为并确定其优先级。
特别是,Humanoid能够为超过50%的UI状态分配人类生成动作的最高概率。我们还计算了每个UI状态中人为操作的百分位数。平均百分位数排名为20.6%,中位数为9.5%,这意味着Humanoid能够将类似人类的行为优先于大多数UI状态的前10%。
C.交互模型的开销
我们然后评估了交互模型的开销。使用包含304,976个人为操作的数据集训练交互模型大约需要66个小时。这是可以接受的,因为模型在用于测试之前只需要训练一次。用于预测UI状态的动作概率所花费的平均时间是107.9毫秒。鉴于Android测试生成器通常需要2秒以上的时间来发送测试输入并等待加载新页面,我们的交互模型将给测试生成器带来的时间开销很小。
D.引导测试的覆盖率
在该实验中,我们使用在先前实验中训练的交互模型来指导测试生成。我们通过检查它是否能真正提高测试覆盖率来评估指导测试发生器。
我们测试了两套应用程序,包括68个开源应用程序和200个流行的市场应用程序。我们将Humanoid与六款最先进的Android测试生成器进行了比较,包括Monkey [3],PUMA [12],Stoat [14],DroidMate [15],Sapienz [9]和DroidBot [11]。所有工具都使用其默认配置。 PUMA,Stoat,DroidMate和DroidBot的输入速度接近600个事件/小时,因为他们都需要在执行操作之前读取UI状态并在发送输入后等待状态转换,而Monkey和Sapienz可以发送输入事件速度非常快(在我们的实验中大约6000次/小时)。
我们使用每个测试工具运行每个开源应用程序1小时,每个市场应用程序运行3个小时。为了适应最近的市场应用程序,大多数工具都是在Android 6.0上进行评估的,因为它得到了大多数工具的支持(一些工具经过了少量修改)。然而,由于Sapienz是近源的并且仅支持Android 4.4,因此它在Android 4.4上进行了评估。对于每个应用和工具,我们记录了每个操作执行后的最终覆盖率和渐进覆盖率。我们重复这个过程三次,并使用平均值作为最终结果。
1)开源应用程序的行覆盖率:开源应用程序上的测试工具实现的行覆盖率的总体比较如图7所示。平均而言,Humanoid实现了43.1%的行覆盖率,这是最高的跨所有测试输入生成器。
有趣的是,采用随机探索策略的Monkey实现了比除Humanoid之外的所有其他基于模型的测试工具更高的覆盖率。 Monkey比其他大多数测试工具表现更好的事实也得到了其他研究人员的证实[39]。因为Monkey能够在相同的时间内生成比其他工具更多的输入。但是,我们的工作证明了基于模型的方法的可扩展性的好处。如果正确使用GUI信息,基于模型的测试工具具有实现更好测试性能的巨大潜力。
每个应用程序的详细行覆盖范围如表III所示。对于一些应用程序,如#3,#36和#45,Monkey的覆盖范围要高得多。原因是Monkey可以生成许多其他工具不支持的输入(例如意图和广播)。对于大多数其他应用程序,Humanoid取得了最佳效果,特别是对于#6,#18,#30等应用程序。
我们进一步研究了为什么Humanoid能够通过检查详细的测试痕迹来超越其他测试工具。我们仔细检查了五个应用程序,其中Humanoid实现了更高的覆盖率。我们发现了一些Humanoid表现优于其他人的情况,如表IV所示。总而言之,Humanoid的高覆盖率主要是由于两个原因:首先,当有大量UI元素可供选择时,Humanoid能够识别关键UI元素并确定其优先级。其次,Humanoid有更高的机会执行一系列有意义的操作,这可以将应用程序推向未开发的核心功能。
图8显示了渐进式覆盖范围w.r.t。每个测试工具发送的输入事件数。请注意,我们没有将Sapienz包含在渐进式覆盖数据中,因为它发送的事件太快,我们无法将其放慢速度,因为它是近源的。在最初的几个步骤中,所有测试工具的行覆盖率迅速增加,因为应用程序刚刚启动,所有UI状态都是新的。 PUMA在前10个步骤中实现了最高覆盖率,因为它有一个在开始时重新启动应用程序的策略,这导致在许多应用程序中覆盖资源回收代码。Humanoid在大约20个事件后开始领先。那是因为那时已经涵盖了易于访问的代码,其他状态隐藏在其他测试工具难以产生的特定交互之后。
在第600个事件点,除了Monkey之外,大多数测试工具的线路覆盖率几乎已经收敛。这是因为Monkey的随机策略产生了大量无效和重复的输入事件,当我们计算事件数量时,这对于覆盖率改善没有帮助。但是,Monkey能够在相同的时间内生成更多的事件。其覆盖率将在第600步后继续增加,并在测试结束时达到约39%(相同的一小时测试持续时间)。
2)市场应用程序的活动覆盖率:与开源应用程序相比,市场应用程序通常具有不同且更复杂的功能和UI结构。因此,我们进一步对市场应用程序进行了实验,以确定Humanoid是否仍然更有效。
由测试工具和渐进覆盖实现的最终活动覆盖分别如图9和图10所示。与开源应用类似,Humanoid与其他工具相比也实现了最高覆盖率(24.1%)。由于市场应用程序的复杂性,一些应用程序的覆盖范围在测试结束时没有收敛。但是,我们相信Humanoid即使在更长的测试时间内也能保持优势。 (由于与上述相同的原因,请注意这两个数字中Monkey的覆盖范围的差异。)
V.限制和未来工作
更多输入类型。有些类型的输入,例如系统广播,传感器事件等,本文未考虑这些类型。这是Humanoid的限制,因为这些输入很难从人类交互中收集,并且在我们的交互模型中也难以表示。但是,目前这不是一个大问题,因为大多数应用程序可以在没有这些操作的情况下进行良好测试Humanoid也不会在发送文本输入操作时预测文本,通过扩展模型以支持文本预测或集成其他文本输入生成技术,可以在将来修复文本输入操作[40]。
覆盖范围进一步改善。虽然Humanoid已经能够从现有的测试工具中显着改善覆盖范围,但测试覆盖率仍然相对较低(比完美覆盖更差)。特别是,某些应用的覆盖率低于10%。这是因为许多应用程序需要特定的输入,例如电子邮件和密码,甚至无法自动生成。一种可能的解决方案是设计更好的半自动化测试方法,其中人类测试人员可以用最少的努力为自动工具提供必要的指导。
利用文本信息。在学习人类交互模式时,我们使用UI框架来表示模型中的每个UI状态,而不使用每个UI元素中的文本。文本信息对于人类使用该应用程序非常重要。我们相信,如果可以在交互模型中正确地表示和学习文本信息,则可以进一步提高Humanoid的性能。
学习非人类互动的痕迹。我们的方法在很大程度上依赖于人工交互轨迹,如果我们想要从更大的数据集中学习更多交互模式,这些轨迹可能难以扩展。由于模型实际从人类交互中学到的是每个UI中动作的重要性,因此只要可以分析动作的重要性,就可以直接训练机器生成的轨迹。
VI.结束语
本文介绍Humanoid,一种用于Android应用程序的新GUI测试输入生成器,能够通过深度学习生成类似人类的测试输入。 Humanoid采用深度神经网络模型来了解最终用户更可能与哪些UI元素进行交互以及如何与大量用户生成的交互跟踪进行交互。在学习模型的指导下,Humanoid能够准确预测与Android应用程序的真人交互。根据对大量开源应用程序和流行的商业应用程序的实验,Humanoid能够比六种最先进的测试工具实现更高的测试覆盖率和更快的速度