使用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设计模式可用于表示页面上的组件。如果自动化测试中的页面包含多个组件,则每个组件都有单独的页面对象,则可以提高可维护性。

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

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

相关推荐
jessezappy18 分钟前
jQuery-Word-Export 使用记录及完整修正文件下载 jquery.wordexport.js
前端·word·jquery·filesaver·word-export
旧林8431 小时前
第八章 利用CSS制作导航菜单
前端·css
yngsqq1 小时前
c#使用高版本8.0步骤
java·前端·c#
小白不太白9501 小时前
设计模式之 模板方法模式
java·设计模式·模板方法模式
Myli_ing2 小时前
考研倒计时-配色+1
前端·javascript·考研
色空大师2 小时前
23种设计模式
java·开发语言·设计模式
余道各努力,千里自同风2 小时前
前端 vue 如何区分开发环境
前端·javascript·vue.js
闲人一枚(学习中)2 小时前
设计模式-创建型-建造者模式
java·设计模式·建造者模式
软件小伟2 小时前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾2 小时前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js