Transplant MonkeyRunner's image comparison and sub-graph acquisition functions, and transplant monkeyrunner

Source: Internet
Author: User
Tags appium

Transplant MonkeyRunner's image comparison and sub-graph acquisition functions, and transplant monkeyrunner
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 < 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;}
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 example
package 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(By.className("android.widget.ListView")).findElement(By.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.sameAs(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...

Monkeyrunner discusses how to trigger an event through id

From com. android. monkeyrunner import MonkeyRunner, MonkeyDevice

From com. android. monkeyrunner. easy import EasyMonkeyDevice

From com. android. monkeyrunner. easy import

Device = MonkeyRunner. waitForConnection ('emulator-100 ')
MonkeyRunner. sleep (3.0)
Easy_device = EasyMonkeyDevice (device)

Easy_device.startActivity (component = 'com. watsons. android/. activity. mainactive ')
# The value following compnent is the name of your app and activity.

Easy_device.touch (By. id ('Id/logoButton '), MonkeyDevice. DOWN_AND_UP)
# The value in single quotes is id, which can be obtained from the development side or directly viewed in the code
 
Android software testing application monkeyrunner programming implementation Acquisition Interface Control click, if entering another activity cannot get control ID?

I am also online ....

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.