浅谈pageobject模式
先来看两段代码
代码1:
package com.zlshuo.selenium.nonaming.pageobject; /**
* @author leshuo
* @version 2014年5月14日
*/
public class AT { public static void main(String[] args){ //获取二手房经纪人电话
String telephoneNum=BasePage.get("http://shanghai.anjuke.com").
serachKeyWords("上海别墅").clickPorpByindex(1).getTelephoneNum(); System.out.println(telephoneNum); //退出driver
BasePage.quit(); }
}
代码2:
package com.zlshuo.selenium.nonaming.pageobject; import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert; /**
* @author leshuo
* @version 2014年5月14日
*/
public class AT1 { private static WebDriver driver;
public static void main(String[] args){ System.setProperty ( "webdriver.chrome.driver" ,
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe" );
WebDriver driver = new ChromeDriver();
driver.get("http://shanghai.anjuke.com");
driver.findElement(By.xpath("//input[@id='glb_search0']")).sendKeys("上海别墅");
driver.findElement(By.xpath("//input[@id='glb_search0']")).submit();
driver.findElement(By.xpath("//a[@id='prop_name_qt_prop_1']")).click();
driver=switchToWindow(2);
String telephoneNum=driver.
findElement(By.xpath("//div[@class='A-fangyuan-call']/p[@class='number']")).
getText();
System.out.println(telephoneNum);
driver.quit(); } public static List<String> getWindowHandlesList() {
Set<String> handles = driver.getWindowHandles();
List<String> list=new ArrayList<String>();
for (String s : handles){
list.add(s);
}
return list;
} public static WebDriver switchToWindow(int index) {
try {
int windowNumber=getWindowHandlesList().size();
if(windowNumber<=0){
Assert.fail("窗口数为0");
}else if(windowNumber==1)
;
else{
return driver.switchTo().window(getWindowHandlesList().get(index-1));
} } catch (NoSuchWindowException e) {
e.printStackTrace();
}
return driver; }
}
这两段代码完成的功能都是一样的:访问安居客搜索"上海别墅",点击搜索结果的第一套房源,获取经纪人的手机号码。
代码1看上去要简洁很多,采用pageobject模式,便于单个用例脚本的编写展示,代码2是用原生的selenium书写,高下立判。代码1用下面这个版本会更加容易理解一点
package com.zlshuo.selenium.nonaming.pageobject; /**
* @author leshuo
* @version 2014年5月14日
*/
public class AT { public static void main(String[] args){ //访问安居客首页
AnjukeHomePage homePage=BasePage.get("http://shanghai.anjuke.com");
//搜索上海别墅二手房
AnjukeSaleListPage listPage=homePage.serachKeyWords("上海别墅");
//点击第一套房源
AnjukeSalePropPage propPage=listPage.clickPorpByindex(1);
//获取房源单页经纪人电话
String telephoneNum=propPage.getTelephoneNum(); System.out.println(telephoneNum); //退出driver
BasePage.quit(); }
}
先来看看BasePage,BasePage是所有页面的父类,其他页面需要继承之,他有两个方法get和quit.get用来初始化driver并访问url,quit用来退出driver,kill浏览器进程
package com.zlshuo.selenium.nonaming.pageobject; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver; /**
* @author leshuo
* @version 2014年5月14日
*/
public class BasePage { private static WebDriver driver; public static AnjukeHomePage get(String url){
System.setProperty ( "webdriver.chrome.driver" ,
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe" );
driver = new ChromeDriver();
driver.get(url);
return new AnjukeHomePage(driver);
} public static void quit(){
driver.quit();
} }
AnjukeHomePage是BasePage.get()返回的页面对象,这里定义为安居客首页,他有一个serachKeyWords方法,用于搜索关键词并返回列表页面
package com.zlshuo.selenium.nonaming.pageobject; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; /**
* @author leshuo
* @version 2014年5月14日
*/
public class AnjukeHomePage extends BasePage{ private WebDriver driver; AnjukeHomePage(WebDriver driver){
this.driver=driver;
} public AnjukeSaleListPage serachKeyWords(String words){
driver.findElement(By.xpath("//input[@id='glb_search0']")).sendKeys(words);
driver.findElement(By.xpath("//input[@id='glb_search0']")).submit();
return new AnjukeSaleListPage(driver);
} }
AnjukeSaleListPage是搜索列表页,此页面展示了搜索出的相关房源信息,我只写了一个选择房源的方法作为例子,点击房源后就进入了房源显示的页面了,所以clickPorpByindex返回的是房源单页对象AnjukeSalePropPage
package com.zlshuo.selenium.nonaming.pageobject; import java.util.ArrayList;
import java.util.List;
import java.util.Set; import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.WebDriver;
import org.testng.Assert; /**
* @author leshuo
* @version 2014年5月14日
*/
public class AnjukeSaleListPage extends BasePage{ private WebDriver driver; public AnjukeSaleListPage(WebDriver driver){
this.driver=driver;
} public AnjukeSalePropPage clickPorpByindex(int index){
driver.findElement(By.xpath("//a[@id='prop_name_qt_prop_"+index+"']")).click();
//切换到新开的窗口
driver=switchToWindow(2);
return new AnjukeSalePropPage(driver);
} private List<String> getWindowHandlesList() {
Set<String> handles = driver.getWindowHandles();
List<String> list=new ArrayList<String>();
for (String s : handles){
list.add(s);
}
return list;
} private WebDriver switchToWindow(int index) {
try {
int windowNumber=getWindowHandlesList().size();
if(windowNumber<=0){
Assert.fail("窗口数为0");
}else if(windowNumber==1)
;
else{
return driver.switchTo().window(getWindowHandlesList().get(index-1));
} } catch (NoSuchWindowException e) {
e.printStackTrace();
}
return driver; }
}
AnjukeSalePropPage只有一个方法即获取经纪人电话
package com.zlshuo.selenium.nonaming.pageobject; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; /**
* @author leshuo
* @version 2014年5月14日
*/
public class AnjukeSalePropPage extends BasePage{ private WebDriver driver; public AnjukeSalePropPage(WebDriver driver){
this.driver=driver;
} public String getTelephoneNum(){
return driver.findElement(By.xpath("//div[@class='A-fangyuan-call']/p[@class='number']")).
getText();
}
}
不难看出,pageobject模式以业务逻辑上的每一步操作作为区分点,页面方法代表了此页面的一个业务操作并严格控制此操作的后续流程,这样做的好处有以下几点:
1.以页面为单位,重复的操作封装在一个方法中,当页面元素或流程变动时只需修改相关页面方法即可,不需要修改相应的脚本
2.测试脚本编写简单,顺着业务逻辑写脚本和手工测试一样的感觉。例如,访问安居客首页->搜索上海别墅->点击搜索结果的第一套房源进入房源单页->获取经纪人手机号码,写成脚本就是BasePage.get("http://shanghai.anjuke.com").serachKeyWords("上海别墅").clickPorpByindex(1).getTelephoneNum(),一气呵成。
3.可以和PageFactory模式一起使用,节约前期开发成本
当然,这些奇淫巧计都是锦上添花之物,真正的着落之处应该在规范流程及提高开发者个人水平这一方面。
先污染后治理的理念是要摒弃的。
浅谈pageobject模式的更多相关文章
- 浅谈MVVM模式和MVP模式——Vue.js向
浅谈MVVM模式和MVP模式--Vue.js向 传统前端开发的MVP模式 MVP开发模式的理解过程 首先代码分为三层: model层(数据层), presenter层(控制层/业务逻辑相关) view ...
- iOS:个人浅谈工厂模式
一.什么是工厂方法? 正式的解释是:在基类中定义创建对象的一个接口,让子类决定实例化哪个类.工厂方法让一个类的实例化延迟到子类中进行.工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好 ...
- 浅谈MVC模式
MVC模式(三层架构模式) (Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...
- 设计模式浅谈----策略模式(c#及java实现)
一.何为策略模式 策略模式是行为型模式的一种,主要用于需要使用不同的算法来处理不同的数据对象时使用,是一种可以在运行时选择算法的设计模式.也称为政策模式. 主要解决:在有多种算法相似的情况下,使用 i ...
- 浅谈MVC模式与MVVM模式的区别
MVC模式: M:Model(数据模型),用于存放数据 V:View(视图),也就是用户界面 C:Controller是Model和View的协调者,Controller把Model中的数据拿过来给V ...
- Swift语言精要 - 浅谈代理模式(Delegate)
在iOS编程中,我们经常谈到代理代理,也就是delegate,那么什么是代理呢? 我们来看一下cocoa对它的描述: Delegation is Cocoa’s term for passing of ...
- 设计模式之——浅谈strategy模式(策略模式)
strategy模式,即策略模式.个人觉得吧,策略模式更多的是一种思维方式. 首先我们要知道,为什么需要策略模式.举个例子,比如用程序输出今天下午去玩什么. PlayGame 玩游戏 package ...
- 浅谈ThreadLocal模式
一.前言: ThreadLocal模式,严格意义上不是一种设计模式,而是java中解决多线程数据共享问题的一个方案.ThreadLocal类是java JDK中提供的一个类,用来解决线程安全问题,并不 ...
- 浅谈单利模式及其应用场景(Python)
python 中的单利模式 使用场景: + Python的logger就是一个单例模式,用以日志记录 + Windows的资源管理器是一个单例模式 + 线程池,数据库连接池等资源池一般也用单例模式 + ...
随机推荐
- js自执行函数表达式
// 下面2个括弧()都会立即执行 (function () { /* code */ } ()); // 推荐使用这个(function () { /* code */ })(); // 但是这个也 ...
- JDBC实现往MySQL插入百万级数据
想往某个表中插入几百万条数据做下测试, 原先的想法,直接写个循环10W次随便插入点数据试试吧,好吧,我真的很天真.... DROP PROCEDURE IF EXISTS proc_initData; ...
- 九度OJ 1042 Coincidence -- 动态规划(最长公共子序列)
题目地址:http://ac.jobdu.com/problem.php?pid=1042 题目描述: Find a longest common subsequence of two strings ...
- clr介绍
CLR(公用语言运行时)和Java虚拟机一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集),并保证应用和底层操作系统之间必要的分离..NET提供了一个运行时环境,叫做公用语言运行时(Comm ...
- localStorage、sessionStorage详解,以及storage事件使用
有关localStorage和sessionStorage的特性. localStorage本身带有方法有 添加键值对:localStorage.setItem(key,value),如果key存在时 ...
- HTML5格式化
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- php 接收二进制流转换成图片
php 接收二进制流转换成图片,图片类imageUpload.php如下: <?php /** * 图片类 * @author http://blog.csdn.net/haiqiao_2010 ...
- MySQL数据库的热备份和冷备份
冷备份(off, 慢, 时间点上恢复)冷备份发生在数据库已经正常关闭的情况下,当正常关闭时会提供给我们一个完整的数据库.冷备份是将关键性文件拷贝到另外位置的一种说法.对于备份数据库信息而言,冷备份是最 ...
- odoo 使用 80 端口
OE安装好,一般需要通过 8069端口来访问. 1:Aapche2 安装 sudo apt-get install apache2 2.安装mod_proxy cd /etc/apache2/mods ...
- REST内容协商注解
@Produces注解: 用于定义方法的响应实体的数据类型.可以定义一个或多个,同时可以为每种类型定义质量因素,质量因素取值范围从0--1的小数值,默认为1. 示例: @Path("conn ...