开发者社区> 晚来风急> 正文

移植MonkeyRunner的图片对比功能实现-Appium篇

简介:
+关注继续查看
如果你的目标测试app有很多imageview组成的话,这个时候monkeyrunner的截图比较功能就体现出来了。而其他几个流行的框架如Robotium,UIAutomator以及Appium都提供了截图,但少了两个功能:
  获取子图
  图片比较
  既然Google开发的MonkeyRunner能盛行这么久,且它体功能的结果验证功能只有截屏比较,那么必然有它的道理,有它存在的价值,所以我们很有必要在需要的情况下把它相应的功能给移植到其他框架上面上来。
  经过本人前面文章描述的几个框架的源码的研究(robotium还没有做),大家可以知道MonkeyRunner是跑在PC端的,只有在需要发送相应的命令事件时才会驱动目标机器的monkey或者shell等。比如获取图片是从目标机器的buffer设备得到,但是比较图片和获取子图是从客户PC端做的。
  这里Appium工作的方式非常的类似,因为它也是在客户端跑,但需要注入事件发送命令时还是通过目标机器段的bootstrap来驱动uiatuomator来完成的,所以要把MonkeyRunner的获取子图已经图片比较的功能移植过来是非常容易的事情。
  但UiAutomator就是另外一回事了,因为它完全是在目标机器那边跑的,所以你的代码必须要android那边支持,所以本人在移植到UiAutomator上面就碰到了问题,这里先给出Appium 上面的移植,以方便大家的使用,至于UiAutomator和Robotium的,今后本人会酌情考虑是否提供给大家。
  还有就是这个移植过来的代码没有经过优化的,比如失败是否保存图片以待今后查看等。大家可以基于这个基础实现满足自己要求的功能
  1. 移植代码
  移植代码放在一个Util.java了工具类中:
public static boolean sameAs(BufferedImage myImage,BufferedImage otherImage, double percent)
{
//BufferedImage otherImage = other.getBufferedImage();
//BufferedImage myImage = getBufferedImage();
if (otherImage.getWidth() != myImage.getWidth()) {
return false;
}
if (otherImage.getHeight() != myImage.getHeight()) {
return false;
}
int[] otherPixel = new int[1];
int[] myPixel = new int[1];
int width = myImage.getWidth();
int height = myImage.getHeight();
int numDiffPixels = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (myImage.getRGB(x, y) != otherImage.getRGB(x, y)) {
numDiffPixels++;
}
}
}
double numberPixels = height * width;
double diffPercent = numDiffPixels / numberPixels;
return percent <= 1.0D - diffPercent;
}
public static BufferedImage getSubImage(BufferedImage image,int x, int y, int w, int h)
{
return image.getSubimage(x, y, w, h);
}
public static BufferedImage getImageFromFile(File f) {
BufferedImage img = null;
try {
img = ImageIO.read(f);
} catch (IOException e) {
//if failed, then copy it to local path for later check:TBD
//FileUtils.copyFile(f, new File(p1));
e.printStackTrace();
System.exit(1);
}
return img;
}
这里就不多描述了,基本上就是基于MonkeyRunner做轻微的修改,所以叫做移植。而UiAutomator就可能需要大改动,要重现实现了。
 2. 客户端调用代码举例
packagesample.demo.AppiumDemo;
importstaticorg.junit.Assert.*;
importjava.awt.image.BufferedImage;
importjava.io.File;
importjava.io.IOException;
importjava.net.URL;
importjavax.imageio.ImageIO;
importlibs.Util;
importio.appium.java_client.android.AndroidDriver;
importorg.apache.commons.io.FileUtils;
importorg.junit.After;
importorg.junit.Before;
importorg.junit.Test;
importorg.openqa.selenium.By;
importorg.openqa.selenium.OutputType;
importorg.openqa.selenium.WebElement;
importorg.openqa.selenium.remote.DesiredCapabilities;
publicclassCompareScreenShots{
privateAndroidDriverdriver;
@Before
publicvoidsetUp()throwsException{
DesiredCapabilitiescap=newDesiredCapabilities();
cap.setCapability("deviceName","Android");
cap.setCapability("appPackage","com.example.android.notepad");
cap.setCapability("appActivity",".NotesList");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),cap);
}
@After
publicvoidtearDown()throwsException{
driver.quit();
}
@Test
publicvoidcompareScreenAndSubScreen()throwsInterruptedException,IOException{
Thread.sleep(2000);
WebElementel=driver.findElement(By.className("android.widget.ListView")).findElement(By.name("Note1"));
el.click();
Thread.sleep(1000);
Stringp1="C:/1";
Stringp2="C:/2";
Filef2=newFile(p2);
Filef1=driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(f1,newFile(p1));
BufferedImageimg1=Util.getImageFromFile(f1);
f2=driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(f2,newFile(p2));
BufferedImageimg2=Util.getImageFromFile(f2);
Booleansame=Util.sameAs(img1,img2,0.9);
assertTrue(same);
BufferedImagesubImg1=Util.getSubImage(img1,6,39,474,38);
BufferedImagesubImg2=Util.getSubImage(img1,6,39,474,38);
same=Util.sameAs(subImg1,subImg2,1);
Filef3=newFile("c:/sub-1.png");
ImageIO.write(subImg1,"PNG",f3);
Filef4=newFile("c:/sub-2.png");
ImageIO.write(subImg1,"PNG",f4);
}
}
  也不多解析了,没有什么特别的东西。
  大家用得上的就支持下就好了...

最新内容请见作者的GitHub页:http://qaseven.github.io/

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
App自动化测试|Appium元素定位工具
App自动化测试|Appium元素定位工具
48 0
干货|app自动化测试之Appium 源码修改定制分析
干货|app自动化测试之Appium 源码修改定制分析
76 0
如何在Android手机上使用poco框架进行测试
如何在Android手机上使用poco框架进行测试
364 0
测试了5款最常见的模拟器,发现与Airtest自动化最配的竟然是...
测试了5款最常见的模拟器,发现与Airtest自动化最配的竟然是...
430 0
Appium自动化(7) - 控件定位工具之Appium 的 Inspector
Appium自动化(7) - 控件定位工具之Appium 的 Inspector
323 0
Android测试工具 UIAutomator入门与介绍(下)
  UI Automator 测试工具定义以及用途
100 0
Android测试工具 UIAutomator入门与介绍(上)
  UI Automator 测试工具定义以及用途
110 0
干货|app自动化测试之Appium 源码修改定制分析
Appium 是由 Node.js 来实现的 HTTP 服务,它并不是一套全新的框架,而是将现有的优秀的框架进行了集成,在 Selenium WebDriver 协议(JsonWireProtocol/Restful web service)的基础上增加了移动端的支持,使 Appium 满足多方面的需求。 官方提供更详细的 Appium 结构说明:https://appium.io/docs/e
95 0
手机自动化测试IDE-----Airtest基本操作方法
手机自动化测试IDE-----Airtest基本操作方法
277 0
Python+Appium自动化测试(9)-自动选择USB用于传输文件(不依赖appium对手机页面元素进行定位)
Python+Appium自动化测试(9)-自动选择USB用于传输文件(不依赖appium对手机页面元素进行定位)
102 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
荷鲁斯 移动端第三方库安全检查引擎介绍
立即下载
荷鲁斯移动端第三方库安全检测引擎介绍
立即下载
函数计算最佳实践:快速开发一个分布式 Puppeteer 网页截图服务
立即下载