視覺測試工具箱

做者|Martin Schneider
編譯|Flin
來源|mediumcss

視覺迴歸測試最多見的狀況是使用基線圖像進行測試。然而,視覺測試的不一樣方面也值得討論。咱們將介紹模板匹配(使用OpenCV)、佈局測試(使用Galen)和OCR(使用Tesseract),並展現如何將這些工具無縫集成到現有的Appium和Selenium測試中。java

咱們使用Java(以及OpenCV和Tesseract的Java包裝器),但相似的解決方案也能夠經過其餘技術堆棧實現。服務器

這篇文章是2020年9月在新加坡的Taqelah和2020年Selenium會議期間(以較短的形式)發表的快速演講的配套文章。有關完整功能的演示和更多詳細信息,請參閱 http://www.justtestlah.qa/app

我但願這個總結能幫助你選擇對你的用例最有影響的工具,並給你一些關於如何將它們集成到你本身的工具箱中的想法。框架

模板匹配

模板匹配的任務是在當前屏幕上找到給定的圖像(模板)。機器學習

Waldo在哪裏?ide

對於移動測試,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/

相關文章
相關標籤/搜索