如何使用Appium在移动应用程序中获取烤面包机消息的文本

时间:2017-05-03 06:35:44

标签: java appium ocr

我正在尝试在Android移动应用中验证烤面包机消息,但无法获取烤面包机消息的文本,因为它未在uiautomatorviewer中显示。 得到一些信息,在OCR的帮助下,可以截取屏幕截图并从截图中获取文本 任何人都可以帮助我在Appium项目中使用java一步一步地完成这项工作吗?

2 个答案:

答案 0 :(得分:2)

您可以按照以下链接中的信息在您的计算机上安装Tesseract:

对于Mac:http://emop.tamu.edu/Installing-Tesseract-Mac

对于Windows:http://emop.tamu.edu/Installing-Tesseract-Windows8

在您的机器上安装TessEract后,您需要在项目中添加TessEract Java库的依赖项。如果您正在使用Maven,添加以下依赖项将起作用:

    <dependency>
        <groupId>org.bytedeco.javacpp-presets</groupId>
        <artifactId>tesseract</artifactId>
        <version>3.04-1.1</version>
    </dependency>

此外,不需要遵循Ivan提到的“第3步”。

如果您正在使用'TestNG',则TessEract API只需要初始化一次,而不是每次都初始化它,根据您的框架,您可以在'BeforeTest'或'BeforeSuite'或'BeforeClass'方法中初始化它并因此在'AfterTest'或'AfterSuite'或'AfterClass'方法中关闭API。

以下是我为实现它而编写的代码。

import static org.bytedeco.javacpp.lept.pixDestroy;
import static org.bytedeco.javacpp.lept.pixRead;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.bytedeco.javacpp.lept.PIX;
import org.bytedeco.javacpp.tesseract.TessBaseAPI;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;

    public class BaseTest {

    static TessBaseAPI api = new TessBaseAPI();

    @BeforeSuite
        public void beforeSuit() throws IOException {

            File screenshotsDirec = new File("target/screenshots");

            if (screenshotsDirec.exists())
                FileUtils.forceDelete(screenshotsDirec);

            FileUtils.forceMkdir(screenshotsDirec);

            System.out.println("Initializing TessEract library");

            if (api.Init("/opt/local/share", "eng") != 0) {
                System.err.println("Could not initialize tesseract.");
            }

        }

    public synchronized boolean verifyToastMessage(String msg)
                throws IOException {
            TakesScreenshot takeScreenshot = ((TakesScreenshot) driver);

            File[] screenshots = new File[5];

            for (int i = 0; i < screenshots.length; i++) {
                screenshots[i] = takeScreenshot.getScreenshotAs(OutputType.FILE);
            }

            String outText;

            Boolean isMsgContains = false;

            for (int i = 0; i < screenshots.length; i++) {
                PIX image = pixRead(screenshots[i].getAbsolutePath());
                api.SetImage(image);
                outText = api.GetUTF8Text().getString().replaceAll("\\s", "");
                System.out.println(outText);
                isMsgContains = outText.contains(msg);
                pixDestroy(image);
                if (isMsgContains) {
                    break;
                }
            }

            return isMsgContains;

        }

    @AfterSuite()
        public void afterTest() {

            try {
                api.close();
            } catch (Exception e) {
                api.End();
                e.printStackTrace();
            }

        }
    }

我还想补充说,编写测试以读取和验证Toast消息是这样的方式不是很可靠,因为在我的一个测试中,此代码成功捕获Toast消息,而在另一个测试中它无法捕获Toast消息,因为当Toast消息消失时捕获屏幕截图。这就是我试图非常有效地编写这段代码的原因。然而,这也不符合目的。

答案 1 :(得分:0)

在Appium论坛上关注此讨论:https://discuss.appium.io/t/verifying-toast/3676

验证烤面包机的基本步骤是:

  1. 执行操作以触发屏幕上显示的Toast消息
  2. 获取x个屏幕截图
  3. 提高所有屏幕截图的分辨率
  4. 使用tessearct OCR检测Toast消息。
  5. 请参阅this repo以使用Java OCR库(参见底部):

    import org.bytedeco.javacpp.*;
    import static org.bytedeco.javacpp.lept.*;
    import static org.bytedeco.javacpp.tesseract.*;
    
    public class BasicExample {
        public static void main(String[] args) {
            BytePointer outText;
    
            TessBaseAPI api = new TessBaseAPI();
            // Initialize tesseract-ocr with English, without specifying tessdata path
            if (api.Init(null, "eng") != 0) {
                System.err.println("Could not initialize tesseract.");
                System.exit(1);
            }
    
            // Open input image with leptonica library
            PIX image = pixRead(args.length > 0 ? args[0] : "/usr/src/tesseract/testing/phototest.tif");
            api.SetImage(image);
            // Get OCR result
            outText = api.GetUTF8Text();
            System.out.println("OCR output:\n" + outText.getString());
    
            // Destroy used object and release memory
            api.End();
            outText.deallocate();
            pixDestroy(image);
        }
    }