使用Selenium-PO设计模式提高Web自动化测试效率

PO(page object)设计模式是在自动化中已经流行起来的一种易于维护和减少代码的设计模式。在自动化测试中,PO对象作为一个与页面交互的接口。测试中需要与页面的UI进行交互时,便调用PO的方法。这样做的好处是,如果页面的UI发生了更改,那么测试用例本身不需要更改,只需更改PO中的代码即可。

PO设计模式具有以下优点:

1、测试代码与页面的定位代码(如定位器或者其他的映射)相分离。

2、该页面提供的方法或元素在一个独立的类中,而不是将这些方法或元素分散在整个测试中。

这允许在一个地方修改由于UI变化所带来的所有修改。

通过一个简单的示例来说明页面对象。首先,思考一个不使用PO模式的自动化测试的典型案例:

python 复制代码
/***
 * Tests login feature
 */
public class Login {
 
  public void testLogin() {
    // 在登录页面上填写登录数据
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();
 
    // 登录后验证h1标签是否为Hello userName
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}

这种方法有两个问题。

1、测试方法与定位器 (在此实例中为By.name)耦合过于严重。如果测试的用户界面更改了其定位器或登录名的输入和处理方式,则测试本身必须进行更改。

2、在对登录页面的所有测试中,同一个定位器会散布在其中。

可以在以下登录页面的示例中应用PO设计模式重写此示例。

python 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
 
/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;
 
  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");
 
  public SignInPage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }
 
  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}

Home page的PO如下所示。

python 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
 
/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;
 
  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");
 
  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }
 
  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }
 
  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* 提供登录用户主页所代表的服务的更多方法. 这些方法可能会返回更多页面对象.
  例如, 单击"撰写邮件"按钮可以返回ComposeMail类对象 */
}

那么,接下来的登录测试用例将使用这两个页面对象。

python 复制代码
/***
 * Tests login feature
 */
public class TestLogin {
 
  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }
 
}

PO的设计方式具有很大的灵活性,但是有一些基本规则可以使测试代码具有理想的可维护性。

PO本身绝不应进行判断或断言。判断和断言是测试的一部分,应始终在测试的代码内,而不是在PO中。PO用来包含页面的表示形式,以及页面通过方法提供的服务,但是与PO无关的测试代码不应包含在其中。

实例化PO时,应进行一次验证,即验证页面以及页面上可能的关键元素是否已正确加载。在上面的示例中,SignInPage和HomePage的构造函数均检查预期的页面是否可用并准备接受测试请求。

PO不一定需要代表整个页面。PO设计模式可用于表示页面上的组件。如果自动化测试中的页面包含多个组件,则每个组件都有单独的页面对象,则可以提高可维护性。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关推荐
捕鲸叉13 分钟前
C++软件设计模式之外观(Facade)模式
c++·设计模式·外观模式
小小小妮子~28 分钟前
框架专题:设计模式
设计模式·框架
先睡29 分钟前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
黑客老陈34 分钟前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
正小安39 分钟前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite
互联网杂货铺1 小时前
Postman接口测试:全局变量/接口关联/加密/解密
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·postman
暴富的Tdy1 小时前
【CryptoJS库AES加密】
前端·javascript·vue.js
neeef_se1 小时前
Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作
前端·vue.js·excel
m0_748235611 小时前
web 渗透学习指南——初学者防入狱篇
前端