古锐,肖璞
(三江学院计算机科学与工程学院,南京 210012)
近些年,手机端的自动化测试工具和框架逐渐增加,但是它们也存在着一些问题。Appium是手机端的自动化测试的一个开源框架,它可以针对原生的应用和Web应用甚至是两种混合的应用进行自动化测试[1]。
本课题的研究目的在于通过基于Appium的Android应用自动化测试框架的研究,在针对同一款Android应用(可能会进行版本迭代或更新)进行测试时,能够将一些人为的手工测试中效率较低且容易出错[2]的基本操作,例如安装启动应用、注册登录、进行点击查看、页面滑动和文本输入等,通过Appium自动化测试框架编写自动化的测试用例脚本来执行对这些机械重复的测试用例的测试,从而提高测试效率。
本论文从自动化测试技术、Appium工具简介和Appium设计理念入手,自主搭建自动化测试所需要的Android环境和Appium环境并进行了相应的配置,通过Eclipse工具编写符合所测试的Android手机App的测试用例。
自动化测试指的是针对软件测试的一种自动实现,为了让人力降低,时间得到保证,并减少一定成本,提高测试的效率,便有了自动化测试这个概念。
自动化测试和手工测试是相辅相成的,在实际生活中,只有在满足必要的前提条件的情况下我们才能去执行自动化测试。可以分以下几种情况,首先这个项目的测试周期一定要足够长,因为完成自动化测试的可行性分析,对测试框架进行选择、设计、编码和调试测试脚本等都需要一定的时间和技术支持。另外,针对某个具体软件或系统,它的需求也不能变动地太频繁,因为需求变化大,测试用例和测试脚本都需要做出相应的调整,这个时候项目的成本便会提高。还有值得一提的是,编写的自动化测试脚本最好能够实现很好的复用,否则自动化测试便不能产生真正意义上的效益。
Appium是支持自动化测试的一个工具,也是支持自动化测试的一个开源框架。Appium支持对iOS平台和Android平台上的原生应用、Web应用和混合应用的测试,iOS和Android应用是通过Web Driver协议来驱动的[3]。另外,Appium支持跨平台,测试人员可以通过它使用相同的API在不同的平台上来编写自动化测试代码,这样可以让代码反复使用。
Appium的核心其实是一个Web服务器,它负责接收发自客户端的连接,监听这些命令并通过不同框架转变成可以交互的代码再在测试手机上执行它,然后返回至Appium服务器运行的结果,最后再返还HTTP响应给客户端。在这种情形下,实际上我们就可以直接使用带HTTP客户端的API的任何语言来写我们自己的测试代码。我们可以将服务器端放置在与测试机不同的机器上,只编写测试代码,然后使用远程云服务来接收和解释命令。
Appium Server是通过Node.js写的,我们可以用源码编译的方式或者直接通过NPM($npm install-g appium$appium)命令安装[3]。Appium还提供了很多基于 WebDriver协议扩展的 C#、PHP、Python、Ruby、JavaScript和Java语言的客户端库[3]。这里的WebDriver可以说是用来进行自动化测试的一个东西,它提供了一些比如对应用中的界面元素进行定位和模拟用户行为等的API,使用Json经由HTTP与服务器进行底层的交互。当使用Appium时,测试人员可以使用它们来代替常规的的WebDriver库。这里我们还需要对Bootstrap.jar有一个了解,首先它是一个UiAutomator测试脚本,由Appium提供,在Android测试机上运行。它能够在测试机上打开一个名为Socket的服务器,负责将Appium从电脑端传过来的指令发送到手机端上,然后通过UiAutomator来执行命令和操作。
Appium的工作原理图和Appium架构图如图1和图2所示。
图1 Appium原理图
图2 Appium架构图
Appium的设计理念可以说是依据下面几个方面进行描述的,首先,由于在所有的平台上Appium都是使用标准的自动化API的特性,测试人员不需要为了自动化测试而去重新编译应用(App)或者对测试App进行修改[3]。Appium使用了client-server的设计模式,而且它的客户端可以是用不同语言编写的,也就是说,测试人员可以使用自己常用的开发工具、开发语言和测试框架去编写自动化测试脚本代码,而不会被限制在某种特定语言或者特定的框架上[3]。而且对于测试人员来说,不再需要为了自动化测试而特地去再重写一套API,因为Webdriver协议里的API已经相当完善,只需要借鉴并且修改完善一下就可以使用了。最后,对于移动端的自动化测试来说,它应该是开源的。
本次测试的环境搭建主要分为两个部分:一是Android环境,主要用来给模拟器连接和真机连接提供支持,二是Appium环境,用来提供测试所需要的工具和环境。
首先我们需要配置Java开发的环境变量,这里我们选择安装jdk1.8(win10 64位),可以从官网下载压缩包,解压按照步骤运行。安装在指定位置好了之后,我们需要进行简单的环境配置,如下所示:
1、新建变量名:JAVA_HOME
变量值:C∶Program Files(x86)Javajdk1.8.0_31
2、新建变量名:classpath
变量值:
.;%JAVA_HOME%libdt.jar;%JAVA_HOME%lib ools.jar;
3、编辑变量:PATH
变量值:.;%JAVA_HOME%in;
4、检查是否配置成功
cmd命令符输入:java–version。
接下来,我们需要一个能连接电脑的Android手机或者是Android模拟器来执行Android移动端应用的自动化测试。这时我们需要安装Android SDK并配置环境变量。
从官网下载解压好之后就可以设置Android环境变量,配置方法与上述java环境变量类似(以本机为例):
1、新建变量名:ANDROID_HOME
变 量 值 :F∶AppiumDesignandroid-sdk_r23.0.2-windowsandroid-sdk-windows
2、编辑变量名:PATH
变量值:
;%ANDROID_HOME%platform-tools;%ANDROID_HOME% ools;
3、找到本机SDK应用程序并启动它,这里我们还需要安装一些不同Android版本的模拟器。
在Appium的官网下载与自身操作系统(Win10)对应的Appium版本:
将AppiumForWindows_1.4.16.1.zip解压,然后通过内部默认安装程序进行安装。cmd命令输入“appiumdoctor”,如果Appium所需要的各项环境都已准备完成,将出现如图3所示的提示。
图3 环境部署成功图
下面列举出本次自动化测试工作中涉及到的测试设备信息,如表1所示。
表1 测试设备信息表
本文基于Appium的Android应用自动化测试框架的研究,在此针对Android真机作了连接测试。
真机连接测试和模拟器连接测试类似,这里我们首先需要打开Android测试机的USB调试模式,通过一个数据线连接至测试电脑,接着在cmd命令中输入adb devices查看是否连接成功,在这里需要记录连接的设备编号(ef5862e9),如图4所示。
图4 真机连接成功
接下来我们需要在该Android测试机上安装需要测试的一款App(新华社客户端),这里可以通过代码实现,另外我们需要获取一些相关的配置信息(被测App的package和activity名称)。在此我们要用到之前安装的SDK内置的一个叫做aapt的工具,它位于SDK的工具目录文件夹下,我们通过cmd命令输入:
aapt dump badging
F∶AppiumDesignappium-workspaceappiumtestAppium_demoappsxhs.apk
(以xhs.apk为例,这里填写待测apk的存放路径),等待运行结束查看:
package∶name='net.xinhuamm.mainclient'
launchable-activity∶name='net.xinhuamm.mainclient.activity.sysconfig.FirstActivity'
这里就是我们需要记录的package和activity信息,在接下来的代码中需要填写,结果如图5和图6所示。
图5 package运行结果查看图
这里我们需要初始化一个Appiumdriver,并在she-zhi()中进行一系列的配置,包括需要安装的测试apk的路径、包名以及Android的设备信息等。在tuichu()中我们需要退出driver,如果不退出的话,在下次进行测试时,连接服务器就会受到影响也就是产生错误信息。
这里使用@Before和@After两个方法,它们是Junit4的注解。@Before是一个初始化方法,在每一个测试方法执行之前运行一次,而@After则是释放资源,在每一个测试方法执行之后都要运行一次。
真机连接测试的核心代码如下:
File pathlujing=new File(System.getProperty("user.dir"));
File applujing=new File(pathlujing,"/apps");//设置存放路径
File app=new File(applujing,"xhs.apk");//待测 apk
DesiredCapabilities sz=new DesiredCapabilities();
sz.setCapability("deviceName","ef5862e9");//测试机设备名
sz.setCapability("platformVersion","4.3");//Android4.3 版本
sz.setCapability("app",app.getAbsolutePath());//获取路径
//填写之前获取的包名和activity名称
sz.setCapability("appPackage","net.xinhuamm.mainclient");
sz.setCapability("appActivity","net.xinhuamm.mainclient.activi
ty.sysconfig.FirstActivity");//activity名称
driver=new AndroidDriver<>(new URL("http∶//127.0.0.1∶4723/wd/hub"),sz);//默认端口 4723
System.out.println("App 已经安装!");//输出 app 成功安装的提示信息
执行成功后在测试机上会发现自动安装了三个东西分别是 xhs.apk、AppiumSetting以及 Unlock。(每次运行都会自动安装Unlock以及AppiumSetting)
实际效果如图7所示。
图7 连接真机
针对本次Android应用App自动化测试,进行了如表2所示的测试用例的设计。
表2 自动化测试用例设计
在测试用例实现的前期,我们还需要进行一些准备工作,确保我们可以对测试机上的待测应用进行简单的点击操作。
下面通过连接测试机,自动安装待测的xhs.apk,针对xhs.apk内部页面进行部分控件的点击(click)操作。首先需要通过Android平台的UIAutomator[4],也就是android-sdk的一个工具uiautomatorviewer.bat,用它来对测试app的元素(button、text Field等)进行抓取,比如通过id、class和text等来确定具体的元素(测试机需要联网,否则无法加载页面内容)。
本次测试主要用了获取name或者id的方式定位到具体的元素,这里以页面的“学习”元素为例,在窗口左边页面点击“学习”,右侧会显示该元素的具体信息,如图8所示。
本次自动化测试的核心模块为:注册登录、页面滑动、中英文输入搜索、屏幕录制和并行测试。
(1)这里给出左滑的测试代码,需要调用下面的方法:
swipeToLeft(driver,1000,2);
核心实现代码如下:
public static void swipeToLeft
(AppiumDriver
{
int w=driver.manage().window().getSize().width;
int h=driver.manage().window().getSize().height;
for(int i=0;i { driver.swipe(w*6/7,h/2,w/7,h/2,during); try{Thread.sleep(2000);} catch(InterruptedException e) {e.printStackTrace();} } } (2)在中英文搜索模块,需要设置一些参数: //支持中文输入 sz.setCapability("unicodeboard","true"); //重置为默认输入法 sz.setCapability("resetKeyboard","true"); 由于输入测试有时需要输入中英文等字符,不同Android手机可能自带输入法或者安装了不同的输入法,这里我们统一安装并调用默认的输入法(Appium unicodeKeyboard)去执行操作,具体方法为: excuteAdbShell("adb shell ime set io.appium.android.ime/.UnicodeIME"); (3)屏幕录制和指定位置截图,我们使用jilu()和jietu()方法去实现: public void jilu()throws IOException { Runtime ss=Runtime.getRuntime(); ss.exec("cmd.exe/C adb shell screenrecord/sdcard/test.mp4");//版本>4.4 } public static void jietu(TakesScreenshot drivername,String fname) { String cPath=System.getProperty("user.dir");//获取路径 File rcrFile=drivername.getScreenshotAs(OutputType.FILE); try { System.out.println("截图保存的路径是∶"+current-Path+"/"+filename); FileUtils.copyFile(rcrFile,new File(cPath+"\"+fname)); }catch(IOException e) { System.out.println("不能保存截图"); e.printStackTrace(); }finally { System.out.println("截图已经完成,它位于 "+cPath+"folder"); } } (4)并行测试[5]是指针对两个不同型号不同版本的Android手机进行自动化测试,这里我们选取Android版本为4.3的vivo手机和Android版本为6.0的华为手机作为测试机,这里我们需要打开两个Appium窗口并设置不同的连接端口为4723(默认)和4722。 (1)在一切相关环境变量都配置好了之后,打开cmd窗口,输入appium-doctor,可能会报错,如图9所示。 图9 检查配置失败图 遇到这种情况的解决办法是将Appium安装目录中的.bin添加到环境变量Path中,以本机为例就是在Path变量中新增如下信息: F∶AppiumDesignAppiumAppium
ode_modules.bin 再次输入appium-doctor,就会发现运行成功,显示所有环境已经配置完毕。 (2)上面我们提到在每次启动Appium跑测试用例时都会自动默认安装Unlock以及AppiumSetting,这里有个办法可以解决这个问题:找到Appium的安装目录,用记事本打开android.js文件,注释掉自动安装unlock和setting两个app的代码: F∶AppiumDesignAppiumAppium
ode_modulesappi -umlibdevicesandroid 如图10所示。 图10 修改配置文件图 注释其中的几行: this.pushSettingsApp.bind(this), this.pushUnlock.bind(this), this.unlock.bind(this), (3)在我们自动化测试的时候,一定要在用例中的相应位置添加一些等待界面元素加载或响应的等待时间,如果运行报错,一般情况是找不到元素或者未设置等待时间,此时可以使用下面的方法避免这个问题: try{Thread.sleep(3000);}//设置一定的秒数等待 catch(InterruptedException a) {a.printStackTrace();} (4)常见的报错问题∶Failed to start an Appium session.Error∶Requested a new session but one was in progress. 解决办法:关掉正在运次的Appium服务,在Appium界面的General Settings中勾选Override Existing Session,然后重启Appium。 本文主要研究了Appium自动化测试框架,同时结合Android手机应用,针对App进行自动化的一个测试。Appium提供的平台等特性能够将自动化测试Android手机的功能很好的实现,在配置好环境等一切相关信息之后,通过执行用例(可使用不同语言)就能快速地执行对测试机的操作,这无疑让本次测试工作的效率也得到了一定的提升。 最后,虽然本次自动化测试工作的研究还算有一定的进展,但是也遇到和存在着很多的问题,例如运行报错,功能能够成功实现或者失败的验证逻辑也可以做一个更深的探讨与完善等。7 环境搭建问题与解决方法
8 结语