Selenium+java - PageFactory设计模式

前言

上一小节我们已经学习了Page Object设计模式,优势很明显,能更好的体现java的面向对象思想和封装特性。但同时也存在一些不足之处,那就是随着这种模式使用,随着元素定位获取,元素定位与页面操作方法都在一个类里维护,会造成代码冗余度过高。

相信使用过spring的同学肯定都知道,基于注解方式的开发,会大大提高开发效率,使代码块变得相对整洁,清晰。

本小节要介绍的就是PageFactory 设计模式,同Page Object思想大体差不多,只是表现形式不太一样,只是通过注解方式来定位元素对象。

一、@FindBy和@CacheLookup用法

元素声明的写法:

    //定位 密码输入框
    @FindBy(name = "loginpassword")
    @CacheLookup
    private WebElement passWord;

注解说明:

@FindBy:这个注解的意思是说我们所查找的元素是以什么方式定位,

@CacheLookup:这个注解的意思是说找到元素之后将缓存元素,重复的使用这些元素,将会大大加快测试的速度。

WebElement passWord:就是变量名

二、PageFactory类使用

PageFactory提供的是静态方法,可以直接调用,一般在用完@FindBy后,需要进行元素初始化,则需要调用initElements(driver,this);方法。

三、使用 PageFactory 模式来分离页面元素

此处演示还沿用page object模式的风格,这里我又加了一层自己暂时定义叫基础层,现在就变成了四层:

  • 基础层:用来存放driver及初始化使用。
  • 对象层:用于存放页面元素定位和控件操作。
  • 操作层:则是一些封装好的功能用例模块。
  • 业务层:则是我们真正的测试用例的操作部分。

下面将举例说明Page Object设计模式,我们还有360影视页面为例,来做进一步讲解。

1、基础层

先创建一个包,名为com.pagefactory.demo,接着在这个包下创建一个类名为HomePage,具体示例代码如下:

import org.openqa.selenium.WebDriver;
 org.openqa.selenium.chrome.ChromeDriver;
 org.openqa.selenium.support.PageFactory;

/**
 * @author rongrong
 * 基础页面
 */
public class HomePage {

    private static WebDriver driver;

    *
     * 用来传递WebDriver
     * @return
     */
     WebDriver driver() {
        return driver;
    }

    public HomePage() {
        设置系统变量,并设置chromedriver的路径为系统属性值
        System.setProperty("webdriver.chrome.driver","tool/chromedriver.exe");
        实例ChromeDriver
        driver = new ChromeDriver();
        PageFactory.initElements(driver,this);
    }

    
     * 打开浏览器
     void open() {
        driver.get("https://i.360kan.com/login"
     * 关闭浏览器
      close() {
        driver.quit();
    }

     LoginPage loginPage() {
        LoginPage loginPage =  LoginPage();
         loginPage;
    }

}

这是我的基础页面,为了让driver抽离出去

2、对象层

接着我们再来创建一个类,名为LoginPage,具体示例代码如下:

 org.openqa.selenium.WebElement;
 org.openqa.selenium.support.CacheLookup;
 org.openqa.selenium.support.FindBy;
 org.openqa.selenium.support.How;
 rongrong
 * 对象库层代码案例
  LoginPage {

     LoginPage(){
        PageFactory.initElements(HomePage.driver(),1)">定位 用户名输入框
    @FindBy(how = How.NAME,using = "loginname")第一种写法
    @CacheLookup
    private WebElement userName;

    定位 密码输入框
    @FindBy(name = "loginpassword")第二种写法
 WebElement passWord;

    定位 登录按钮
    @FindBy(linkText = "立即登录" WebElement loginBtn;

    定位 提示错误信息
    @FindBy(css = "[class='b-signin-error js-b-signin-error error-2']" WebElement errorMsg;


     WebElement getUserName() {
         userName;
    }

     WebElement getPassWord() {
         passWord;
    }

     WebElement getLoginBtn() {
         loginBtn;
    }

     WebElement getErrorMsg() {
         errorMsg;
    }

    
     * 用户名输入操作
     *
     * @param userName
      sendKeysUserName(String userName) {
        getUserName().clear();
        getUserName().sendKeys(userName);
    }

    
     * 密码输入操作
     *
     *  passWord
      sendKeysPassWord(String passWord) {
        getPassWord().clear();
        getPassWord().sendKeys(passWord);
    }
}

3、操作层

接着我们再来创建一个类,名为LoginMovies,用来记录登录的一系列操作,具体示例代码如下:

package com.demo;

 org.testng.Assert;

 rongrong
 * 操作层代码案例
  LoginMovies {

    *
     * 登录过程
     *  userName
     *  pwd
     *  expected
      loginByPageFactory(String userName,String pwd,String expected) {
        HomePage homePage =  HomePage();
        打开登录页
        homePage.open();
        输入用户名
        homePage.loginPage().sendKeysUserName(userName);
        输入密码
        homePage.loginPage().sendKeysPassWord(pwd);
        点击登录
        homePage.loginPage().getLoginBtn().click();
        获取提示语操作
        String msg = homePage.loginPage().getErrorMsg().getText();
        验证输入手机号错误是否提示
        Assert.assertEquals(msg,expected);
        关闭浏览器
        homePage.close();
    }
}

4、业务层

最后我们再来创建一个类,名为TestPageFactory,用来验证登录功能,具体示例代码如下:

 org.testng.annotations.Test;

 rongrong
 * 业务层代码案例
  TestPageFactory {


    
     * 测试登录
     */
    @Test
     textLogin() {
        实例化操作对象
        LoginMovies loginMovies =  LoginMovies();
        登录操作
        loginMovies.loginByPageFactory("your userName","your passWord","输入手机号不合法");
    }


}

从以上代码看,如果页面元素发生变化,我们在对应类里修改对应元素即可,而操作和业务层流程类及用例都不用改,如果仅是业务流程更改,只需要维护业务层流程类业务脚本,其他几个类都不用改,从而做到了很好的将页面、元素、脚本进行了分离。

关于PageObject & PageFactory的使用,这里仅为读者提供了思路,有兴趣的同学可以继续拓展,笔者能力有限,如果觉得文章好,还请添加关注我哦

相关文章

转载地址:https://www.cnblogs.com/mini-monkey/p/12104821...
web自动化测试过程中页面截图相对比较简单,可以直接使用sel...
目录前言一、Selenium简介二、浏览器驱动1.浏览器驱动参考2....
一、iframe的含义:iframe是HTML中框架的一种形式,在对界面...
转载请注明出处❤️作者:测试蔡坨坨原文链接:caituotuo.to...
'''##**认识selenium**​**下载:pipinstall...