浅谈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的资源管理器是一个单例模式 + 线程池,数据库连接池等资源池一般也用单例模式 + ...
随机推荐
- 14_输出映射2_resultMap
[resultMap] 如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射列表. 1.定义resultMap,(在UserMapper.xm ...
- java中的JSON对象的使用
申明:没工作之前都没听过JSON,可能是自己太菜了.可能在前台AJAX接触到JSON,这几天要求在纯java的编程中,返回JSON字符串形式. 网上有两种解析JSON对象的jar包:JSON-lib. ...
- JavaWeb用户登录功能的实现
大四快毕业了,3年多的时间中,乱七八糟得学了一大堆,想趁找工作之前把所学的东西整理一遍,所以就尝试着做一个完整的JavaWeb系统,这几天试着做了一个用户登录的功能,分享给大家,肯定有很多不完善的地方 ...
- 如何在Ubuntu上创建及管理LXC容器?
将LXC安装到Ubuntu上 $ sudo apt-get install lxc 安装完毕之后,运行lxc-checkconifg工具,检查当前Linux内核支持LXC的情况.要是一切都已被启用,内 ...
- 欢迎使用skymvc框架,简单易用的php框架
skymvc是一款轻量.简单易用的php mvc框架,经过多个项目实践改良. 特点: 1.mvc架构 2.m.v.c之间可以互相调用 3.简单的路由控制 R("/index.php" ...
- apache2.2+PHP5.4.28
搭建apache+php开发环境,apache一路正常安装,但是,下载的php搭建后,配置好apache.php,始终报错“The requested operation has failed!”换了 ...
- 韩顺平_JAVA_视频教程_下载(打开迅雷,直接复制链接地址即可下载)
ed2k://|file|韩顺平.循序渐进学.java.从入门到精通.第0讲-开山篇.avi|37021064|f4fb2fb3db938a642146ccc8f0935fed|h=ao2k3ep7p ...
- sirius的学习笔记(3)
毕业论文什么的终于搞完了,重拾我的python Creating the python skeleton project directory $ mkdir project $ cd project ...
- WPF窗体置于桌面最底层
在WPF中设置窗体的Topmost属性可以将窗体永远置于顶部,但是没有提供Bottommost属性将窗体置底.若果要将窗体置于桌面的最底部,就需要使用Windows API来实现了.解决方案如下: 1 ...
- c# 如何通过反射 获取\设置属性值、
//定义类public class MyClass{public int Property1 { get; set; }}static void Main(){MyClass tmp_Class = ...