• Selenium Video Tutorials

Selenium WebDriver - 頁面工廠



使用 Selenium Webdriver 開發的測試用例可以透過在測試中整合不同的設計模式來簡化。其中一個廣泛使用設計模式是頁面物件模型,通常稱為 POM。為了實現頁面物件模型,我們可以藉助工廠類,也就是頁面工廠。頁面工廠類可從 Selenium Webdriver 獲得。

什麼是頁面工廠?

如前所述,頁面工廠是一個有助於實現頁面物件模型的類。它是頁面物件模型的改進版本,由 Webdriver 類提供。它具有使用註解初始化構成頁面物件的 Web 元素的功能。

頁面工廠的特性

@FindBy

此註解在頁面工廠中用於識別、宣告和執行 Web 元素的操作,藉助各種定位器,如 id、name、class name、link text、partial link text、css、xpath 和 tagname。

語法

FindBy(name = "elementname") 
WebElement e;

@FindBys

此註解在頁面工廠中用於識別、宣告和執行 Web 元素的操作,藉助各種定位器,如 id、name、class name、link text、partial link text、css、xpath 和 tagname,透過指定多個搜尋條件。必須滿足搜尋條件之間的 AND 條件才能唯一識別元素。

語法

@FindBys({
   @FindBy(tagname = "a"),
   @FindBy(linkText = "Search")
})
WebElement lnk;

在上面的示例中,如果滿足所有兩個條件,我們將能夠識別一個 Web 元素。

@FindAll

頁面工廠中的此註解類似於 @FindBys,因為它允許多個搜尋條件。但是,為了唯一地定位元素,需要滿足任何一個條件(條件之間的 OR 條件必須為真)。

語法

@FindAll({
   @FindBy(tagname = "a"),
   @FindBy(linkText = "Search"),
   @FindBy(class = "name"),
})
WebElement btn;

在上面的示例中,如果滿足三個條件中的任何一個,我們將能夠識別一個 Web 元素。

@CacheLookUp

此註解在頁面工廠中用於最佳化執行速度。這通常用於引用測試中經常使用的元素,例如每次每個測試用例都需要使用的使用者憑據。它允許在第一次使用後將常用變數儲存在快取記憶體中。此註解可以與其他頁面工廠註解同時使用。

語法

@CacheLookUp
@FindAll({
   @FindBy(tagname = "a"),
   @FindBy(linkText = "Search"),
   @FindBy(class = "name"),
})
WebElement loginBtn;

initElement()

它是頁面工廠類中的一個靜態方法,用於初始化由 @FindBy 註解識別的所有 Web 元素。

延遲初始化

AjaxElementLocatorFactory 基於頁面工廠中的延遲載入思想來定位操作中的 Web 元素並傳遞超時時間。這通常用於具有 Ajax 元素的應用程式。

頁面工廠和頁面物件模型的區別

頁面工廠和頁面物件之間的區別如下所示:

  • 在頁面工廠中,元素由 @FindBy 識別,而在頁面物件模型中,元素使用 By 識別。
  • 頁面工廠具有頁面物件模型中不存在的延遲初始化的概念。
  • 頁面物件模型是一種設計模式,而頁面工廠是 Webdriver 類中可用的一個類,它有助於實現頁面物件模型。
  • 在頁面物件模型中,每個物件都必須單獨初始化,而在頁面工廠中,initElement() 方法一次初始化所有物件。

示例

在下面的示例中,單擊“新使用者”。

Selenium Page Factory 1

單擊“新使用者”按鈕後,我們將轉到註冊頁面,顯示“歡迎,註冊”文字。

Selenium Page Factory 2

對於以上示例,我們將建立兩個頁面類 - WelcomePage.java 和 RegisterPage.java,其中我們將分別在這些頁面上宣告 Web 元素(使用 @FindBy 註解)以及要對這些元素執行的操作。

我們還將建立測試類 - WelcomePageTest.java,其中將包含實際的測試用例、初始化 WelcomePage 和 RegisterPage 的驅動程式物件以及與該測試用例相關的斷言。所有測試用例都將在同一個 POM 包下。

Selenium Page Factory 3

頁面類 WelcomePage.java 的程式碼實現。

package POM;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class WelcomePage {
   WebDriver driver;
   @FindBy(xpath = "//*[@id='signInForm']/h1")
   WebElement text;
   @FindBy(xpath = "//*[@id='signInForm']/div[3]/a")
   WebElement btn;;
   public WelcomePage(WebDriver driver) {
      this.driver=driver;
      
      // initializing all page objects
      PageFactory.initElements(driver, this);
   }
   public String verifyPageHeading() {
      String getHeadtext = text.getText();
      return  getHeadtext;
   }
   public void clickOnNewUser() {
      btn.click();
   }
}

