If your target test app has a lot of imageviews, the comparison function of monkeyrunner is displayed. Several other popular frameworks, such as Robotium, UIAutomator, and Appium, provide two fewer functions:
- Obtain subgraphs
- Image comparison
Since the MonkeyRunner developed by Google has been prevalent for so long and the result verification function of its body function is only compared with screenshots, it must have its own principles and value, therefore, it is necessary to port its functions to other frameworks as needed. After studying the source code of several frameworks described in my previous article (robotium has not done it), you can know that MonkeyRunner is running on the PC end, the monkey or shell of the target machine will be driven only when the corresponding command event needs to be sent. For example, the image is obtained from the buffer device of the target machine, but the comparison picture and acquisition subgraph are made from the client PC. Here, Appium works in a similar way because it runs on the client. However, when you need to inject the event to send commands, you can use bootstrap of the target machine segment to drive uiatuomator, therefore, it is very easy to transplant the MonkeyRunner's function of obtaining subgraphs and comparing images. However, UiAutomator is another thing, because it runs on the target machine, so your code must be supported by android, so I encountered a problem when porting it to UiAutomator, here we will first provide the transplantation above Appium for your convenience. As for UiAutomator and Robotium, I will consider whether to provide it to you as appropriate in the future.
In addition, the transplanted code has not been optimized, for example, whether to save the image for future viewing. You can implement functions that meet your requirements based on this foundation. 1. Transplant the code and put it in a Util. java tool class:
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 Here we will not describe it much. It is basically a slight modification based on MonkeyRunner, so it is called transplantation. However, UiAutomator may require major changes and needs to be reproduced.
2. Client call code examplePackage sample. demo. appiumDemo; import static org. junit. assert. *; import java. awt. image. bufferedImage; import java. io. file; import java. io. IOException; import java.net. URL; import javax. imageio. imageIO; import libs. util; import io. appium. java_client.android.AndroidDriver; import org. apache. commons. io. fileUtils; import org. junit. after; import org. junit. before; import org. junit. test; import org. openqa. selenium. by; import org. openqa. selenium. outputType; import org. openqa. selenium. webElement; import org. openqa. selenium. remote. desiredCapabilities; public class CompareScreenShots {private AndroidDriver driver; @ Beforepublic void setUp () throws Exception {DesiredCapabilities cap = new DesiredCapabilities (); cap. setCapability ("deviceName", "Android"); cap. setCapability ("appPackage", "com. example. android. notepad "); cap. setCapability ("appActivity ",". notesList "); driver = new AndroidDriver (new URL (" http: // 127.0.0.1: 4723/wd/hub "), cap) ;}@ Afterpublic void tearDown () throws Exception {driver. quit () ;}@ Testpublic void compareScreenAndSubScreen () throws InterruptedException, IOException {Thread. sleep (2000); WebElement el = driver. findElement (. className ("android. widget. listView ")). findElement (. name ("Note1"); el. click (); Thread. sleep (1000); String p1 = "C:/1"; String p2 = "C:/2"; File f2 = new File (p2); File f1 = driver. getScreenshotAs (OutputType. FILE); FileUtils. copyFile (f1, new File (p1); BufferedImage img1 = Util. getImageFromFile (f1); f2 = driver. getScreenshotAs (OutputType. FILE); FileUtils. copyFile (f2, new File (p2); BufferedImage img2 = Util. getImageFromFile (f2); Boolean same = Util. sample (img1, img2, 0.9); assertTrue (same); BufferedImage subImg1 = Util. getSubImage (img1, 6, 39,474, 38); BufferedImage subImg2 = Util. getSubImage (img1, 6, 39,474, 38); same = Util. sameAs (subImg1, subImg2, 1); File f3 = new File ("c:/sub-1.png"); ImageIO. write (subImg1, "PNG", f3); File f4 = new File ("c:/sub-2.png"); ImageIO. write (subImg1, "PNG", f4 );}}
There is not much parsing, and there is nothing special. If you can use it, you just need to support it...
Porting MonkeyRunner's image comparison and acquisition of subgraphs