视觉测试工具箱

熵阱代码
• 阅读 1302

作者|Martin Schneider
编译|Flin
来源|medium

视觉测试工具箱

视觉回归测试最常见的情况是使用基线图像进行测试。然而,视觉测试的不同方面也值得讨论。我们将介绍模板匹配(使用OpenCV)、布局测试(使用Galen)和OCR(使用Tesseract),并展示如何将这些工具无缝集成到现有的Appium和Selenium测试中。

我们使用Java(以及OpenCV和Tesseract的Java包装器),但类似的解决方案也可以通过其他技术堆栈实现。

这篇文章是2020年9月在新加坡的Taqelah和2020年Selenium会议期间(以较短的形式)发表的快速演讲的配套文章。有关完整功能的演示和更多详细信息,请参阅 http://www.justtestlah.qa/

我希望这个总结能帮助你选择对你的用例最有影响的工具,并给你一些关于如何将它们集成到你自己的工具箱中的想法。

模板匹配

模板匹配的任务是在当前屏幕上找到给定的图像(模板)。

视觉测试工具箱

Waldo在哪里?

视觉测试工具箱

对于移动测试,Appium在其1.9版本中以图像定位器策略的形式添加了此功能。(更多信息可以在文档和早期教程中找到)其思想是将图像的Base64编码字符串表示传递给WebDriver。

使用图像定位器(image locator),你可以像任何其他WebElement一样与结果元素交互。例如:

WebElement element = 
driver.findElementByImage(base64EncodedImageFile);
element.click();

By image = MobileBy.image(base64EncodedImageFile);
new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(image)).click();

开发人员采用的方法是将功能添加到Appium服务器的一部分,并使用OpenCV(这将成为运行Appium服务器的实例的依赖项)来增强实际的图像识别能力。

有趣的是,客户端与服务器之间的流程如下所示:

  1. 从Appium服务器请求截图。
  2. 将屏幕截图和模板都发送到Appium服务器进行匹配。

这感觉并不完美,尤其是如果我们想在同一个屏幕上匹配多个模板。

当我在2018年首次实现模板匹配时(当时还不知道Appium团队已经在开发模板匹配),我也选择了OpenCV,而是在客户端运行了它。使用OpenCV Java包装器,我的代码要点如下所示:

Mat result = new Mat(resultRows, resultCols, CvType.CV_32FC1);
Imgproc.matchTemplate(image, templ, result, Imgproc.TM_CCOEFF_NORMED);
MinMaxLocResult match = Core.minMaxLoc(result);
if (match.maxVal >= threshold) {
  // found
}

这种方法不需要向上述Appium服务器发出额外的请求。实际上,除了屏幕截图的功能外,它不需要WebDriver的任何功能。它还可以与Selenium和Appium一起使用。也就是说,这也增加了对OpenCV的依赖,这次是对运行测试执行的实例的依赖。

我将以上两种方法(客户端和服务器端执行)都包装到TemplateMatcher接口中,以展示其用法(将其视为PoC)。

你可以在JustTestLah中找到更多详细信息和示例!

布局测试

另一种视觉测试类型涉及验证页面或屏幕的布局。你可以通过图像比较来做到这一点,图像比较也会隐式检查布局。一种更简单的方法是使用像Galen这样的专用布局测试工具(在我看来,这是最被低估的UI测试框架之一)。

Galen使用每个屏幕的规范来定义屏幕上的所有(重要)元素及其大小以及它们之间的绝对或相对位置。

让我们以Google搜索页为例:

视觉测试工具箱

我们可以使用以下规范表示它:

SEARCH_FIELD:
   below LOGO
   centered horizontally inside viewport
   visible

LOGO:
   above SEARCH_FIELD
   centered horizontally inside viewport
   width < 100% of SEARCH_FIELD/width
   visible

SEARCH_BUTTON:
   near LUCKY_BUTTON 20px left
   visible

注意,上面使用的是JustTestLah!框架的语法(通过在页面对象的YAML文件中定义的唯一键引用UI元素)。在纯Galen中,这些需要在spec文件的顶部定义:

@objects
    LOGO          id        hplogo
    SEARCH_FIELD  css       input[name=q]
    ...

有多种执行这些检查的方法。我更喜欢将verify方法作为BasePage抽象类的一部分:

private T verify() {
  String baseName = this.getClass().getSimpleName();
  String baseFolder = this.getClass().getPackage().getName().replaceAll("\\.", File.separator);
  String specPath = baseFolder
              + File.separator
              + configuration.getPlatform()
              + File.separator
              + baseName
              + ".spec";
  galen.checkLayout(specPath, locators);
  return (T) this;
}

这样,每当我们第一次与屏幕交互时,我们都可以轻松地从测试中调用验证(顺便说一句,我使用类似的方法来集成Applitools进行视觉测试):

public class GoogleSteps extends BaseSteps {
  private GooglePage google;

  @Given("I am on the homepage")
  public void homepage() {
    google.verify().someAction().nextAction();
  }
}

光学字符识别(OCR)

