CN108829389A - 基于Appium的安卓应用自动化触发执行方法 - Google Patents
基于Appium的安卓应用自动化触发执行方法 Download PDFInfo
- Publication number
- CN108829389A CN108829389A CN201810271904.6A CN201810271904A CN108829389A CN 108829389 A CN108829389 A CN 108829389A CN 201810271904 A CN201810271904 A CN 201810271904A CN 108829389 A CN108829389 A CN 108829389A
- Authority
- CN
- China
- Prior art keywords
- event
- control
- gui
- appium
- activity component
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
- G06F8/38—Creation or generation of source code for implementing user interfaces
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/451—Execution arrangements for user interfaces
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Human Computer Interaction (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Debugging And Monitoring (AREA)
Abstract
本发明公开了一种基于Appium的安卓应用自动化触发执行方法,包括获取待执行安卓应用程序的全部Activity组件名称并生成启动参数文件并启动执行;获取待执行安卓应用的GUI信息及控件元素的信息并生成唯一标识;生成待执行应用的模拟操作事件并压栈存储;执行模拟操作事件;输出遍历结果。本发明本发明方法能够自动对安卓应用进行自动化触发执行,而且算法科学可靠,Activity组件的覆盖率极高。
Description
技术领域
本发明具体涉及一种基于Appium的安卓应用自动化触发执行方法。
背景技术
随着移动互联网向交通、支付、教育、医疗等诸多领域的渗透,搭载安卓(Android)***的智能移动终端的普及,Andorid应用在生活中起到越来越重要的作用。然而,Android应用良莠不齐,有许多质量偏低甚至携带恶意行为的 Android应用存在。
如果需要对携带恶意行为的Android应用进行鉴别,运行安卓应用并根据该安卓应用的具体行为特征进行鉴别是较为可靠的手段之一。但是,如果进行人工鉴别,则需要人工首先下载并安装该安卓应用,然后人工测试该安卓应用的所有动作并进行鉴别。但是,人工检测不仅费时费力,而且极易造成漏检等行为。
为了更好的对安卓应用进行测试,近年来很多学者针对Android应用测试进行了大量研究工作,而Android应用自动化触发执行方法的研究就是其中的一个重要方向。目前的Android应用自动化触发执行方法仅针对简单的原生控件进行单个控件的自动触发,如按钮控件Button、文本控件TextView、图片控件 ImageView等,并没有考虑其他控件的自动化触发执行及控件之间的关联关系,如混合应用所用到的网页视图控件WebView中可触发的非Android原生控件、列表控件ListView的每个Item及其内部控件都是可触发执行的,编辑控件 EditText输入的测试数据是与其他关联控件的语义有关联的等;另外,由于待执行应用中Activity组件关系图的是森林,单次图形用户界面(GUI)控件触发并不能覆盖所有Activity组件,造成Activity组件覆盖率低的问题。
发明内容
本发明的目的在于提供一种能够自动对安卓应用进行自动化触发执行的基于Appium的安卓应用自动化触发执行方法。
本发明提供的这种基于Appium的安卓应用自动化触发执行方法,包括如下步骤:
S1.获取待执行Android应用程序的全部Activity组件名称并生成启动参数文件,将待执行Android应用程序在Appium框架下自动启动执行;
S2.获取待执行Android应用的GUI信息及控件元素的信息,并生成GUI 唯一标识;
S3.动态生成待执行应用的模拟操作事件,并进行压栈存储;
S4.在Appium框架下按照深度遍历算法依次执行步骤S3得到的模拟操作事件,从而对待执行应用进行自动触发测试;
S5.输出遍历结果,从而完成安卓应用的自动化触发执行。
步骤S1所述的获取全部Activity组件名称、生成启动参数文件并自动启动执行Android应用程序,具体包括如下步骤:
A.获取待执行应用内含有的Activity组件,存入自定义的ActivityList数据结构中;
B.配置应用启动与动态执行过程中需要的信息,并启动安卓应用自动执行。
步骤A所述的获取待执行应用内含有的Activity组件存入自定义的ActivityList数据结构中,具体为解压待执行应用的Android安装包(APK),获得其中的AndroidManifest.xml文件,逆向处理该文件,分析获得应用内部包含的全部Activity组件名称,存入到自定义的ActivityList数据结构中,用于比较和建立Activity组件的触发路径。
步骤B所述的配置应用启动与动态执行过程中需要的信息并启动安卓应用自动执行,具体为利用Appium获取待执行应用的包名,把启动进入图形界面所在的Activity组件名称和应用主界面所在的Activity组件名称写入启动参数文件 data.properties中;将存在的编辑控件EditText提示信息和其输入值,以键值对的形式写入EditContent.txt中;最后根据启动参数文件和开源工具Appium的 driver.startActivity()方法启动待执行的安卓应用。
步骤S2所述的获取待执行Android应用的GUI信息及控件元素的信息并生成GUI唯一标识,具体包括如下步骤:
a.获取当前GUI下控件元素信息和GUI所在的Activity组件名称;
b.生成当前GUI的唯一标识并存储。
步骤a所述的获取当前GUI下控件元素信息和GUI所在的Activity组件名称,具体为通过开源工具Appium获取当前GUI下,包括Android原生控件和网页视图控件WebView中所包含的非Android原生控件在内的,所有可见控件元素的信息,将当前GUI下的布局信息以xml格式的字符串返回,采用树形结构描述控件之间的关系以及每个控件的属性,最后利用安卓调试桥工具(ADB)获得当前GUI所在的Activity组件名。
步骤S3所述的动态生成待执行应用的模拟操作事件并进行压栈存储,具体包括如下步骤;
(1)对编辑控件EditText生成模拟操作事件Event;
(2)对列表控件ListView生成模拟操作事件Event;
(3)对剩余的其他控件生成模拟操作事件Event。
步骤(1)所述的对编辑控件EditText生成模拟操作事件Event,具体包括如下步骤:
A:生成执行输入操作的模拟操作事件Event;
B:生成执行其他操作的模拟操作事件Event;
步骤A所述的生成执行输入操作的模拟操作事件Event具体为首先获取编辑控件EditText的输入提示信息,当编辑控件EditText的text属性值或content-desc属性值不为空时,则以此作为编辑控件EditText的输入提示信息,否则,根据编辑控件EditText坐标属性bounds寻找当前GUI下,坐标中心点位于编辑控件EditText左侧且与之距离最近的文本控件TextView,作为与编辑控件EditText存在语义关联的控件,获得其不为空的text属性值或content-desc属性值作为编辑控件EditText的输入提示信息;然后根据输入提示信息匹配 EditContent.txt中写入的键值对,如果匹配成功,则以匹配到的值作为编辑控件EditText的测试数据,生成执行输入操作的模拟操作事件Event,否则分析输入提示信息,产生要求格式的随机输入字符串作为编辑控件EditText的测试数据,生成执行输入操作的模拟操作事件Event,最后将生成的Event压入EventStack 栈中存储。
步骤B所述的生成执行其他操作的模拟操作事件Event具体为判断编辑控件EditText的clickable属性、long-clickable属性和scrollable属性的值,从而生成执行相应操作的模拟操作事件Event,最后将生成的Event依次压入EventStack 栈中存储。
步骤(2)所述的对列表控件ListView生成模拟操作事件Event,具体包括如下步骤:
a:对子项目Item生成模拟操作事件Event;
b:对子项目Item中包含的控件生成模拟操作事件Event。
步骤a所述对子项目Item生成模拟操作事件Event具体为判断列表控件 ListView的clickable属性和long-clickable属性的值从而对其包含的每个子项目 Item生成执行相应操作的模拟操作事件Event,在Event的bounds属性中存储 Item所处位置,与Item的idenValue属性一起唯一确定Item,最后将生成的Event 依次压入EventStack栈中存储。
步骤b所述对子项目Item中包含的控件生成模拟操作事件Event具体为判断Item中内部控件的clickable属性、long-clickable属性生成相应的操作事件 Event,在Event的bounds属性中存储Item所处位置,与内部控件的idenValue 属性一起唯一确定Item的内部控件,最后将生成的Event依次压入EventStack 栈中存储。
步骤(3)所述的对剩余的其他控件生成模拟操作事件Event,具体为遍历获得的xml格式的字符串,并对剩余的控件判断其clickable属性值、long-clickable 属性值和scrollable属性值,最后根据属性值生成对应的Event并依次压入 EventStack栈中存储。
步骤S4所述的在Appium框架下按照深度遍历算法依次执行步骤S3得到的模拟操作事件从而对待执行应用进行自动触发测试,具体包括如下步骤:
1)确定TraversalStack栈顶所指向的GUI是否完成其内部控件的遍历;
2)前往模拟操作事件Event正确的执行页面;
3)执行模拟操作事件Event;
4)继续遍历待执行应用中未被测试的Activity组件,直到遍历结束。
步骤1)所述的确定TraversalStack栈顶所指向的GUI是否完成其内部控件的遍历,具体为提取TraversalStack栈顶的UINodeName值,与EventStack栈顶 Event中的UINodeName属性值进行比较,从而判定其内部控件的遍历是否完成。
步骤2)所述的前往模拟操作事件Event正确的执行页面,具体为首先判断EventStack栈顶Event的UINodeName属性值是否与当前GUI的UINodeName 值一致;然后寻找一条从当前GUI到达正确执行页面即目标GUI的最短路径,最后根据该最短路径上需执行的模拟操作事件序列依次执行模拟操作事件直到到达目标GUI。
步骤3)所述的执行模拟操作事件Event,具体为依次出栈EventStack中模拟操作事件Event,利用Appium的方法,定位控件并执行,执行后更新 GUITransGraph,直至不存在待执行的模拟操作事件为止。
步骤4)所述的继续遍历待执行应用中未被测试的Activity组件,具体为在TraversalStack中GUI的相关模拟操作事件全部被执行完毕,完成对Activity组件森林中以主页面所在Activity组件作为根节点的树的深度遍历之后,判断待执行应用是否仍有Activity组件未被测试并依次利用Appium工具以之作为主页面所在Activity组件启动应用,重复步骤S2~S4对执行未被测试的Activity组件再次进行深度遍历,直至不存在未被测试的Activity组件为止。
步骤S5所述的输出遍历结果,具体为将待执行应用的Activity总数、应用 GUI总数,基于Appium的Android应用自动化触发执行方法遍历到的Activity 数量、Activity覆盖率及GUI数量写入相关Result.txt文件,生成测试报告、GUI 界面转换图和Activity组件转换图。
本发明提供的这种基于Appium的安卓应用自动化触发执行方法,通过建立待执行应用的图形界面GUI控件元素与Activity组件之间的对应关系,生成GUI 唯一标识,并利用开源Appium的getPageSource方法捕获包括Android原生控件和网页视图控件WebView中所包含的非Android原生控件在内的所有可见控件信息生成模拟操作事件,依据改进的深度遍历算法对待执行应用进行触发,使待执行应用中的Activity组件在GUI控件元素的触发下按路径得以测试,并最终形成一个完整且能够自动化运行的***,因此本发明方法能够对安卓应用进行自动化触发执行,而且算法科学可靠,Activity组件的覆盖率极高。
附图说明
图1为本发明方法的方法流程图。
图2为本发明方法在第一实施例中的GUI唯一标识UINodeName命名规则示意图。
图3为本发明方法在第一实施例中的对AndroidManifest.xml逆向所得AndroidManifest.txt部分内容示意图。
图4为本发明方法在第一实施例中的包名为com.guokr.android的应用的某页面示意图。
图5为本发明方法在第一实施例中的包名为com.guokr.android的应用的某页面输入控件执行完模拟操作事件后的页面示意图。
图6为本发明方法在第一实施例中在对包名为com.guokr.android的应用测试所得页面转换图部分内容示意图。
图7为本发明方法在第一实施例中对包名为com.guokr.android的应用测试所得Activity组件转换图部分内容示意图。
具体实施方式
如图1所示为本发明方法的方法流程图:本发明提供的这种基于Appium的安卓应用自动化触发执行方法,包括如下步骤:
S1.获取待执行Android应用程序的全部Activity组件名称并生成启动参数文件,将待执行Android应用程序在Appium框架下自动启动执行;具体包括如下步骤:
A.获取待执行应用内含有的Activity组件,存入自定义的ActivityList数据结构中;具体为解压待执行应用的Android安装包(APK),获得其中的 AndroidManifest.xml文件,逆向处理该文件,分析获得应用内部包含的全部 Activity组件名称,存入到自定义的ActivityList数据结构中,用于比较和建立 Activity组件的触发路径;
B.配置应用启动与动态执行过程中需要的信息,并启动安卓应用自动执行;具体为利用Appium获取待执行应用的包名,把启动进入图形界面所在的 Activity组件名称和应用主界面所在的Activity组件名称写入启动参数文件 data.properties中(data.properties结构如表1所示);将存在的编辑控件EditText 提示信息和其输入值,以键值对的形式写入EditContent.txt中;最后根据启动参数文件和开源工具Appium的driver.startActivity()方法启动待执行的安卓应用;
表1 data.properties结构示意表
S2.获取待执行Android应用的GUI信息及控件元素的信息,并生成GUI 唯一标识;具体包括如下步骤:
a.获取当前GUI下控件元素信息和GUI所在的Activity组件名称;具体为通过开源工具Appium获取当前GUI下,包括Android原生控件和网页视图控件 WebView中所包含的非Android原生控件在内的,所有可见控件元素信息,将当前GUI下的布局信息以xml格式的字符串返回,采用树形结构描述控件之间的关系以及每个控件的属性(其说明如表2所示),最后利用安卓调试桥工具 (ADB)获得当前GUI所在的Activity组件名;
表2控件属性说明表
属性 | 说明 |
index | 控件在父节点中的索引 |
text | 控件的text属性 |
resource-id | 控件的id |
class | 控件的类名 |
package | 控件所属应用包名 |
content-desc | 控件的备注属性 |
checkable | 控件可否被选择开关 |
checked | 控件是否被选择开 |
clickable | 控件是否响应点击 |
enabled | 控件是否可用 |
focusable | 控件可否获得焦点 |
focused | 控件是否获得焦点 |
scrollable | 控件是否响应滑动 |
Long-clickable | 控件是否响应长按 |
password | 是否以”.”显示文本 |
selected | 控件是否被选中 |
b.生成当前GUI的唯一标识并存储;
GUI唯一标识的命名规则的定义过程如图2所示,ActivityName为GUI所处的Activity组件名,MD5str为GUI内所有控件的resource-id属性值连接并进行一次MD5加密后得到的字符串。将ActivityName与得到的MD5str连接得到当前GUI的唯一标识UINodeName;
将UINodeName存入到自定义的TraversalStack数据结构中,同时更新自定义的GUITransGraph数据结构。TraversalStack中存储的是遍历到达但尚未完成内部控件遍历的GUI;GUITransGraph是自定义的图结构,节点为GUI,边为引起GUI发生转换的模拟操作事件Event,记录了遍历过程中发现的GUI转换关系;
S3.动态生成待执行应用的模拟操作事件,并进行压栈存储;根据GUI所在Activity组件名及其控件元素的信息,对控件生成模拟操作事件Event,存入到自定义的EventStack堆栈中。EventStack中存储的是各个GUI中待执行的模拟操作事件Event,Event结构如表3所示;
表3 Event结构示意表
具体为包括如下步骤;
(1)对编辑控件EditText生成模拟操作事件Event;
编辑控件EditText是根据输入数据进行触发的,因此当获得编辑控件 EditText时,需要动态生成测试数据,并根据测试数据产生模拟操作事件;
首先,获取编辑控件EditText的输入提示信息,当编辑控件EditText的text 属性值或content-desc属性值不为空时,则以此作为编辑控件EditText的输入提示信息,否则根据编辑控件EditText坐标属性bounds寻找当前GUI下,坐标中心点位于编辑控件EditText左侧且与之距离最近的文本控件TextView,作为与编辑控件EditText存在语义关联的控件,获得其不为空的text属性值或 content-desc属性值作为编辑控件EditText的输入提示信息;
其次,根据输入提示信息匹配EditContent.txt中写入的键值对,如果匹配成功,则以匹配到的值作为编辑控件EditText的测试数据,生成执行输入操作的模拟操作事件Event,否则分析输入提示信息,产生要求格式的随机输入字符串作为编辑控件EditText的测试数据,生成执行输入操作的模拟操作事件Event,最后将生成的Event压入EventStack栈中存储;
最后,分别判断编辑控件EditText的clickable属性、long-clickable属性和scrollable属性的值是否为“true”(真),若为真,则分别生成对应的点击、长按、滑动操作事件Event并依次压入EventStack栈中,否则,不生成对应操作事件;
(2)对列表控件ListView生成模拟操作事件Event;
首先,判断列表控件ListView的clickable属性和long-clickable属性的值是否需要对其包含的每个子项目Item生成执行点击操作或长按操作的模拟操作事件Event,在Event的bounds属性中存储Item所处位置,与Item的idenValue 属性一起唯一确定Item,并将生成的Event依次压入EventStack栈中存储;
接着,根据Item中内部控件的clickable属性、long-clickable属性判断是否需要对Item中存在的控件生成相应的点击操作或长按操作事件Event,并在 Event的bounds属性中存储Item所处位置,与内部控件的idenValue属性一起唯一确定Item的内部控件,最后将生成的Event依次压入EventStack栈中存储;
(3)对剩余的其他控件生成模拟操作事件Event;
遍历获得的xml格式的字符串,对剩余的其他控件,判断其clickable属性值、long-clickable属性值和scrollable属性值,根据属性值生成对应的Event,压入EventStack栈中存储;
S4.在Appium框架下按照改进的深度遍历算法依次执行步骤S3得到的模拟操作事件,从而对待执行应用进行自动触发测试;具体包括如下步骤:
1)确定TraversalStack栈顶所指向的GUI是否完成其内部控件的遍历;
提取TraversalStack栈顶的UINodeName值,与EventStack栈顶Event中的UINodeName属性值进行比较,如不一致,则确定为TraversalStack栈顶所指向的GUI内部控件遍历完成,该UINodeName出栈,存入完成队列FinishList中;
2)前往模拟操作事件Event正确的执行页面;
为了保证模拟操作事件Event在正确的页面执行,首先判断EventStack栈顶Event的UINodeName属性值是否与当前GUI的UINodeName值一致:如不一致,则在GUITransGraph中寻找从当前GUI到达正确执行页面即目标GUI的最短路径,当不存在路径时,利用表4中所示的Appium提供的方法,模拟点击返回键的操作,继续在返回的GUI中寻找,直到找到一条最短路径为止。依次执行该最短路径上需执行的模拟操作事件序列,直到到达目标GUI;
表4 Appium提供的方法示意表
方法名 | 作用 |
driver.startActivity | 打开指定的应用的指定的Activity |
driver.pressKeyCode | 模拟点击实体按键 |
TouchAction(driver).longPress().perform() | 对控件模拟长按操作 |
webElement.click() | 对控件模拟点击操作 |
webElement.sendKeys() | 对控件模拟输入操作 |
driver.swipe() | 对控件模拟滑动操作 |
findElement(By.name()) | 利用text属性或content-desc属性定位控件 |
findElement(By.id()) | 利用resource-id属性定位控件 |
如在执行序列当中某个Event后,并未发生预期的GUI转换,即到达GUI 与该Event的toUINodeName属性值不一致,则修改Event的toUINodeName属性值为到达的GUI,并更新GUITransGraph;同时认定无法前往目标GUI,将 EventStack与TraversalStack中目标GUI相关的元素出栈,并将此目标GUI加入已完成遍历的FinishList中,避免重复的遍历;
3)执行模拟操作事件Event;
依次出栈EventStack中模拟操作事件Event,利用开源Appium的方法(如表4所示),定位控件并执行,执行后更新GUITransGraph,若进入了未曾到达的页面,则将该GUI的UINodeName值压入TraversalStack栈中存储,对该GUI 中的控件生成Event压入Eventstack栈中存储。重复步骤1)~3),直到TraversalStack中GUI的相关模拟操作事件全部被执行完毕,不存在待执行的模拟操作事件为止;
4)继续遍历待执行应用中未被测试的Activity组件,直到遍历结束;
由于待执行应用中Activity组件关系图是森林,单以主页面所在Activity组件作为出发点进行的深度优先遍历并不能覆盖所有Activity组件,在 TraversalStack中GUI的相关模拟操作事件全部被执行完毕,完成对Activity组件森林中以主页面所在Activity组件作为根节点的树的遍历之后,判断待执行应用是否仍有Activity组件未被测试。若有未被测试Activity组件,则依次利用 Appium工具以之作为主页面所在Activity组件启动应用,重复步骤S2~S4对执行未被测试的Activity组件再次进行深度优先遍历,直到不存在未被测试的 Activity组件为止,遍历完成;
S5.输出遍历结果,从而完成安卓应用的自动化触发执行;将待执行应用的Activity总数、应用GUI总数,基于Appium的Android应用自动化触发执行方法遍历到的Activity数量(AR)、Activity覆盖率(AC)及GUI数量写入相关 Result.txt文件,生成测试报告、GUI界面转换图和Activity组件转换图。
以下结合具体实施例对本发明方法进行进一步说明:
实施例1:
步骤1:获取待执行Android应用程序的全部Activity组件名称,生成启动参数文件,使待执行Android应用程序在Appium框架下自动启动执行;
步骤1.1:获取待执行应用内含有的Activity组件,存入到自定义的ActivityList数据结构中;
AXMLPrinter2是一款android安卓xml文件反编译解密工具,可以将android 安卓编译过的二进制xml文件反编译明文输出保存。解压待执行应用的Android 安装包(APK),获得其中的AndroidManifest.xml文件,利用AXMLPrinter2.jar 对AndroidManifest.xml进行逆向处理生成AndroidManifest.txt,如图3所示,读取并分析AndroidManifest.txt,获得应用内部包含的全部Activity组件名称,存入到自定义的ActivityList数据结构中。
步骤1.2:配置应用启动与动态执行过程中需要的信息,并启动应用;
利用Appium获取待执行应用的包名,应用启动进入图形界面所在的 Activity组件名称和应用主界面所在的Activity组件名称写入启动参数文件 data.properties中。将需要给出指定文本输入值的编辑控件EditText的提示信息和其输入值,以键值对的形式写入EditContent.txt中。利用Appium提供的 driver.startActivity()方法启动待执行应用。
表5测试com.guokr.android时配置的键值对示意表
键名 | 键值 |
手机号 | 15012345678 |
密码 | 12345678 |
验证码 | 1234 |
步骤2:获取待执行应用的GUI信息及控件元素的信息,生成GUI唯一标识;
步骤2.1:获取当前GUI下控件元素信息和GUI所在的Activity组件名;
通过开源Appium提供的getPageSource()方法获取当前GUI下包括Android 原生控件和网页视图控件WebView中所包含的非Android原生控件在内的所有可见控件元素信息,利用安卓调试桥工具(ADB)提供的“adb shell dumpsys activity top”命令,分析执行该命令的返回值获得当前GUI所在的Activity组件名。
步骤2.2:生成当前GUI的唯一标识并存储;
根据图2所示命名规则给GUI生成唯一标识UINodeName,将UINodeName 压栈,同时更新GUITransGraph,添加以UINodeName命名的节点。
步骤3:动态生成待执行应用的模拟操作事件Event,并压栈存储;
步骤3.1:对编辑控件EditText生成模拟操作事件Event;
遍历步骤2.1中getPageSource()方法返回的xml格式的字符串,首先获得所有class属性值为“android.widget.EditText”的编辑控件EditText,接下来去获取该EditText的输入提示信息。图4为包名为com.guokr.android的应用存在EditText 控件的一个页面,3个编辑控件text属性值分别为“手机号或果壳网账号邮箱”、“密码”、“验证码”,利用该属性作为输入提示信息去EditContent.txt匹配写入的键值对,得到的输入值分别为“15012345678”、“12345678”、“1234”。生成对应的输入模拟操作事件压栈,同时根据控件的clickable属性、long-clickable 属性、scrollable属性,生成对该控件执行点击、长按、滑动等操作的一个或多个Event压入EventStack中。
步骤3.2:对列表控件ListView生成模拟操作事件Event;
首先,根据列表控件ListView的clickable属性和long-clickable属性的值判断是否需要对其包含的每个子项目Item生成执行点击操作或长按操作的模拟操作事件Event,在Event的bounds属性中存储Item所处位置,与Item的idenValue 属性一起唯一确定Item,并将生成的Event依次压入EventStack栈中存储;
接着,根据Item中内部控件的clickable属性、long-clickable属性判断是否需要对Item中存在的控件生成相应的点击操作或长按操作事件Event,并在 Event的bounds属性中存储Item所处位置,与内部控件的idenValue属性一起唯一确定Item的内部控件,最后将生成的Event依次压入EventStack栈中存储;
步骤3.3:对剩余的其他控件生成模拟操作事件Event;
遍历步骤3.1中获得的xml格式的字符串,对剩余的其他控件,判断其 clickable属性值、long-clickable属性值和scrollable属性值,根据属性值生成对应的Event,压入EventStack栈中存储。
步骤4:在开源Appium框架下按照改进的深度遍历算法依次执行模拟操作事件Event,对待执行应用进行自动触发测试;
步骤4.1:确定TraversalStack栈顶所指向的GUI是否完成其内部控件的遍历。
判断TraversalStack栈顶GUI与EventStack栈顶Event的UINodeName属性值是否一致,如不一致,则认为该GUI内部控件遍历完成,出栈TraversalStack 栈顶,存入FinishList中。
步骤4.2:前往模拟操作事件Event正确的执行页面。
首先判断EventStack栈顶Event的UINodeName属性值是否与当前GUI的UINodeName值一致。如不一致,则在GUITransGraph中寻找从当前GUI到达正确执行页面即目标GUI的最短路径,当不存在路径时,利用Appium提供的 driver.pressKeyCode(KEYCODE_BACK)方法,模拟点击返回键的操作,继续在返回的GUI中寻找,直到找到一条最短路径为止。依次执行该最短路径上需执行的模拟操作事件序列,直到到达目标GUI。
如在执行序列当中某个Event后,并未发生预期的GUI转换,即到达GUI 与该Event的toUINodeName属性值不一致,则修改Event的toUINodeName属性值为到达的GUI,并更新GUITransGraph。同时认定无法前往目标GUI,将 EventStack与TraversalStack中目标GUI相关的元素出栈,并将此目标GUI加入已完成遍历的FinishList中,避免重复的遍历。
步骤4.3:执行模拟操作事件Event。
出栈EventStack中Event,根据其idenType属性值、idenValue属性值、action 属性值、bounds属性值利用Appium提供的方法(如表4所示),定位控件并执行Event,更新GUITransGraph,若进入了未曾到达的页面,则将该GUI的 UINodeName值压入TraversalStack栈中存储。重复步骤4.1、4.2、4.3,直到 TraversalStack中GUI的相关模拟操作事件全部被执行完毕,不存在待执行的模拟操作事件为止。图5表示的是该页面执行完编辑控件EditText对应Event后的情况。
步骤4.4:继续遍历待执行应用中未被测试的Activity组件,直到遍历结束。
图6为对包名为com.guokr.android的应用测试所得页面转换图 GUITransGraph部分内容,节点表示GUI,边表示引起GUI转换的模拟操作事件Event,其中红色的边表示模拟点击返回按钮的事件,图7为对包名为 com.guokr.android的应用测试所得Activity组件转换图部分内容,节点表示 Activity组件,边表示引起Activity组件转换的模拟操作事件Event,其中红色的边表示模拟点击返回按钮的事件,由图7可知应用com.guokr.android中Activity 组件关系图是森林,单以主页面所在Activity组件作为出发点进行的深度遍历并不能覆盖所有Activity组件,仍有未被测试Activity组件,则直接利用Appium 工具以之作为主页面所在Activity组件启动应用,重复步骤S2~S4对执行未被测试的Activity组件再次进行深度遍历,直到不存在未被测试的Activity组件为止,遍历完成。
步骤5:输出遍历结果。
步骤1中获得了待执行应用的全部Activity组件,根据遍历过程遍历到达的Activity组件和GUI,可得到应用总的Activity数量(AT),基于Appium的Android 应用自动化触发执行方法遍历到的Activity组件数量(AR),Activity组件覆盖率(AC),GUI数量,将这些信息写入Result.txt文件中生成测试报告,利用GraphViz 将GUITransGraph输出成如图6所示的图片文件,节点表示GUI,边表示引起 GUI的模拟操作事件Event,其中红色的边表示模拟点击返回按钮的事件;根据 GUI与Activity组件间的对应关系可得Activity组件转换图输出成如图7所示的图片文件,节点表示Activity组件,边表示引起Activity转换的模拟操作事件 Event,其中红色的边表示模拟点击返回按钮的事件。
实施例2:
本实施例说明上述方法在实际应用中的作用。对谷歌应用商店随机选取的 12个应用进行了测试,结果如表6所示。表中,第一列为应用程序类型;第二列为应用程序包名;第三列为应用程序APK大小;第四列为应用程序中包含的 Activity组件总数(AT);第五列为动态执行过程访问到的Activity组件总数(AR);第六列为动态执行过程中访问到的GUI总数(GUI),第七列为Activity组件覆盖率的百分比(AC);第八列为动态执行所需时间(Time),单位为分钟;第九列为应用程序名称。
从表6的测试结果可知,本方法可以通过自动触发所有GUI界面的控件操作,遍历到待执行应用程序中的大部分Activity组件。
根据表中AC可知,利用本方法对12个待执行应用程序进行测试,其Activity 组件覆盖率的平均值为89.29%,其中有8个待执行应用的Activity组件覆盖率为100%。由于开源Appium无法模拟复杂的手势操作,如滑动滑块到指定位置才执行的手势;且部分Activity组件的触发是跟多个控件的执行顺序有关系,另外,还有些Activity组件并不允许利用开源Appium的driver.startActivity方法对其进行启动,这使得部分待执行应用的Activity组件覆盖率达不到100%。由应用程序中包含的Activity组件总数和Activity组件覆盖率之间关系可知,随着 Activity组件数量增加,Activity组件覆盖率也降低,这是因为大多数情况下包含的Activity组件越多意味着应用功能越复杂,加大了自动化触发执行的难度。
表6基于Appium的Android应用自动化触发执行方法实验结果示意表
Claims (7)
1.一种基于Appium的安卓应用自动化触发执行方法,包括如下步骤:
S1.获取待执行Android应用程序的全部Activity组件名称并生成启动参数文件,将待执行Android应用程序在Appium框架下自动启动执行;
S2.获取待执行Android应用的GUI信息及控件元素的信息,并生成GUI唯一标识;
S3.动态生成待执行应用的模拟操作事件,并进行压栈存储;
S4.在Appium框架下按照深度遍历算法依次执行步骤S3得到的模拟操作事件,从而对待执行应用进行自动触发测试;
S5.输出遍历结果,从而完成安卓应用的自动化触发执行。
2.根据权利要求1所述的基于Appium的安卓应用自动化触发执行方法,其特征在于步骤S2所述的获取待执行Android应用的GUI信息及控件元素的信息并生成GUI唯一标识,具体包括如下步骤:
a.获取当前GUI下所有控件元素信息和GUI所在的Activity组件名称;
b.生成当前GUI的唯一标识并存储。
3.根据权利要求1所述的基于Appium的安卓应用自动化触发执行方法,其特征在于步骤S3所述的动态生成待执行应用的模拟操作事件并进行压栈存储,具体为包括如下步骤;
(1)对编辑控件EditText生成模拟操作事件Event;
(2)对列表控件ListView生成模拟操作事件Event;
(3)对除编辑控件和列表控件外的剩余控件生成模拟操作事件Event。
4.根据权利要求3所述的基于Appium的安卓应用自动化触发执行方法,其特征在于步骤(1)所述的对编辑控件EditText生成模拟操作事件Event,具体为首先,获取编辑控件EditText的输入提示信息,当编辑控件EditText的text属性值或content-desc属性值不为空时,则以此作为编辑控件EditText的输入提示信息,否则根据编辑控件EditText坐标属性bounds寻找当前GUI下,坐标中心点位于编辑控件EditText左侧且与之距离最近的文本控件TextView,作为与编辑控件EditText存在语义关联的控件,获得其不为空的text属性值或content-desc属性值作为编辑控件EditText的输入提示信息;其次,根据输入提示信息匹配EditContent.txt中写入的键值对,如果匹配成功,则以匹配到的值作为编辑控件EditText的测试数据,生成执行输入操作的模拟操作事件Event,否则分析输入提示信息,产生要求格式的随机输入字符串作为编辑控件EditText的测试数据,生成执行输入操作的模拟操作事件Event,最后将生成的Event压入EventStack栈中存储。
5.根据权利要求3所述的基于Appium的安卓应用自动化触发执行方法,其特征在于步骤(2)所述的对列表控件ListView生成模拟操作事件Event,具体为首先分别判断列表控件ListView的clickable属性和long-clickable属性的值,对其子项目Item生成相应的操作事件Event压入EventStack栈中存储;然后根据Item中内部控件的clickable属性、long-clickable属性对其生成相应的操作事件Event压入EventStack栈中存储。
6.根据权利要求1所述的基于Appium的安卓应用自动化触发执行方法,其特征在于步骤S4所述的在Appium框架下按照深度遍历算法依次执行步骤S3得到的模拟操作事件从而对待执行应用进行自动触发测试,具体包括如下步骤:
1)确定TraversalStack栈顶所指向的GUI是否完成其内部控件的遍历;
2)前往模拟操作事件Event正确的执行页面;
3)执行模拟操作事件Event;
4)继续遍历待执行应用中未被测试的Activity组件,直到遍历结束。
7.根据权利要求6所述的基于Appium的安卓应用自动化触发执行方法,其特征在于步骤4)所述的继续遍历待执行应用中未被测试的Activity组件,具体为在TraversalStack中GUI的相关模拟操作事件全部被执行完毕,完成对Activity组件森林中以主页面所在Activity组件作为根节点的树的深度遍历之后,判断待执行应用是否仍有Activity组件未被测试并依次利用Appium工具以之作为主页面所在Activity组件启动应用,重复权利要求1中所述步骤S2~S4对执行未被测试的Activity组件再次进行深度优先遍历,直至不存在未被测试的Activity组件为止。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810271904.6A CN108829389A (zh) | 2018-03-29 | 2018-03-29 | 基于Appium的安卓应用自动化触发执行方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810271904.6A CN108829389A (zh) | 2018-03-29 | 2018-03-29 | 基于Appium的安卓应用自动化触发执行方法 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN108829389A true CN108829389A (zh) | 2018-11-16 |
Family
ID=64155328
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201810271904.6A Pending CN108829389A (zh) | 2018-03-29 | 2018-03-29 | 基于Appium的安卓应用自动化触发执行方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN108829389A (zh) |
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110865851A (zh) * | 2019-11-18 | 2020-03-06 | 中国民航信息网络股份有限公司 | 一种Android应用数据自动采集方法及*** |
CN110990258A (zh) * | 2019-10-29 | 2020-04-10 | 贝壳技术有限公司 | 基于Android***的APP测试方法、装置、可读存储介质及处理器 |
CN111240957A (zh) * | 2019-11-27 | 2020-06-05 | 广东电网有限责任公司信息中心 | Android应用的Activity关系图生成方法 |
CN111427803A (zh) * | 2020-06-11 | 2020-07-17 | 平安国际智慧城市科技股份有限公司 | 自动化随机测试方法、装置、计算机设备及介质 |
CN112650669A (zh) * | 2020-12-04 | 2021-04-13 | 苏州黑云智能科技有限公司 | 基于区块链的appium自动化测试方法 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN106326104A (zh) * | 2015-07-08 | 2017-01-11 | 腾讯科技(深圳)有限公司 | 终端控件测试方法及装置 |
CN106776319A (zh) * | 2016-12-15 | 2017-05-31 | 广州酷狗计算机科技有限公司 | 自动测试方法及装置 |
CN107193733A (zh) * | 2017-05-12 | 2017-09-22 | 微梦创科网络科技(中国)有限公司 | 模拟Monkey测试的方法、装置和*** |
-
2018
- 2018-03-29 CN CN201810271904.6A patent/CN108829389A/zh active Pending
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN106326104A (zh) * | 2015-07-08 | 2017-01-11 | 腾讯科技(深圳)有限公司 | 终端控件测试方法及装置 |
CN106776319A (zh) * | 2016-12-15 | 2017-05-31 | 广州酷狗计算机科技有限公司 | 自动测试方法及装置 |
CN107193733A (zh) * | 2017-05-12 | 2017-09-22 | 微梦创科网络科技(中国)有限公司 | 模拟Monkey测试的方法、装置和*** |
Non-Patent Citations (1)
Title |
---|
张胜桥等: ""基于APK的Android应用程序GUI遍历自动化方法"", 《计算机应用》 * |
Cited By (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110990258A (zh) * | 2019-10-29 | 2020-04-10 | 贝壳技术有限公司 | 基于Android***的APP测试方法、装置、可读存储介质及处理器 |
CN110865851A (zh) * | 2019-11-18 | 2020-03-06 | 中国民航信息网络股份有限公司 | 一种Android应用数据自动采集方法及*** |
CN110865851B (zh) * | 2019-11-18 | 2023-12-01 | 中国民航信息网络股份有限公司 | 一种Android应用数据自动采集方法及*** |
CN111240957A (zh) * | 2019-11-27 | 2020-06-05 | 广东电网有限责任公司信息中心 | Android应用的Activity关系图生成方法 |
CN111240957B (zh) * | 2019-11-27 | 2023-09-15 | 广东电网有限责任公司信息中心 | Android应用的Activity关系图生成方法 |
CN111427803A (zh) * | 2020-06-11 | 2020-07-17 | 平安国际智慧城市科技股份有限公司 | 自动化随机测试方法、装置、计算机设备及介质 |
CN111427803B (zh) * | 2020-06-11 | 2020-10-20 | 平安国际智慧城市科技股份有限公司 | 自动化随机测试方法、装置、计算机设备及介质 |
CN112650669A (zh) * | 2020-12-04 | 2021-04-13 | 苏州黑云智能科技有限公司 | 基于区块链的appium自动化测试方法 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN108829389A (zh) | 基于Appium的安卓应用自动化触发执行方法 | |
White et al. | Improving random GUI testing with image-based widget detection | |
US9600401B1 (en) | Automated GUI testing | |
CN108681508B (zh) | 一种基于视觉识别的测试方法及终端 | |
CN105955889B (zh) | 一种图形界面自动化测试方法 | |
CN109409533B (zh) | 一种机器学习模型的生成方法、装置、设备及存储介质 | |
CN106294152B (zh) | 应用用户界面的遍历测试装置及方法 | |
US11042472B2 (en) | Authoring automated test suites using artificial intelligence | |
CN107102947B (zh) | Atm交易流程测试装置及方法 | |
US20080320462A1 (en) | Semi-automated update of application test scripts | |
US7895575B2 (en) | Apparatus and method for generating test driver | |
WO2020228283A1 (zh) | 特征提取方法、装置及计算机可读存储介质 | |
CN107301130A (zh) | 一种vr一体机测试工具及其方法 | |
CN107122295B (zh) | 测试用例脚本的生成方法和装置 | |
CN109726105A (zh) | 测试数据构造方法、装置、设备及存储介质 | |
CN112597065B (zh) | 页面测试方法和装置 | |
CN110114755A (zh) | 示例编程中的行为特征使用 | |
US20200327043A1 (en) | System and a method for automated script generation for application testing | |
CN110287696A (zh) | 一种反弹shell进程的检测方法、装置和设备 | |
CN108959067A (zh) | 搜索引擎的测试方法、装置及计算机可读存储介质 | |
US20090144625A1 (en) | Sequence detection and automation for complex portal environments | |
US20100221694A1 (en) | Adaptive electronic learning system and method | |
CN108446398A (zh) | 一种数据库的生成方法及装置 | |
CN108459949A (zh) | 一种测试方法及终端 | |
CN109918299A (zh) | 一种对比数据库结构差异的方法 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
RJ01 | Rejection of invention patent application after publication | ||
RJ01 | Rejection of invention patent application after publication |
Application publication date: 20181116 |