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;
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", "输入手机号不合法");
} }
从以上代码看,如果页面元素发生变化,我们在对应类里修改对应元素即可,而操作和业务层流程类及用例都不用改,如果仅是业务流程更改,只需要维护业务层流程类业务脚本,其他几个类都不用改,从而做到了很好的将页面、元素、脚本进行了分离。
关于PageObject & PageFactory的使用,这里仅为读者提供了思路,有兴趣的同学可以继续拓展,笔者能力有限,如果觉得文章好,还请添加关注我哦
Selenium+java - PageFactory设计模式的更多相关文章
- 浅析selenium的PageFactory模式 PageFactory初始化pageobject
1.首先介绍FindBy类: For example, these two annotations point to the same element: @FindBy(id = "foob ...
- 浅析selenium的PageFactory模式
前面的文章介绍了selenium的PO模式,见文章:http://www.cnblogs.com/qiaoyeye/p/5220827.html.下面介绍一下PageFactory模式. 1.首先介绍 ...
- 记我的第二次自动化尝试——selenium+pageobject+pagefactory实现自动化下单、退款、撤销回归测试
需求: 系统需要做下单.退款.撤销的回归测试,有下单页面,所以就想到用selenium做WEB UI 自动化 项目目录结构: common包上放通用的工具类方法和浏览器操作方法 pageobject包 ...
- maven+selenium+java+testng+jenkins自动化测试
最近在公司搭建了一套基于maven+selenium+java+testng+jenkins的自动化测试框架,免得以后重写记录下 工程目录 pom.xml <project xmlns=&quo ...
- Selenium+java - 手把手一起搭建一个最简单自动化测试框架
写在前面 我们刚开始做自动化测试,可能写的代码都是基于原生写的代码,看起来特别不美观,而且感觉特别生硬. 来看下面一段代码,如下图所示: 从上面图片代码来看,具体特征如下: driver对象在测试类中 ...
- selenium第一课(selenium+java+testNG+maven)
selenium介绍和环境搭建 一.简单介绍 1.selenium:Selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包 ...
- 基于java的设计模式入门(1)——为什么要学习设计模式
大年初一,楼主在这里给大家拜年,祝大家码上升职加薪,码上有对象结婚,码上有车有房,幸福安康. 过完年,回学校注册报道之后,大概就要回深圳到公司开始实习了.提高自己,无非就有两种方式,一是看书学习,二是 ...
- Selenium+Java+TestNG环境配置
1. JDK 2.eclipse+TestNG >TestNG安装. Name:testng Location:http://beust.com/eclipse.如图: 3.seleniu ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
随机推荐
- MyBatis:choose标签的用法
<!-- 4.2 choose用法 需求: 在已有的sys_user表中,除了主键id外,我们认为user_name也是唯一的, 所有的用户名都不可以重复.现在进行如下查询:当参数id有值的时候 ...
- SpringBoot工程热部署
SpringBoot工程热部署 1.在pom文件中添加热部署依赖 <!-- 热部署配置 --> <dependency> <groupId>org.springfr ...
- python基础知识五 各类型数据方法补充,转换,分类,编码+坑中菜
3.9各类型数据方法补充,转换,分类,编码,坑中菜 3.9.1数据类型方法补充 1.str:不可变 补充方法 s1.capitalize():首字母大写 s1 = "alex" s ...
- c++小游戏——拯救公主
#include<stdio.h> #include<ctime> #include<time.h> //suiji #include<windows.h&g ...
- C#3.0新增功能08 Lambda 表达式
连载目录 [已更新最新开发文章,点击查看详细] Lambda 表达式是作为对象处理的代码块(表达式或语句块). 它可作为参数传递给方法,也可通过方法调用返回. Lambda 表达式广泛用于: 将 ...
- .NetCore下ES查询驱动 PlainElastic .Net 升级官方驱动 Elasticsearch .Net
1.背景 由于历史原因,笔者所在的公司原有的ES查询驱动采用的是 PlainElastic.Net, 经过询问原来是之前PlainElastic.Net在园子里文档较多,上手比较容易,所以最初作者选用 ...
- 《VR入门系列教程》之20---使用Oculus移动端SDK
使用Oculus移动端SDK 在基于安卓系统的GearVR上开发应用需要用到Oculus的移动端SDK,下面的网址可以下载SDK:http://developer.oculus.com ...
- 小白学python-day04-作业-九九乘法表相关
作业内容: 作业一: 作业二: 作业三: (1) (2) \n换行 \t制表符 end="" 代表打印不换行,双引号里面可以在结果之间加字符. print() 代表换行打印,使用时 ...
- DedeCms常用内容调用标签实例大全
一.调用顶级栏目标签 <a href="{dede:global.cfg_cmsurl/}/" class="ahov">首页</a> ...
- python课堂整理11---函数即变量
一.前向引用 函数即是变量,在调用前要先定义好. def bar(): print('from bar') def foo(): print('from foo') bar() foo() def f ...