视觉断言的另一种形式是光学字符识别,其首字母缩写为OCR。每当由于某种原因将文本渲染为图像并且无法使用标准测试工具进行验证时,此功能将非常有用。

对于那些使用Selenium进行Web抓取而不是进行测试的用户来说,这可能也很有趣,因为这是网站开发人员采取的反措施之一,以使其变得更加困难。

我们使用Tesseract(一种最初由HP在1980年代开发,目前由Google赞助的OCR工具)。

我们的示例不是最实际的示例,而是要展示Tesseract在检测不同类型的字体方面的强大功能:我们将验证Google徽标是否确实拼写出“ Google”:

public class GooglePage extends BasePage<GooglePage> {

  @Autowired private OCR ocr;

  ...

  public String getLogoText() {
    return ocr.getText($("LOGO"));
  }
}
public class GoogleSteps extends BaseSteps {
  private GooglePage google;

  ...

  @Then("the Google logo shows the correct text")
  public void checkLogo() {
    assertThat(google.getLogoText()).isEqualTo("Google");
  }
}

使用的OCR服务如下所示:

public class OCR implements qa.justtestlah.stubs.OCR {

  private Logger LOG = LoggerFactory.getLogger(OCR.class);

  private TakesScreenshot driver;
  private Tesseract ocr;

  @Autowired
  public OCR(Tesseract ocr) {
    this.ocr = ocr;
  }

  /**
   * @param element {@link WebElement} element to perform OCR on
   * @return recognised text of the element
   */
  public String getText(WebElement element) {
    return getText(element.getScreenshotAs(OutputType.FILE));
  }

  /** @return all text recognised on the screen */
  public String getText() {
    return getText(getScreenshot());
  }

  private String getText(File file) {
    LOG.info("Peforming OCR on file {}", file);
    try {
      return ocr.doOCR(file).trim();
    } catch (TesseractException exception) {
      LOG.warn("Error performing OCR", exception);
      return null;
    }
  }

  /**
   * Usage:
   *
   * <pre>
   * new OCR().withDriver(driver);
   * </pre>
   *
   * @param driver {@link WebDriver} to use for capturing screenshots
   * @return this
   */
  public OCR withDriver(WebDriver driver) {
    this.driver = (TakesScreenshot) driver;
    return this;
  }

  /**
   * Usage:
   *
   * <pre>
   * new OCR().withDriver(driver);
   * </pre>
   *
   * @param driver {@link TakesScreenshot} to use for capturing screenshots
   * @return this
   */
  public OCR withDriver(TakesScreenshot driver) {
    this.driver = driver;
    return this;
  }

  private File getScreenshot() {
    return driver.getScreenshotAs(OutputType.FILE);
  }

  @Override
  public void setDriver(WebDriver driver) {
    this.driver = (TakesScreenshot) driver;
  }
}

这要求在运行测试的实例上安装Tesseract。有关完整的源代码和演示,请查看JustTestLah!测试框架。

原文链接:https://medium.com/better-pro...

欢迎关注磐创AI博客站:
http://panchuang.net/

sklearn机器学习中文官方文档:
http://sklearn123.com/

欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
梦
4年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
Aidan075 Aidan075
4年前
收藏!52个实用的数据可视化工具!
(https://imghelloworld.osscnbeijing.aliyuncs.com/7eb12e08a15ea8f07553d6fa730c8d48.png)来源丨原力大数据大家好,我是小五🐶从数据获得信息的最佳方式之一是,通过视觉化方式,快速抓住要点信息。另外,通过视觉化呈现数据,也揭示了令人惊奇的
Wesley13 Wesley13
3年前
CSS瀑布流布局
瀑布流布局是什么瀑布流布局是一种常见的网页布局方式,视觉上给人一种参差不齐的多栏的效果,常用于图片为主的版块,如下图。!(https://timgsa.baidu.com/timg?image&quality80&sizeb9999_10000&sec1589721778046&dib34a014e7481f1a5685
Stella981 Stella981
3年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
3年前
Spring Boot(十二)单元测试JUnit
一、介绍JUnit是一款优秀的开源Java单元测试框架,也是目前使用率最高最流行的测试框架,开发工具Eclipse和IDEA对JUnit都有很好的支持,JUnit主要用于白盒测试和回归测试。<!more白盒测试:把测试对象看作一个打开的盒子,程序内部的逻辑结构和其他信息对测试人员是公开的;回归测试
计算机视觉与信息取证技术讲解
今晚20:0022:00人工智能技术与自信计算机视觉就是用各种成像系统代替视觉器官作为输入敏感手段,由计算机来代替大脑完成处理和解释。计算机视觉的最终研究目标就是使计算机能象人那样通过视觉观察和理解世界,具有自主适应环境的能力。要经过长期的努力才能达到的目标。因此,在实现最终目标以前,人们努力的中期目标是建立一种视觉系统,这个系统能依据视觉敏感和反馈的某
Java服务总在半夜挂,背后的真相竟然是... | 京东云技术团队
最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(