前言
针对C/S架构的项目做自动化测试,我们可能最先考虑的是引入惠普的QTP工具,软件上的每一个空间都可以识别成唯一的元素定位,对这些元素按照测试用例进行操作,实现开发自动化测试脚本的目的。而对于非传统的C/S架构的软件系统,比如C/S中嵌入了B/S,这时QTP就可能没有办法识别B/S大空间内部的元素,只能把整个B/S的空间作为一个元素识别出来,这样我们就没办法来操作B/S内部的元素,当然,QTP也是支持坐标的,但是做过的人可能都知道,这种方式其实并不稳定,而检查点也会变得比较牵强,这个时候就引入了一个Java的第三方jar包:Sikuli。
原理
Sikuli的原理很简单,把屏幕上的片段截图作为元素,以这些图片作为操作对象来完成C/S的自动化测试,同样以图片为元素作为验证点。
优点
优点的话可能就是突破了上面说的QTP有些空间的内部元素无法识别的一个瓶颈,当然,这种方式同样可以应用在Web的自动化测试中。
缺点
就我在项目中的使用过程,发现的缺点有三个:
1、需要大量的截图(这里其实可以从开发那边拿到一些控件的图片,会更精准一点)
2、当前屏幕上有两个相同的截图吻合,Sikuli无法判断究竟是操作哪个元素
3、Sikuli驱动键盘和鼠标去操作图片元素,在屏幕上可以看到鼠标移动的轨迹,在执行自动化的时候鼠标和键盘不可以动,这也就使得调试就会有点麻烦了。庆幸的是,Sikuli的API很简单,在调试上也不会造成太多的麻烦。
引入Sikuli的jar包
如果自动化框架是用Maven来管理第三方jar包的话,在pom.xml文件中加入下面的代码即可:
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>1.1.0</version>
</dependency>
如果是手工导入的话,可以在官网去下载 http://www.sikuli.org/
包的全名为sikulixapi-1.1.0.jar
private Screen s = new Screen();
private String root;
private String path;
// 获取图片路径
public PCFramework(String module) {
root = Thread.currentThread().getContextClassLoader().getResource(".").getPath();
path = root.replace("target/test-classes/", "src/test/resources/data/imgs/" + module + "/");
GeneralMethods.log(">==================================================<");
try {
ITestResult it = Reporter.getCurrentTestResult();
GeneralMethods.log("Now Starting: " + it.getTestClass().getName());
} catch (Exception e) {
}
}
Screen是sikuli开放主要API功能的类,定义一个screen的对象即可调用所有的操作,包括点击,双击,右键点击,移动到指定位置,输入文本等操作。
构造函数的功能主要是为了指定截图的路径,传入module参数以区别截图下面的不同文件夹,按功能把截图放到指定的路径下面。
// 点击图片
public void click(String imgName) {
try {
GeneralMethods.log("Click on 【" + imgName + "】");
wait(imgName);
s.click(fullPath(imgName));
} catch (Exception e) {
throw new RuntimeException("Cannot find the img file: " + imgName);
}
}
// 双击图片
public void doubleClick(String imgName) {
try {
GeneralMethods.log("Double click on 【" + imgName + "】");
wait(imgName);
s.doubleClick(fullPath(imgName));
} catch (Exception e) {
throw new RuntimeException("Cannot find the img file: " + imgName);
}
}
// 右键点击
public void rightClick(String imgName) {
try {
GeneralMethods.log("Right click on 【" + imgName + "】");
wait(imgName);
s.rightClick(fullPath(imgName));
} catch (Exception e) {
throw new RuntimeException("Cannot find the img file: " + imgName);
}
}
以上是一些基本的点击操作,其它的可以按这个套路来,可以看到封装了一个wait的方法,其实跟webdriver等待页面元素加载完成再操作元素的原理是一样的,可以按自己的需求来封装,每个方法调用一次wait,在wait方法中加入截屏的方法,脚本运行失败后可以通过截屏来判断是哪一步出现了问题。其实sikuli自带有一个截屏的方法,不过看起来不是很好用,就另外封装了一个,用的是Robot类下面的createScreenCapture方法,还比较好用。
这里提一下,图片的名称是支持中文的,如果待测的系统是中文的,用中文命名图片的话,脚本里面调用中文图片名称,这样代码更容易读懂。