实 验 简 介
UI自动化实现分三种,第一种基于坐标,二种基于图像,第三种基于元素,本章介绍的自动化工具SikuliX,它不仅提供一个IDE的工具,还提供了SikuliX.jar的Java包,供JAVA程序调用。能够以JAVA代码来方式实现自动化。
Python语言之所以被称之为‘胶水语言’,是因为它可以直接调用其他编程语言。当我们想要通过Python来调用SikuliX.jar,是可以通过第三方包jpype来执行JAVA代码的方式来实现。
实 验 目 的
(1)理解如何使用Python调用Java代码接口。
实 验 流 程
1.在Python中安装jpype1的第三方扩展包。
在cmd中执行pip install jpype1或者Python –m pip install jpype1,由于使用的Python3.x版本,所以没有用jpype包,而是使用jpype1包(后面不是L,是数字1)如图所示。
当本机上没有jpype-0.6.2包时会自动在网络上搜索镜像文件并安装,很多时候在安装过程中会出现一些错误,如图所示。
如果出现上面的问题,说明需要在系统中安装Visual C++ Build Tools 2015,可以从 http://landinghub.visualstudio.com/visual-cpp-build-tools 这个网址上下载。
2.编写Python调用SikuliX的代码。
(1)安装好jpype1包后,就可以写端Python调用Java的代码,看看能否成功。
import jpype #引入jpype模块 jvmPath = jpype.getDefaultJVMPath() #指定jvm的默认路径 jpype.startJVM(jvmPath) #通过jpype启动jvm jpype.java.lang.System.out.println( ‘hello world! ‘) #通过jpype执行Java代码 jpype.shutdownJVM() #关闭jvm |
如果环境没有问题,能够正常调用JVM时,上面代码在Python执行结果如图所示。
(2)由于需要通过Java来调用SikuliX.jar的Java包,所以需要注意自己电脑上Java的版本,SikuliX1.1.1是支持JDK8的,所以可以在http://java.com/en/download/manual.jsp下载JDK 8。
(a)配置Java环境变量:
首先,右键计算机---属性---高级系统设置---环境变量;建议是都设置系统变量,一般Path这个变量是存在的。
(b)添加JAVA_HOME:
新建系统变量JAVA_HOME
变量名:JAVA_HOME
变量值:C:\ProgramFiles\Java\jdk1.8.0(此处是你的jdk安装目录,建议默认的C盘即可)
(c)添加CLASSPATH:
新建系统变量CLASSPATH
变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
(d)添加Path变量内容:
这个变量一般系统中已经存在,所以编辑它,在最后加上如下变量值:
变量值:.;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
添加完成之后,确认保存
(3)通过Python调用SikuliX.jar来操作蜗牛进销存系统。
想要用Python调用jar的Java包,不光需要通过jpype模块,还需要明确引入SikuliX.jar的扩展包。
前面直接调用Java的代码明显不能满足要求,缺乏引入指定jar包的方法。在startJVM()函数中,不光有指定JVM路径的参数,还有args参数,可以将指定的扩张包交给JVM编译。那么在代码中就可以加入SikuliX.jar的包。其作用相当于在Java代码中import SikuliX。既然可以引入jar包,那么执行SikuliX操作可以有两种方式来实现:
第一种:在Java中直接调用SikuliX.jar。然后将SikuliX的操作代码打包成jar文件,在Python中调用;
第二种:在Python中通过jpype引入SikuliX.jar。然后在后面直接调用Java来执行SikuliX来操作页面。
这里就只演示后者。
import jpype #引入jpype模块来执行Java代码 import os,time jvmpath = jpype.getDefaultJVMPath() #指定Java的JVM路径 jarpath = os.path.join(os.path.abspath('.'), 'G:/SikuliX/SikuliX/SikuliX/') #指定jar包路径 if not jpype.isJVMStarted(): #判断JVM是否启动 jpype.startJVM(jvmpath,'-Djava.class.path=%s'%(jarpath+'SikuliX.jar')) system = jpype.java.lang.System #为System调用定义一个变量,方便后面使用 javaclass = jpype.JClass('org.Sikuli.script.Screen') #引入SikuliX中的Screen类 s = javaclass() #实例化Screen类得到对象 s.doubleClick('D:/Sikulitest/1515658316113.png') #通过Screen对象操作 time.sleep(10) #SikuliX包中没有了Sikuli-script包中的wait()函数,用线程休眠代替 s.click('D:/Sikulitest/1515660994865.png') s.type('http://localhost:8080/WoniuSales/\n') time.sleep(2) s.click('D:/Sikulitest/1515738489187.png') time.sleep(2) s.click('D:/Sikulitest/1515738607167.png') s.type('18781163070') s.click('D:/Sikulitest/1515739177258.png') jpype.shutdownJVM() #关闭JVM |
这里只是实现了Python代码的jar包调用,具体用于测试的验证点插入就省略了,和IDE一样的方法就不在赘述,只是在使用的时候需要注意一些IDE里的方法代码里没有,比如wait(),我们可以使用time的sleep()函数来解决。
如果想要得到wait()方法相同的效果,也就是在一个超时时间范围内一直等待,需要自己封装一个方法来实现。
def wait_element(n,img): #n是自定义超时时间,数据类型为int,img是要等待的元素 if type(n) == int: for i in range(n): if exists(img): #如果存在该图片,等待结束 break else: time.sleep(1) #如果不存在,1秒后再找 else: return Flase #超时后,直接返回元素找不到 else: print(‘超时时间类型错误,请输入整型’) return True |
这样,在需要的时候调用该方法,一样可以在一个自定义的超时时间范围内等待目标元素出现。
3.SikuliX使用总结。
对于界面元素识别的容错能力,实现了标准的断言,通过对比两张图像是否一致来决定测试结果的正确性等。所以,在相对稳定的项目中,我们已经可以较好地使用Sikuli来完成自动化测试了。
SikuliX作为一款UI自动化工具,其基于图像识别的方式,对于使用者来说,上手快,使用简单,操作容易的特点,对于大家来说已经有一定的体会。但是,SikuliX无论是使用IDE直接调用Jypthon,还是通过代码调用jar包来实现自动化,它都有一些局限性, Sikuli只有提供一个exists()的函数来匹配结果,当使用者想通过界面上元素内容来做验证的时候,却发现没有提供相对应的方法。因为exists()方法也只能通过图片来作判断。
而且,由于并不是所有的界面元素都是标准的。从稳定性上来说,也同样存在问题,比如界面元素的风格变化或者大小的变化等,或者是多个元素的图像非常类似的情况,都会导致Sikuli无法正确地识别的操作。所以我们仍然有必要继续探寻更加稳定的自动化测试实施方案。就前面对这款工具的使用做如下总结:
1.优点
(1)整体上Sikuli小巧、便捷、容易上手。
(2)Sikuli脚本可以不经过API的编译器直接自动化搜索到任何你能在屏幕上看到的东西。
(3)对各种程序都适合,B/S和C/S使用时一样的。
(4)不存在标准控件和非标准控件的问题,都是通过图片来查找。
(5)相对位置概念较小,要求不高(但是对象本身尺寸有影响)。
(6)一次编码,多次运行(基于java的)、jython和java的支持,用编程的方式比较容易扩展 。
2.缺点
(1)图片的分辨率、色彩、尺寸、唯一性对程序的影响 (如果有两个相同的,无法区分具体哪一个)。
(2) Sikuli本身还不完善(处于开发、升级阶段)还有很多程序bug,能否继续发展还是未知数。
(3) 只认识当前活动的图标(只有当前界面有才行),如果有遮挡就找不到元素的异常。
(4) 用例组织方面有提供但是目前有bug,还未调研尝试便利性。
(5) 脚本基于截图,存储占用空间较大。
(6) 目前还不适合设计成一种测试框架(有用例组织功能,但是目前有bug,暂时没有用过)。
(7) 测试报告的生成,直接用message的话比较弱。
思 考 练 习
(1) 完成上述实验,并且尝试利用Python调用Java的其他接口。
下周分享:核心实验:Selenium WebDriver->基础使用