一篇文章学会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; 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,具体示例代码如下: 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,用来记录登录的一系列操作,具体示例代码如下: 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,用来验证登录功能,具体示例代码如下: import org.testng.annotations.Test; /** * @author rongrong * 业务层代码案例 */ public class TestPageFactory { /** * 测试登录 */ @Test public void textLogin() { //实例化操作对象 LoginMovies loginMovies = new LoginMovies(); //登录操作 loginMovies.loginByPageFactory("your userName", "your passWord", "输入手机号不合法"); } }
从以上代码看,如果页面元素发生变化,我们在对应类里修改对应元素即可,而操作和业务层流程类及用例都不用改,如果仅是业务流程更改,只需要维护业务层流程类业务脚本,其他几个类都不用改,从而做到了很好的将页面、元素、脚本进行了分离。
关于交友的数量与质量晓风残月,子夜沉思朋友靠质量,不靠数量。人生走着走着自己都不知是什么时候,发现好多社交是无用的的?记得,在读大学的时候,常常约几个同学,一起吃吃喝喝,喜欢醉后的无话不说。那时候起码
佟丽娅陈思诚婚变对婚姻的反思佟丽娅陈思诚离婚了,网上在沸腾了,对此我有如下不怎么深刻的对婚姻的反思。欢迎有智者交流。其实离婚肯定是当事人的事,旁观者没必要说三道四,也无权给他人定义裁判对与错。婚姻是否适合永远
惬意于南山图书馆里的缱绻时光人生最好的旅行,就是空间之余进入一个无人打扰的地方,发现一种久违的感动,一个幽静的图书馆,或者你搬到一个新的小区,邻里之间谁也不认识,出门进门不用打招呼,谁也不知道你是谁,这种感觉
18决赛最后一战,这道世界杯下酒菜了解一下世界杯淘汰赛进行到一半,夺冠热门纷纷回家,巴墨之战赛前还在猜测,内马尔会不会步梅老板和总裁的后尘。五星王者巴西迎战北美之王墨西哥,结果令人振奋,内马尔稳得一比!一进球一助攻,直接促
吸睛能力MAX,XESS亮相CES2019,多款生态链产品惊艳世界作为CES展的常驻实力派,TCL在今年展会上不仅推出了X10QLED8KTV等在内的多款电视新品,也将XESS生态链产品带上了国际舞台。作为TCL的高端子品牌,XESS旗下首款产品
穷人装富人,富人装穷人,一个伪装的世界多精彩穷人装富人,富人装穷人,这世界伪装何时了。层次决定人意识与思维。穷人穷久了,所处圈层多属同类。他们日夜做梦都是一夜暴富,但谈何容易,正如一句网络流行语晚上想起千条路,早上起来走原路
苏宁818电脑数码榜单国产品牌狂吸眼球,华为音箱突然大卖距离8月18日苏宁发烧购物节的时间越来越短,苏宁各大版块的人气也越来越旺盛,各大品牌各款产品的重磅优惠接连放出,广大消费者更是剁手到停不下来。而值得注意的是,电脑数码版块一直以来都
苏宁全民焕新节悟空榜GSHOCK王者荣耀联名款手表热卖春天可以没有新潮的发色,也可以没有精致的美甲,但一定要有漂亮的服装首饰。苏宁全民焕新节,其优惠力度堪称上半年的双11,此外还有新品扎堆上市,315品质服务保障,让消费者的购物体验得
苏宁618空调销量榜柜机销量奥克斯首次夺冠空调是夏天最为重要的降温神器,眼看气温越来越高了,这一家电也迎来热销。苏宁作为中国最大的家电渠道,在618刚开始的时候就迎来了一次空调购买大热潮,不仅有打破历史价的空调爆款,还有各
摄影游戏样样精通,双十一还没到我为什么着急下手这台双屏神器?毫无疑问,对于剁手党来讲双十一一定是最值得期待的,进入十一月,不仅是京东淘宝还是苏宁,不管是快消家电还是手机电脑只有一个主题,那就是买买买!可以说这是目前败家味道最浓的一个节了,错
苏宁焕新节手机悟空榜华为后来居上勇夺安卓阵营双料冠军自第一届苏宁315全民焕新节启幕以来,以数码3C为代表的品类集体爆发,销量呈井喷趋势。尤其苏宁易购特为焕新节启动了悟空榜,每日公布全品类的详细销售实况后,各品牌商家更是打了鸡血般疯