前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一篇文章学会PageFactory模式

一篇文章学会PageFactory模式

作者头像
软件测试君
发布2019-08-29 13:19:33
2.1K0
发布2019-08-29 13:19:33
举报
文章被收录于专栏:测试人生

前言

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

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

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

一、@FindBy和@CacheLookup用法

元素声明的写法:

代码语言:javascript
复制
    //定位 密码输入框    @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,具体示例代码如下:

代码语言:javascript
复制
import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.support.PageFactory;
/** * @author rongrong * 基础页面 */public class HomePage {
    private static WebDriver driver;
    /***     * 用来传递WebDriver     * @return     */    public static WebDriver driver() {        return driver;    }
    public HomePage() {        //设置系统变量,并设置chromedriver的路径为系统属性值        System.setProperty("webdriver.chrome.driver", "tool/chromedriver.exe");        //实例ChromeDriver        driver = new ChromeDriver();        PageFactory.initElements(driver, this);    }
    /**     * 打开浏览器     */    public void open() {        driver.get("https://i.360kan.com/login");    }
    /**     * 关闭浏览器     */    public void close() {        driver.quit();    }
    public LoginPage loginPage() {        LoginPage loginPage = new LoginPage();        return loginPage;    }
}

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

2、对象层

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

代码语言:javascript
复制
import org.openqa.selenium.WebElement;import org.openqa.selenium.support.CacheLookup;import org.openqa.selenium.support.FindBy;import org.openqa.selenium.support.How;import org.openqa.selenium.support.PageFactory;
/** * @author rongrong * 对象库层代码案例 */public class LoginPage {
    public LoginPage(){        PageFactory.initElements(HomePage.driver(),this);    }
    //定位 用户名输入框    @FindBy(how = How.NAME, using = "loginname")//第一种写法    @CacheLookup    private WebElement userName;
    //定位 密码输入框    @FindBy(name = "loginpassword")//第二种写法    @CacheLookup    private WebElement passWord;
    //定位 登录按钮    @FindBy(linkText = "立即登录")    @CacheLookup    private WebElement loginBtn;
    //定位 提示错误信息    @FindBy(css = "[class='b-signin-error js-b-signin-error error-2']")    @CacheLookup    private WebElement errorMsg;

    public WebElement getUserName() {        return userName;    }
    public WebElement getPassWord() {        return passWord;    }
    public WebElement getLoginBtn() {        return loginBtn;    }
    public WebElement getErrorMsg() {        return errorMsg;    }
    /**     * 用户名输入操作     *     * @param userName     */    public void sendKeysUserName(String userName) {        getUserName().clear();        getUserName().sendKeys(userName);    }
    /**     * 密码输入操作     *     * @param passWord     */    public void sendKeysPassWord(String passWord) {        getPassWord().clear();        getPassWord().sendKeys(passWord);    }}

3、操作层

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

代码语言:javascript
复制
package com.demo;
import org.testng.Assert;
/** * @author rongrong * 操作层代码案例 */public class LoginMovies {
    /***     * 登录过程     * @param userName     * @param pwd     * @param expected     */    public void loginByPageFactory(String userName, String pwd, String expected) {        HomePage homePage = new 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,用来验证登录功能,具体示例代码如下:

代码语言:javascript
复制
import org.testng.annotations.Test;
/** * @author rongrong * 业务层代码案例 */public class TestPageFactory {

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

}

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、@FindBy和@CacheLookup用法
  • 二、PageFactory类使用
  • 三、使用 PageFactory 模式来分离页面元素
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档