1、前言1第一章绪论21.1 研究背景以及意义21.2 框架概述31.3 本文主要工作以及创新点41.4 本文组织结构4第二章安卓UI测试技术52.1 安卓UI测试技术简介52.2 安卓UI测试的难点52.3 安卓UI测试的方法6人工测试62.3.1 自动化工具测试62.4 安卓UI测试的评价标准82.5 本章小结9第三章人机对战框架的需求分析与概要设计103.1 人机对战框架工程的整体概述103.2 系统需求分析11用例图113.2.1 用例描述11系统顺序图14324非功能性需求描述143.3 系统概要设计15类图153.3.1 开发视图163.4 本章小结18第四章人机对战框架的详细设计与具
2、体实现第四章人机对战框架的详细设计与具体实现19框架子模块概述194.1.1 Execution 模块2023安卓UI测试的方法安卓ui测试在现今主要有两种方式:人工编写代码测试与自动化工具测试。2.3.1 人工测试安卓UI测试的人工测试主要也可以分为两种方式:(1)直接编写测试代码现如今,安卓UI测试的代码编写都是基于框架编写的,而最为流行的安卓UI 测试框架,有 UIAutomator、Robotium 与 Appium。这三者分别使用不同的代码规范,测试者需要按照这些规范编写测试代码并运行, 就可以模拟出正常用户使用安卓应用的行为。(2)众包测试众包测试是一种比拟新型的测试方式,它会将待
3、测的安卓应用分发给数百人即 进行测试,这些人会分别使用他们自己能想到的所有方法来测试该应用,并填写测试 报告。相较于编写测试代码而言,这种方式并没有太好的复现性,但是由于用户数量 巨大,而且测试者和编码者不同,可以完全将自己看为程序的使用者来提出意见,因 此也能得到好的反响。2.3.2 自动化工具测试为了节约人力与物力,研究人员们意图开发出能够自动进行安卓UI测试的工具, 并取得了不错的进展。现如今的自动化工具,主要可以根据其测试策略分为三类:随 机探索策略、基于模型的探索策略与系统的探索策略。(1)随机探索策略随机探索策略顾名思义,即所有的操作都是随机的,自动化工具会根据自己的 随机策略为安
4、卓应用生成输入。并且,该策略几乎只能应用于UI测试。这种方法生 成测试用例的效率实际上并不高,因为随机性,经常会牛成重复的应用输入。同时, 由于安卓应用的层次性,即许多页面需要进行一定量的固定操作才能进入,随机探索 策略就难以进入这些页面了。但是,由于随机策略生成测试用例,即应用输入的效率 十分之高,该策略也常用来进行安卓应用的压力测试。比拟有名的随机探索策略自动化测试工具有Monkey与Dynodroid,前者是由安 卓SDK (Software Development Kit)自身提供的命令行工具,可以说是官方工具了, 正如其名,它会像猴子一样随机的进行动作来测试。后者那么是一个年代较为久
5、远的工 具,作为安卓自动化工具的开山鼻祖之一而常常被人提及。(2)基于模型的探索策略基于模型的探索策略,是从一些网络爬虫中得到的灵感,这种策略的自动化工 具,会获取每个页面中,可以点击或进行其他操作的控件,将他们放入栈或队列中, 接着按照顺序一个个进行处理。当然,也可以通过配置文件来说明不需要进行操作的 活动的名称来加快进程。这种方法的优点是可以将所有的UI都测试到,无论深度有 多深,这是随机策略无法到达的。但是同样的,基于模型的探索策略也有缺点,就是 在不改变核心算法的情况下,每一次的测试路径是一样的,如果针对一款刚刚完成的 安卓应用进行测试的话,每当遇到让程序崩溃的错误,就需要重头测试一遍
6、,较为消 耗时间。比拟有名的基于模型的探索策略自动化测试工具有AppCrawler与PUMA,前者 是国人编写的一款工具,通过配置文件的输入,可以做到自动辨识登录界面,从而做 到能够测试绝大局部应用。而后者那么是一款基于Monkey编写的框架,他可以用来接 入安卓应用从进行动态分析。(3)系统的探索策略有一局部安卓应用的行为,只有在提供特定的输入的时候才会显现出来。而之前 的两种方法显然无法做到这一点,因此,一些安卓测试工具使用了更复杂的技术,比 如符号执行或进化算法来对尚未覆盖的代码进行探索,这就是系统的探索策略。由于这一研究较为深奥,因此相关人员对于这局部工具也仍然只是处于研究中。 较为有
7、名的系统的探索策略的自动化测试工具有ACTEve, 一种符号测试的工具。1.1 UI测试工具的比照2015年,Shauvik Roy Choudhary等人对局部著名的安卓自动化UI测试工具进行 了一次比照实验口叫实验的结果令人惊讶,测试完安卓应用后,代码覆盖率最高的工 具,居然是随机探索策略的Monkey,平均覆盖率到达了近50%。但这个数据相较于 人工编写代码而言,是很低的,因为人工编写代码的覆盖率,几乎是能覆盖整个应用 的。不过,自动化测试工具也有他的优点,那就是速度快。他们到达代码覆盖率的时 间几乎都在5-10分钟内。而如果换成人类进行测试代码的编写,可能需要花上好几 个小时。2.4
8、安卓UI测试的评价标准安卓UI测试的结果评估指标很多,对于代码而言,有代码覆盖率、异常触发率、 变异杀死率等等。(1)代码覆盖率代码覆盖率应该是现如今最为常见的测试结果评估指标了,测试代码覆盖了整个 应用的多少,至少从数量上可以侧面反响这一次的测试是否全面。因为测试代码最主 要的目的就是通过输入来实现对程序功能以及代码的覆盖,来观察程序的反响以找到 程序的缺陷,从而才能对程序继续进行改进。代码覆盖率主要包括源代码的覆盖率与 中间代码的覆盖率,源代码覆盖率更为准确,但是大局部情况下,应用并不会开放源 代码,因此中间代码覆盖率的适用性会更强。(2)异常触发率异常触发率对于人工代码而言可能不是必须的
9、,因为一般触发了异常会导致程序 退出,接下来的代码就无法继续执行了,可是对于自动化工具而言,这是一个比拟重 要的指标。工具触发了异常,说明工具找到了应用程序的问题,侧面就能说明自动化 工具到达了目的,因此也是一个重要的测试结果评判标准。(3)变异杀死率他变异是一个比拟不常见的概念,在通用的情况下,变异是指,源代码的某一处逻 辑发生改变,导致程序整体功能也因此而改变的情况,一般是在开发人员手误写错了 代码的时候发生。比方将大于号错写成小于号,就会使得程序的输出与预计不符。在这种情况下,测试代码应当使用断言来对这些局部进行检测,断言是指,对某 一个输出或者某一个值做出一个固定的判断,如果程序执行导
10、致断言处时,该值与我 们设定好的固定值不同,那么直接执行停止并报错,以便于发现错误。目前的一些测试竞赛中,会加入故意注入变异的方式,来评判测试代码能否发现 这些变异。在安卓UI测试中,由于测试过程与单元测试完全不同,本文认为变异能否杀死, 取决于运行同样的代码时,在无变异的情况下能成功执行的测试代码,在变异后的应用下能够仍然执行成功,如果执行失败了,那么说明杀死了该变异,反之那么没有检查到 该变异。2.5 本章小结安卓UI测试相较于Java测试而言,还相对并不成熟。人工编写代码进行测试虽 然可以到达较高的代码覆盖率,但是相对而言耗时较长。而自动化测试工具虽然用时 很快,但是并不能够到达一个非常
11、高的代码覆盖率值。由于安卓本身的碎片化问题,测试这一过程就需要考虑到许多针对特定版本的情 况,这也就使得安卓测试比起其他测试而言更加复杂。况且,安卓框架也在不断进行更新,这也就意味着,如果不对测试代码,或自动 化测试工具进行持续不断的维护,就会产生引版本更新而无法使用的情况。本文认为, 现在的安卓UI测试仍然有可以开展的空间。对于人工测试,我们可以制作将人手动 点击的过程录制下来并转换成代码的工具。这种工具据本文所调查,已经有人正在研 究。而对于自动化测试工具,更加全面的考虑可能发生的问题,如对于登录页面,我 们可以提供输入,如果遇到了让程序崩溃的问题,我们也可以通过工具复现来解决等 等。总而
12、言之,安卓UI测试目前还并不完善,但是如果能结合上述所说的各种方式, 相信未来的安卓UI测试一定会变得简单而又高效。第三章人机对战框架的需求分析与概要设计本章通过UML绘图的方法,讲述了人机对战框架的需求分析与概要设计,经 由用例图、类图、时序图等内容,具体的描述了人机对战框架的设计思想与使用实 例。3.1人机对战框架工程的整体概述为了能够使得安卓应用测试结果得到一个标准化的评判,本文选择自己实现一个 框架来到达这样的效果。但是人机对战框架的功能不仅限于此,人机对战框架的功能 主要是为了慕测信息科技的主平台所用。慕测主平台主要分为教育版与企业 版,在教育版的安卓应用分项中,学生通过提交安卓应用
13、测试脚本来获取分数,而通 过人机对战框架,可以简化原本的流程。同时,该框架也用来进行人机对战比赛这一 活动。在2017年全国大学生测试大赛的安卓人机对战分项赛中,已经使用过该框架 的雏形,接着将对框架进行了不断的改进以增加新的功能。人机对战框架的具体实现由五个局部组成:源代码修改、接收待测应用与测试代 码并执行测试、反响测试中获得的数据、对数据进行分析并计算得分、将所有详细结 果以及得分输出。这五个局部会分别在第四章中进行详细说明。同时,据我所调查的,本文所介绍的人机对战框架,不仅是第一款用来进行人机 对战的框架,也是第一款意图于将安卓应用测试结果规范化的框架。并且,最重要的 一点是,框架的使
14、用方法十分简单,只需要提供规定好的输入并修改几句配置文件, 整个框架的流程就能一键完成了,也就是纯黑盒完成。本章中,先进行框架的需求分析与概要设计的介绍。3.2系统需求分析用例图用例描述对于上述用例图而言,我们可以做出以下用例描述表3.1用户使用人工脚本测试用例编号001编制时间2018/4/13前置条件用户环境下安装了 Appium框架并且进行了正确配置且模拟器或实机正确的连接上了电脑基本领件流描述用户更改框架中相关配置文件用户输入相应命令以开始测试系统进行测试,反响信息并分析信息计算分数系统返回分数与详细输出扩展事件流2a、用户提供了无效的命令2al、系统返回相应的错误提示后置条件无特殊要
15、求无用例说明用户使用人工脚本测试的流程表3.2用户使用人工脚本变异测试用例编号002编制时间2018/4/13前置条件用户环境下安装了 Appium框架并且进行了正确配置且模拟器 或实机正确的连接上了电脑基本领件流描述用户更改框架中相关配置文件用户输入相应命令以开始测试系统生成变异apk系统进行变异测试,反响信息并分析信息计算分数系统返回分数与详细输出扩展事件流2a、用户提供了无效的命令2al、系统返回相应的错误提示3a、用户提供的应用源码无法变异3al、系统停止执行,返回错误提示后置条件无特殊要求无用例说明用户使用人工脚本变异测试的流程表3.3用户为框架接入新的工具用例编号003编制时间20
16、18/4/13前置条件无基本领件流描述用户对想要接入的工具进行修改用户将相应的工具使用代码加入框架代码中扩展事件流无后置条件无特殊要求无用例说明用户为人机对战框架添加新的自动化测试工具表3.4用户使用自动化测试工具进行测试用例编号002编制时间2018/4/13前置条件用户环境下安装了相应工具所需的环境并且进行了正确配置且 模拟器或实机正确的连接上了电脑。基本领件流描述用户更改框架中相关配置文件用户输入相应命令以开始测试系统进行测试,反响信息并分析信息计算分数系统返回分数与详细输出扩展事件流2a、用户提供了无效的命令2al、系统返回相应的错误提示。2b、用户选择的工具不存在2bl、系统停止执行
17、,返回错误提示。后置条件无特殊要求无用例说明用户使用自动化脚本进行测试的流程323系统顺序图由于系统本身与用户之间的交互较少,主要在于系统本身的运行上进行了相当多 的运算,因此仅附上用例01的顺序图,其他用例与此基本相似。用户使用人工脚本浏试底序图图3.2用例01的顺序图描述非功能性需求描述本节描述了框架所需要的环境与非功能性需求。人机对战框架的非功能性需求如表3.5所示,要求系统具有良好的健壮性、兼容 性与易用性。表3.5非功能性需求表名称内容非功能性需求类别系统兼容性框架在Windows或Linux系统下应当都可以正常使用兼容性使用简易型所有操作都应当可以一键完成易用性低出错率系统本身的逻
18、辑正确,不应当在用户输入正确指令的情况下出错健壮性用户交互良好在系统运行时,应当有信息被不断地输 出,防止使用者误解为系统无响应易用性人机对战框架所需要的环境如表3.6所示。表3.6系统所需环境环境耍求具体内容人工脚本测试要求运行系统内必须安装Appium人工脚本变异测试要求运行系统内必须安装Appium,且拥有可运 行的MDroid+工具自动化工具测试要求运行系统内必须可以正常运行相应的自动化测试工具3.3系统概要设计类图人机对战框架的类从用例描述入手,可以找到候选类:自动化测试工具接口、自 动化工具、系统、进行测试、返回结果、计算得分、执行人工脚本变异测试。它们之 间的关系如图3.3所小:
19、1.1.2 Interface 模块20Mutant Manage 模块214.2 Execution子模块的详细设计与具体实现21插桩224.2.1 执行测试28反响数据304.2.2 分析数据并计算得分31输出得分与详细报告324.3 Interface模块的的详细设计与具体实现324.4 Mutant Manager模块的详细设计与具体实现344.5 本章小结36第五章框架的评分标准与功能测试375.1 框架评分标准375.2 框架功能测试38应用选择385.2.1 人工脚本测试38人工脚本变异测试395.2.2 自动化工具测试415.3 本章小结42第六章总结与展望436.1 本文总结
20、436.2 后续工作展望43参考文献45致 谢错误!未定义书签。进行测试(ManualTest)-测试代码位置:String-输出彳: String+ 开启 AppiumServer(String): String计算得分(GetPoint)-场出位置:String+ getHTMLPointQ: double+ getExceptionPoint(String): double返回结果(Feedback)-应用源码位置:String+获取插桩信息0自动化测试工具接口系统0-1 : 0.*+运行0-String- iSiD: String- appPackage : String- 而用E詈:
21、String- log线程:Process- 输出位置:String自动化测试工具-运行脚本位置:String-工具位置:String变异测试(Mutant Ex ecution)+ 创业异(String) + 创立 APK(String) +变异执行,Stimg) + 结果图3.3类图开发视图图3.4描述了人机对战框架开发中的静态视图,即包图。使得框架的构架能够清晰的被使用者理解。图3.4开发视图3.4本章小结本章分为三个局部,分别是人机对战框架工程的整体概述、人机对战框架的需求 分析局部和人机对战框架的系统概要设计局部。第一局部描述了人机对战框架的编写 目的,使用场景以及使用案例。第二局部
22、从用例图、用例描述、系统顺序图以及非功 能性需求的角度讲述了人机对战框架的需求分析内容。第三局部那么从整体上描述了人 机对战框架的结构设计,通过类图和包图展现了框架的实现方式。第四章人机对战框架的详细设计与具体实现本章通过介绍具体代码的方法,讲述了人机对战框架的详细设计与具体实现, 通过对插桩、执行测试、计算数据等核心代码进行讲解来说明人机对战框架的具体 运行过程。4框架子模块概述人机对战框架的流程几乎是线性的,图4.1展示了人机对战框架的工作流程,编 写时将框架分为三个大模块,分别是:Execution Interface和Mutant Manage.每一个 模块都分工管理框架的不同局部。接
23、下来本文会先简略的介绍每个模块,而关于每个 模块的详细设计与实现会在4.2节中进行具体描述。计算得分图4.1人机对战框架流程图Execution 模块Execution模块顾名思义,作用是执行人工脚本测试与自动化工具测试,获取返 回的覆盖率、异常触发率等数据并计算得分与给出最终结果。同时,该模块也是人机 对战框架的主要流程。模块会先接收用户输入的信息,接着使用函数:public void MnualTest.run() 方法来开始人工脚本测试,或使用public void AutomatorTools.start()方法来开始自动化工具测试,这两个方法会自动翻开所需的后台软件,接着在连接的 手
24、机上开始测试,直到测试完毕或者测试因为某些情况而中断时结束。当测试完毕后, 框架会调用函数:public void Feedback.getEC()来获得测试的覆盖率数据与异常触发情况,并直接生成到用户先前输入的输出文件夹 中,因此没有返回值。接着使用函数:public void CulculatePoint.generate()方法,从之前获得的覆盖率数据生成清晰可见的HTML文件与XML文件,其中包含 了详细的代码覆盖率信息。最后使用GetPoint类中的函数:public double GetPoint.getHTMLPoint()public double GetPoint.getEx
25、ceptionPoint()两个方法来分别获取覆盖率分数与异常触发分数,就可以作为最终得分的依据了。4.1.1 Interface 模块Interface模块主要与自动化测试工具相关,由于自动化工具的数量十分的多,我 们不可能做到一一去为它们进行配置来使其可用,因此,编写了两个抽象类作为接口: AutomatorToolsDriver作为自动化工具的管理器,AutomatorToolsTest作为自动化工具 的生成器。为了实现同时在多台手机上进行测试,AutomatorToolsTest继承了 Thread 类,并且包含一个抽象函数:public abstract void run()正是Th
26、read类中的run()函数的覆盖,其他工具接入时,需要在该函数中编写代 码使得自己的工具能够启动。AutomatorToolsDriver那么是AutomatorToolsTest的管理器,其中包含三个抽象函数:public abstract void start()public abstract AutomatorToolsTest startTestTask()public abstract void dispatchTest()作用分别是开始整个测试、启动一个AutomatorToolsTest与开始测试前所需要做 的环境和数据的处理。这样做可能在连接多台手机时,获取所有连接着的手机的
27、信息, 并且可以做到同时在这些手机上开始测试。4.1.2 Mutant Manage 模块该模块主要与变异生成与变异覆盖率获取相关,由于变异的流程较长,因此将这 个模块别离出主流程并进行单独的处理。在该模块的流程中,如图4.1中最右侧的流程所示,我们需要先将源代码复制一 份备用,接着调用MDroid+工具来生成变异后的代码,这一步由函数public void mdpAutoPull.entrance.createMutant()方法来完成,但是由于MDroid+只会生成编译后的代码,因此我们还需要通过函 数public void mdpAutoPull.entrance.createApk()
28、来将这些变异过的代码一个个的加入之前复制后的源代码中并进行编译来生成 变异apk。接着使用函数public void mdpAutoPull.autoExecutio.exec()就会自动将这些apk安装到手机上并根据用户输入的测试代码来进行测试了。测 试完毕后,会输出日志,最后,根据这些日志,框架会使用函数public void mdpAutoPull.autoExecutio.logMerge()来将这些日志整合,就可以获知本次测试中有多少变异被覆盖到了。4.2Execution子模块的详细设计与具体实现Execution子模块主要包含了五个局部,从图4.1上可以看出,分为插桩、执行、 反
29、响执行数据、计算得分与数据输出。本节会对这五个局部的详细设计与具体实现进 行一一讲解。4.2.1 插桩在本框架中,代码覆盖率是最为主要的得分依据,因此,首先要得到安卓应用的 源代码才可以进行测试。但是,虽然现在在学术界有一些可以对安卓应用程序进行反 编译以获取源代码的程序,现如今仍然有许多安卓应用程序是加了外壳的,这也就导 致工具的不可使用,因此,我们需要用户本身输入源代码给框架进行各种操作。综上所述,我们需要为程序进行插桩,插桩是指,对代码中注入一些叫做桩的 代码,这些代码被运行到了之后,会进行某些操作,在测试完毕后这些代码的状态会 被返回到一个新建的文件中,只要分析这个文件,我们就能了解到
30、测试的执行经过了 哪些地方,甚至于知道测试的流程是怎样的。在人机对战框架中,我们选择对将安卓 程序编译好后生成的.class文件进行插桩,由于.class文件是被源文件生成且可以被覆 盖的,这样做可以防止源代码被修改导致的不可恢复的问题。那么首先就要来介绍一下Java字节码是什么。Java字节码是通过javac (javacompile)命令或者其他IDE工具,将Java源文件 编译后生成的.class文件中的内容,由于该文件是放在Java自己的JVM (Java虚拟 机)中执行的,因此它使得Java实现跨框架运行的功能。比方有这样一个简单的Java方法:public static void
31、try()a();if(b()c();elsed();e();将其转换为字节码后,会变成:public static try()V/V指该函数的返回值简写INV0KESTAT1C a()V / INVOKESTATIC 指调用一个静态方法INV0KESTAT1C a()V / INVOKESTATIC 指调用一个静态方法INVOKESTATIC b()ZIFEQ LIINVOKESTATIC c()VGOTO L2/IFEQ指当且仅当值为。时成立,即b()=0 b()不为0,执行c()/函数的结束,继续执行后面的命令L1:INVOKESTATIC d()VL2:INVOKESTATIC e()
32、VL1:INVOKESTATIC d()VL2:INVOKESTATIC e()Vb()为0,执行d()/if结束,执行最后的e()RETURN完整的Java字节码文件中还包含有魔数(magic number),版本(version)等信 息,和插桩本身无关因此暂时不作介绍。而插桩那么是在这些指令中根据一个既定规那么加入指令,具体实现过程仍然以上述方法为例,如图4.2所示:RETURN图4.2java代码、字节码与插桩后比照表4探针注入的执行流程图种类汪入刖注入后备注序列在一个简单的序列 情况下,在所有语句 之中注入一个探针 即可。语句A语句A语句BP语句B无条件跳转在无条件跳转中,和 序列一
33、样,是一定会 执行的,因此在 GOTO指令前注入 一个探针即可。GOTOP语句AGOTO语也-4在有条件跳转中,由 于需要了解测试过 程究竟经历了哪一 侧,因此两边需要各 注入一个探针。语句B4-P语句C语句BPf语句C具体的插桩方式通过Jacocot151, 一款已经存在多年且仍然在不断更新的著名代码 覆盖率检测工具来进行完成,该工具使用ASM3.0的接口来进行实现,ASM3O是 一个专门对Java字节码进行操作的APL通过使用该APL我们可以做到对Java字 节码的增加、删除、修改等操作。Jacoco会在四种情况下进行插桩,如表4.1所示。这四种情况包含了所有字节码中可能出现的情况,而且比
34、每一句字节码都插桩要 节省空间,故而选择这种插桩方法。在插桩的类文件中,会先设定好一个布尔数组,在P处放置与该数组对应的代 码,如果P处被执行到了,那么该布尔数组的对应位置那么会被设定为true。当测试指 定完毕后,只要检测该布尔数组,那么可以知道对应处的执行情况。摘要近年来,在互联网的带动下,使用智能手机的人数越发上涨,安卓与IOS也成为 了移动应用的主体。其中安卓平台的开展更为迅速,2017年11月1日,美国市场研 究机构NPD Group说明,安卓在美国智能手机市场上的销量份额首次超过IOS。也 正因如此,市场对安卓应用的要求不断提升,开发人员需要提供高品质的应用才能满 足用户的需求,对
35、安卓应用的测试便成为了开发应用中的一个关键流程。但是,测试结果本身的好坏,其实是难以判断的。所有的测试用例都通过了,并 不代表应用的所有问题都被发现了,更何况,使用不同的测试方法,由于他们的测试 过程不同,所得到的结果也会完全不同,这就使得这些结果相互之间不可比拟。因此, 为了使得安卓测试的结果有一定的可比性,本文提出了一种能够标准化安卓应用测试 结果的框架,主要用于在人机对战中能够给出一个可比的结果。本平台通过代码的各 种覆盖率、日志中的异常信息、变异的执行情况等方面进行结果的评判,最后给出所 有的详细生成结果与最终得分。与此同时,使用该框架中接入的工具对多个安卓应用 进行测试,得出的结果与
36、己有论文中所述的结果基本相同,证明了框架的可靠性。关键词:安卓测试;自动化测试;人机对战;安卓变异该方法的具体实现,需要人工手动完成。首先要将Jacoco引入到待测应用的项 目中。Jacoco官方提供了一份生成覆盖率数据的代码,其中包含方法:task jacocoTestReport(type: JacocoReport) group = nJacocoReportndescription 二 H Generate Jacoco coverage reports after running tests.n reports xml.enabled = true html.enabled = tr
37、ue)classDirectories = fileTree( dir: *./build/intermediates/classes/debug1, excludes:,*/*$InjectAdapter.class*/*$ModuleAdapter.class, */*$ViewInjector*.class )sourceDirectories = files(coverageSourceDirs)executionData = files, $buildDir/outputs/code-coverage/coverage.ec)doFirst new File(n$buildDir/i
38、ntermediates/classes/n).eachFileRecurse file - if (file.name.contains(,$,) file.renameTo(61e.path.replace($, $) ) ) ) )该方法会扫描当前状态下,类中之前插入的布尔数组的信息,来判断有多少桩已 经被覆盖了,并生成一个.ec文件,其中包含了这些信息。该文件是二进制文件,在 查阅了 Jacoco官方文档后,本文将这些内容按一定规范输出,可以看到如图4.3所示 的内容:1 version:e2 id:unknownhost-a8bea9223 6id:7 name:com/white/
39、bihudai1y/module/splash/SplashActivityprobes0:true8 probes1:false9 probes2:false liprobes3zfalse12 probes4:false13 probes5zfalse14 probes6zfalse15 probes7:false16 probes8:false17 probes9zfalse18 probes10:false19 probes11zfalse20 probes12:false21 probes13zfalse22 probes14:false23 probes15:false24 pro
40、bes16:false25 probes 17:false26 probes18:false27 probes19:false28 probes20:false29 probes21:falseso probes22zfalse31 probes23:false32 probes24zfalse33 probes25zfalse34 probes26zfalse35i name:com/white/bihudaily/app/BihuDai1yApplication36 probes0:trueprobes1zfalse37 probes 2:trueprobes3:true图4.3 ec文件
41、内容而接下来的一步是需要手动完成插桩工作的原因。由于jacocoTestReport方法需 要被触发才能执行,因此我们必须将该方法加入到应用源代码的Acticity相关的类的 代码中。即当用户触发Activity中的某个方法时,Jacoco才能生成这样一份覆盖率信 息。但是单纯的将方法放入Activity中的Ondestry。方法,会因为某些未知的原因导 致该函数并不会被执行到。因此目前的方法是自动化的将jacocoTestReport方法加入 到每一个Activity文件中的每一个函数的开头。这样做其实是有弊端的,如果每一个操作都会进行数据的生成,会导致交互速度 变慢,生成大量无用文件等问题
42、。因此这是一个仍需解决的问题。但是以目前的方法来看,将jacocoTestReport方法加入到每一个函数的开头确实 是有效的。只是因为弊端较大,因此没有将该过程的自动化加入到框架中。执行测试由图4.1可知,人机对战框架的执行可以分为人工代码执行和自动化测试工具执 行两局部。为了保证框架使用的简易型,我们已经将测试代码的执行简化为输入一句代码即 可执行的一键化流程。对于人工编写的测试代码,由于Java的自动化编译与执行需求工程的引入包的 固定,因此我们要求待测代码的工程格式与我们的要求相同,同时,使用Appium作 为自动化测试的框架,因此用户的电脑上必须将Appium环境配置完毕,准备完全后
43、, 用户只需要提供测试代码的位置、待测Apk的源码位置、待测Apk的位置等相关信 息输入框架,框架就会自动执行本次测试并给出结果。对于自动化工具而言,首先需要接入我们提供的接口,该接口允许代码编写者执 行一个脚本来启动相应的工具,所有的参数只需要在脚本中调整完毕即可。接着,使 用者只需要提供自己想选择的,且框架中已接入的工具的名称和待测Apk源码位置、 待测Apk的位置等信息,框架就会自动执行本次测试并给出结果。执行的具体实现主要由类ManualTest与类AutomatorToolsDriver来完成,后者属 于Interface模块,因此暂时不作介绍。而前者主要分为三个局部,执行前置操作、
44、执 行与执行后收尾处理。appium -a 127.0.0.1 -p $1 -U $2 -log-level info:error -log $3 -session-override -bp $5 | tee $4public void setupAppium(String outputdir ,String devicelD, String logCatPath, String appiumLogsPath, String exceptionLogsPath) throws InterruptedException Process process = null;int dp = (Integ
45、er研port) + 100);String command = cmd + Commands/linux/appium.sh + port + ” “ + devicelD + ” ” + exceptionLogsPath+ n + appiumLogsPath + + dp;System.owtprintln(command);r.exec(command);)上述代码为启动Appium服务的一局部代码节选,人工脚本测试中,框架首先需 要自动启动Appium来保证测试可以执行,上述代码会启动Appium服务,并将Appium 输出的日志放置在用户输入的输出文件夹中。接着,使用类似的方法,我们也会将手机的日志信息输入到输出文件夹中:adb -s $1 logcat -c # clear buffer# select the application pid and ActivityManager , ActivityThreadadb -s $1 logcat -v long $2public void startCaptureLog(String deviceTD)command=cmd+ +Commands/linux/logcat.sh +deviceID + + logPath;log