頁面類 RegisterPage.java 的程式碼實現。

package POM;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class RegisterPage {
   WebDriver driver;
   @FindBy(xpath = "//*[@id='signupForm']/h1")
   WebElement text;
   public RegisterPage(WebDriver driver) {
      this.driver=driver;
      
      // initializing all page objects
      PageFactory.initElements(driver, this);
   }
   public String verifyPageHeading() {
      String getHeadtext = text.getText();
      return  getHeadtext;
   }
}

測試類 WelcomePageTest.java 的程式碼實現。

package POM;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.*;
import java.util.concurrent.TimeUnit;
import static org.testng.Assert.assertEquals;

public class WelcomePageTest {
   WebDriver driver;
   WelcomePage objWelcomePage;
   RegisterPage objRegisterPage;

   @BeforeTest
   public void setup() {

      // Initiate the Webdriver
      driver = new ChromeDriver();

      // adding implicit wait of 12 secs
      driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

      // Opening the webpage
      driver.get("https://tutorialspoint.tw/selenium/practice/login.php");
   }
   @Test(priority = 1)
   public void verifyWelcomePageHeading() {
   
      // object of WelcomePage page class
      objWelcomePage = new WelcomePage(driver);
      String text = objWelcomePage.verifyPageHeading();
      System.out.println("Page heading in Welcome Page: " + text);
      
      // assertions to test case
      assertEquals("Welcome, Login In", text);
   }

   @Test(priority = 2)
   public void moveToRegisterPage() {
      objWelcomePage = new WelcomePage(driver);
      objWelcomePage.clickOnNewUser();
   }

   @Test(priority = 3)
   public void verifyRegisterPageHeading() {
   
      // object of RegisterPage page class
      objRegisterPage = new RegisterPage(driver);
      String text = objRegisterPage.verifyPageHeading();
      System.out.println("Page heading in Register Page: " + text);
      
      // assertions to test case
      assertEquals("Welcome,Register", text);
   }
   @AfterTest
   public void teardown() {
   
      // quitting browser
      driver.quit();
   }
}

pom.xml 中的依賴項。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>org.example</groupId>
   <artifactId>SeleniumJava</artifactId>
   <version>1.0-SNAPSHOT</version>
   <properties>
      <maven.compiler.source>16</maven.compiler.source>
      <maven.compiler.target>16</maven.compiler.target>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
   
   <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
   <dependencies>
      <dependency>
         <groupId>org.seleniumhq.selenium</groupId>
         <artifactId>selenium-java</artifactId>
         <version>4.11.0</version>
      </dependency>
      
      <!-- https://mvnrepository.com/artifact/org.testng/testng -->
      <dependency>
         <groupId>org.testng</groupId>
         <artifactId>testng</artifactId>
         <version>7.9.0</version>
         <scope>test</scope>
      </dependency>
   </dependencies>
</project>

輸出

Page heading in Welcome Page: Welcome, Login In
Page heading in Register Page: Welcome,Register

===============================================
Default Suite
Total tests run: 3, Passes: 3, Failures: 0, Skips: 0
===============================================
Selenium Page Factory 4

在上面的示例中,我們首先在 Welcome 和 Register 頁面上定位了元素,並在頁面類 WelcomePage.java 和 RegisterPage.java 中對它們執行了操作。

在測試類 WelcomePageTest.java 中,我們聲明瞭這些頁面類的物件以設計測試用例的整個流程。

上述實現中使用了 TestNG 測試框架以及頁面工廠。我們在控制檯中獲得了帶有訊息的頁面標題 - “歡迎頁面標題:歡迎,登入”和“註冊頁面標題:歡迎,註冊”。

控制檯中的結果顯示“已執行的測試總數:3”,因為有三個方法:

  • verifyWelcomePageHeading()
  • moveToRegisterPage()
  • verifyRegisterPageHeading()

最後,收到訊息“透過:3”和“程序已完成,退出程式碼為 0”,表示程式碼已成功執行。

結論

本教程全面介紹了 Selenium WebDriver 頁面工廠。我們從頁面工廠的描述開始,逐步講解了頁面工廠的功能、頁面物件模型和頁面工廠之間的區別,並透過一個示例說明了如何將頁面工廠與 Selenium 結合使用。這將使您深入瞭解頁面工廠。建議您持續練習所學內容,並探索與 Selenium 相關的其他知識,以加深理解並拓寬視野。

廣告

© . All rights reserved.