Selenium 简明教程

Selenium WebDriver - Page Object Model

通过在自动化测试中采用设计模式,可以改进使用 Selenium Webdriver 开发的测试用例。页面对象模型(也称为 POM)是最常用的设计模式之一,可用于使用 Selenium Webdriver 创建自动化测试。

The test cases developed using Selenium Webdriver can be improved by adopting design patterns in the automated tests. Page Object Model (also known as POM) is one most commonly used design pattern which can be used to create automated tests with Selenium Webdriver.

What is a Page Object Model?

页面对象模型是一种设计模式,在 Selenium 测试用例开发中用于将网页元素和测试用例分离在不同的类文件中。页面对象类似于面向对象的类,类似于测试应用程序的界面。

Page Object Model is a design pattern which is adopted in Selenium test case development for segregation of the web elements and test cases in different class files. A page object is similar to an object oriented class which is similar to an interface of the application under test.

实际测试用例使用对象类的类方法与 Web 应用程序进行交互。在开发测试用例后,如果未来网页元素的任何属性发生更改,则只需在页面对象级别进行必要的更改,而无需在测试用例级别进行更改。

The actual test cases make use of the methods of the object classes to interact with the web application. After a test case has been developed, in future if any property of the web elements get changed, then necessary changes would only need to be made at the page object level and not at the test case level.

同样,如果已将新的 Web 元素添加到应用程序的网页中,则应首先将其添加到声明所有对象的页面级别的唯一专用位置。

Likewise, if a new web element has been added to a web page in application, that should be first added to the one and only dedicated place where all the objects are declared at the page level.

在根据 Page Object Model 设计测试用例时,应用程序的每个页面都被认为是一个独立的类文件。在该独立的类文件中,将提供所有该页面特定的 Web 元素。

While designing test cases based on Page Object Model, each page in the application is considered as a separate class file. Within that independent class file, all the web elements specific to that page, will be available.

测试用例的验证和断言保存在特定的测试类文件中,而不是保存在页面对象类文件中。因此,任何类文件之间不存在相互依赖关系。

Verifications and Assertions for a test case are maintained in the particular test class file and not on the page object class file. Thus there is no interdependence between any class files.

Benefits of Using Page Object Model

使用 Page Object Model 的好处如下:

The benefits of using a Page Object Model are listed below −

  1. There is a proper distinction among code written for test cases, features specific to a page, locators for the web elements, and so on.

  2. Page Object Model provides something similar to an object repository, where all the web elements and the actions to be performed on them are stored at a particular place, rather than being declared in multiple places within the test cases.

  3. In case, a change in property of a web element is seen, modifications specific to that element need to be made only at a single place, rather than multiple places. Thus it is easy for maintenance purposes.

  4. As separate and independent class files are maintained, the test code developed for a page, can be reused for another test case. Hence saving a lot of resources.

  5. As separate and independent class files are developed as per the web pages on the application, it makes the code very readable and clean by just going through the class files.

  6. Every distinctive web element is declared only once.

Example

单击欢迎页面上的“新用户”按钮。

Click on the New User button on the Welcome Page.

selenium page object model 1

点击 New User 后,我们将导航到注册页面,其中包含文本 Welcome, Register

After clicking New User, we would navigating to the Registration page, with text Welcome, Register.

selenium page object model 2

在这里,我们将拥有页面类 - WelcomePage.java 和 RegisterPage.java,它们将包含这些两个页面上的 Web 元素和这些元素上的操作。我们还将拥有测试类 - WelcomePageTest.java,它将是实际的测试用例,并且还与测试用例相关的断言。所有测试类都驻留在同一个 POM 包中。

Here, we would have the page classes - WelcomePage.java and RegisterPage.java which would contain web elements on these two pages and actions on those elements. We would also have the test class - WelcomePageTest.java which would be the actual test case, and also assertions related to the test case. All the test classes reside within the same POM package.

selenium page object model 3

页面类 WelcomePage.java 上的代码实现。

Code Implementation on page class WelcomePage.java.

package POM;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class WelcomePage {
   WebDriver driver;
   By text = By.xpath("//*[@id='signInForm']/h1");
   By btn = By.xpath("//*[@id='signInForm']/div[3]/a");
   public WelcomePage(WebDriver driver) {
      this.driver=driver;
   }
   public String verifyPageHeading() {
      String getHeadtext = driver.findElement(text).getText();
      return  getHeadtext;
   }
   public void clickOnNewUser() {
      driver.findElement(btn).click();
   }
}

代码实现 - RegisterPage.java。

Code Implementation - RegisterPage.java.

package POM;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class RegisterPage {
   WebDriver driver;
   By text = By.xpath("//*[@id='signupForm']/h1");
   public RegisterPage(WebDriver driver) {
      this.driver=driver;
   }
   public String verifyPageHeading() {
      String getHeadtext = driver.findElement(text).getText();
      return  getHeadtext;
   }
}

代码实现 - WelcomePageTest.java。

Code Implementation - 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://www.tutorialspoint.com/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 中的依赖项。

Dependencies in 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
===============================================

Process finished with exit code 0
selenium page object model 4

在这里,我们首先识别了 Welcome 和 Register 页面上的元素,并在页面类 - WelcomePage.java 和 RegisterPage.java 中对这些 Web 元素执行了操作。

Here, we had first identified the elements on Welcome and Register pages and performed actions on those web elements inside the page classes - WelcomePage.java and RegisterPage.java.

在测试类 WelcomePageTest.java 中,我们创建了页面类的对象,以通过断言来完成测试用例的完整流程。

Inside the test class WelcomePageTest.java, we had created objects of the page classes to have the complete flow of the test case with assertions.

我们使用了 TestNG 测试框架来实现 Page Object Model,并使用控制台中的消息检索页面标题 - Page heading in Welcome Page: Welcome, Login In and Page heading in Register Page: Welcome,Register

We had used the TestNG test framework to implement the Page Object Model and retrieved the page headers with the message in the console - Page heading in Welcome Page: Welcome, Login In and Page heading in Register Page: Welcome,Register.

控制台中的输出显示 Total tests run: 3 ,因为有三个方法具有 @Test 注释 - verifyWelcomePageHeading()、moveToRegisterPage() 和 verifyRegisterPageHeading()。

The output in the console shows Total tests run: 3, since there are three methods having the @Test annotations - verifyWelcomePageHeading(), moveToRegisterPage(), and verifyRegisterPageHeading().

最后,接收到消息 Passes: 3Process finished with exit code 0 ,表示代码执行成功。

Finally, the message Passes: 3, and Process finished with exit code 0 was received, signifying successful execution of the code.

Conclusion

这结束了我们对 Selenium Webdriver Page Object Model 教程的全面介绍。我们从描述 Page Object Model 开始,然后了解了 Page Object Model 的好处,以及一个示例说明如何将其与 Selenium 一起使用。这使你对 Page Object Model 有了深入的了解。明智的做法是不断练习你学到的知识,并探索与 Selenium 相关的其他知识,以加深你的理解并拓展你的视野。

This concludes our comprehensive take on the tutorial on Selenium Webdriver Page Object Model. We’ve started with describing a Page Object Model and walked through the benefits of a Page Object Model, and an example illustrating how to use it along with Selenium. This equips you with in-depth knowledge of the Page Object Model. It is wise to keep practicing what you’ve learned and exploring others relevant to Selenium to deepen your understanding and expand your horizons.