PageObjects 设计模式

什么是Page Objects(翻译为:页面对象?)…

简单的说,Page Objects是指UI界面上用于与用户进行交互的对象。它可以指整个页面,也可以指Page上的某个区域。Page Objects是你的test code的交互对象,是对实际UI的一种抽象模型化。通过Page Objects可以减少重复代码的编写,例如,很多页面都有同样的header,footer,navigator等部分,如果对这些进行抽象,只写一次就可以在其他地方通用了。

注意PageObjects与Page Objects是不一样的,PageObjects用于特指采用Page Objects进行封装的一种设计模式(Design Pattern),而不仅仅是多一个空格的区别。哈。

如何实现PageObjects设计模式?

一般情况下,对于一个Page Objects对象,它有两个方面的特征:

  • 自身元素(WebElement)
  • 实现功能 (Services)

自身元素很好理解,就是实实在在的页面元素。而Page Object通常也都是实现一定的功能的。就Test的开发人员来说,更关心的是Page Objects它们实现了什么交互功能,而不是其内部的实现,因此,这里的功能与开发人员理解的功能是不一样的

以用户登录为例:在登录界面,点击登录后要么成功,转向首页。要么失败,出现提示出错信息。 
相信这是一个很容易理解的场景吧!
Java Code可能类似如下:

public class LoginPage {//用户名录入框private WebElement usernameBox;//密码录入框private WebElement passwordBox;//提交按钮private WebElement submitButton;public HomePage loginAs(String username, String password) {usernameBox.sendKeys(username);passwordBox.sendKeys(password);submitButton.submit();return new HomePage(...)}public LoginPage loginAsExpectingError(String username, String password) {//  出错的username,password 仍留在LoginPage}public String getErrorMessage() {// 获取错误信息}
}   

从上面可以看出,同时封装了元素以及功能。此处样例,元素是没有初始化的。可以通过类似于driver.findElement()的函数来直接进行初始化,另外WebDriver提供了一个PageFactory用于对PageObjects设计模式进行支持,下面将会讲到。
通过上面的这段代码,也展现出了一个重要的问题,那就是assertion不应该在Page Objects内部,而应该由tests进行处理。Page Objects只是返回需要验证的信息即可。

总结

  • public方法代表Page提供的功能
  • 尽量不要暴露Page的内部细节
  • 不要assertion
  • 方法可以返回其他Page Objects
  • Page Objects不用代表整个页面,可以是任意一个部分
  • 一样的操作,不同的结果应该分开(正确登录,错误登录)

样例

public class LoginPage {private final WebDriver driver;// 用户名录入框private WebElement usernameBox;// 密码录入框private WebElement passwordBox;// 提交按钮private WebElement submitButton;public LoginPage(WebDriver driver) {this.driver = driver;if (!"Login".equals(driver.getTitle())) {throw new IllegalStateException("This is not the login page");}this.usernameBox = driver.findElement(By.id("username"));this.passwordBox = driver.findElement(By.id("passwd"));this.submitButton = driver.findElement(By.id("login"));}public HomePage loginAs(String username, String password) {usernameBox.sendKeys(username);passwordBox.sendKeys(password);submitButton.submit();return new HomePage(driver);}
}

PageFactory

从上面的样例中,有没有发现每个元素都要进行driver.findElement()这样的操作,写起来好累啊,一堆重复性的代码。有没有更好的,更优雅的处理方法呢?org.openqa.selenium.support.PageFactory就是用来负责处理这个的,真Happy! 
下面以百度搜索作为样例场景,搜索一个关键字:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.support.PageFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/**
* @author shenyanchao
* */
public class BaiduSearchPage {public static final Logger LOG = LoggerFactory.getLogger(BaiduSearchPage.class);private WebElement wd;public void searchFor(String keyword) {wd.sendKeys(keyword);wd.submit();}public static void main(String[] args) {WebDriver driver = new HtmlUnitDriver();driver.get("http://www.baidu.com");BaiduSearchPage baiduPage = PageFactory.initElements(driver,BaiduSearchPage.class);LOG.info("before search url is:{}",driver.getCurrentUrl());baiduPage.searchFor("blueshen");LOG.info("after search url is:{}",driver.getCurrentUrl());}
}

运行以上代码,发现已经可以正常运行,结果如下:

......
before search url is:http://www.baidu.com/
......
after search url is:http://www.baidu.com/s?wd=blueshen&rsv_bp=0&rsv_spt=3

可见,搜索后,已经转向了正确的搜索结果页面。然而WebElement是如何初始化的呢?玄机就在BaiduSearchPage baiduPage = PageFactory.initElements(driver,BaiduSearchPage.class);这行代码。PageFactory负责初始化了Page里的元素,amazing,用起来就是这么的优雅。
那么下来,我就要问了:PageFactory是怎么定位元素的呢?

原来PageFactory初始化元素有一个惯例,样例中将WebElement的名称定为wd,那么PageFactory将按类似以下的形式对其进行初始化: 
driver.findElement(By.id("wd"));
PageFactory认为wd是HTML元素的id或者name字段的值,并且优先从id开始查找。至此,我们终于知道怎么回事了。

随着项目的变大,以及使用的更加深入,HTML元素的id,name字段并不一定唯一,并且java Class的属性看起来都是一堆无意义的名称。这些要求我们必须要进行改进。幸好PageFactory已经提前考虑到了这一切,它支持annotations来显式定位元素。那么上述的百度搜索样例,可以修改为如下形式:

public class BaiduSearchPage {public static final Logger LOG = LoggerFactory.getLogger(BaiduSearchPage.class);@FindBy(how = How.NAME, using = "wd")@CacheLookupprivate WebElement serachBox;public void searchFor(String keyword) {serachBox.sendKeys(keyword);serachBox.submit();}
......
}

明确的指定HOW.NAME,using=”wd”,意为查找name=”wd”的元素,并将其初始化赋值给searchBox这一有意义的属性名。其中@CacheLookup用于标识其只初始化一次,然后缓存起来备用。

感觉还不够简洁吗?继续修改:

@FindBy(name = "wd")
private WebElement searchBox;

这是其简略模式,还支持各种定位方式。

    @FindBy(id="...")@FindBy(className="...")@FindBy(name="...")@FindBy(xpath="...")@FindBy(linkText="...")@FindBy(partialLinkText="...")@FindBy(tagName="...")@FindBy(css="...")

同时支持@FindBys用于支持列表元素查找定位,返回List<WebElement>类型。

总之,利用PageObjects设计模式并且配合PageFactory使用,将使你的自动化测试优雅、易懂、易维护。

转载于:https://www.cnblogs.com/111testing/p/7198372.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI与人类围棋士的差距到底有多大?

来源&#xff1a;计算广告四年前&#xff0c;谷歌旗下DeepMind公司开发的围棋人工智能AlphaGo以4-1战胜韩国大国手李世乭九段。今天&#xff0c;AlphaGo在大众视野中掀起的惊涛骇浪已渐平息&#xff0c;AlphaGo和李世乭都已从江湖退隐。然而&#xff0c;围棋界因AlphaGo而起的沧…

mariadb使用mysql驱动_MariaDB安装与使用

下载相对应的电脑版本程序等待下载完成......安装教程&#xff1a;双击运行设置数据库的密码等待安装完成..这样就完成安装了。安装完成&#xff0c;会在桌面生成这个图标双击可以直接使用下面我通过两种方式来使用MariaDB数据库(可视化&#xff0c;命令行)通过可视化方式使用。…

SpringMVC 应用配置

1、增加Spring的支持 新建web项目&#xff0c;添加如下jar包&#xff1a; commons-logging-1.2.jar  spring-aop-4.2.5.RELEASE.jar  spring-aspects-4.2.5.RELEASE.jar  spring-beans-4.2.5.RELEASE.jar spring-context-4.2.5.RELEASE.jar  spring-context-support-4.…

脑机接口技术重大突破!首次帮助瘫痪男子恢复运动和触觉

来源&#xff1a;网易智能触觉是我们感受外部世界不可或缺的感官&#xff0c;但许多人却因脊髓损伤或因患病瘫痪而失去这种能力。不过&#xff0c;最近非营利组织巴特尔研究所的研究人员宣称&#xff0c;他们首次利用脑机接口&#xff08;BCI&#xff09;技术帮助一名美国瘫痪男…

LoadRunner如何调用外部函数

LoadRunner如何调用外部函数 使用 VuGen 时&#xff0c;可以调用在外部 DLL 中定义的函数。通过从脚本调用外部函数&#xff0c;可以降低脚本的内存使用量以及总体运行时间。要调用外部函数&#xff0c;需要加载定义了该函数的 DLL。可以用下列方法加载 DLL&#xff1a; 本地—…

python海龟图画龙珠_火影,海贼王,七龙珠,还在为漫画书发愁!我用Python一键生成电子漫画书...

小时候看漫画都是要买书的&#xff0c;一本好几块钱&#xff0c;成本那个高啊后来可以在线看漫画&#xff0c;感觉真是爽不过近几年新的问题又出现了&#xff1a;漫画网站广告太多&#xff0c;更重要的是越来越多的作品、章节出于各种原因被下架、限制观看。为了提升观看体验&a…

谷歌自揭“家丑”:医疗AI实验室表现超神,临床结果却不佳

来源&#xff1a;澎湃新闻在医疗领域&#xff0c;尤其是在医学影像筛查过程中&#xff0c;人工智能常被描述为完美的工作者。它们能准确识别疾病&#xff0c;拥有人类专家级的发现能力&#xff0c;还不知疲倦。但与许多技术一样&#xff0c;在实验室取得成功是一回事&#xff0…

[openjudge] 2797最短前缀 Trie

描述 一个字符串的前缀是从该字符串的第一个字符起始的一个子串。例如 "carbon"的字串是: "c", "ca", "car", "carb", "carbo", 和 "carbon"。注意到这里我们不认为空串是字串, 但是每个非空串是它自身…

mysql 移植ucos_基于STM32F767的UCOSIII移植学习

(一)移植前的准备1.HAL库基本工程模板新建一个工程模块&#xff0c;其中包含LED驱动和串口驱动程序即可&#xff0c;用于验证UCOS-III系统能够正常工作。2.UCOS-III源码准备去Micrium官网下载最新的UCOSIII源码&#xff0c;下载地址&#xff1a;Micrium官网下载地址&#xff0c…

美国5G到底怎么了?

来源&#xff1a;网优雇佣军美国司法部长威廉巴尔&#xff08;William Barr&#xff09;在2月6日应华盛顿智库“战略与国际研究中心”&#xff08;CSIS, Center for Strategic & International Studies&#xff09;邀请&#xff0c;参加了“中国倡议”会议&#xff08;Chin…

Mysql实现幂等_MQ如何方式消息重复消费--幂等性

一、何为幂等性&#xff1f;其任意多次执行所产生的影响均与一次执行的影响相同从对系统的影响结果来说&#xff1a;At least once 幂等消费 Exactly once。那么如何实现幂等操作呢&#xff1f;最好的方式就是&#xff0c;从业务逻辑设计上入手&#xff0c;将消费的业务逻辑设…

SQL实践篇(一):使用WebSQL在H5中存储一个本地数据库

文章目录 简介本地存储都有哪些&#xff1f;如何使用WebSQL打开数据库事务操作SQL执行 在浏览器端做一个英雄的查询页面如何删除本地存储参考文献 简介 WebSQL是一种操作本地数据库的网页API接口&#xff0c;通过它&#xff0c;我们可以操作客户端的本地存储。 WebSQL曾经是H…

JavaScript之正方教务系统自动化教评[插件-转载]

【声明】本插件系学院学长原创&#xff0c;非博主所创&#xff0c;发布此处&#xff0c;仅供学习和效仿。 /*** name:正方教务系统自动化教评-插件* * author:chenzhongshu* date:2017-07-04* notice:原生js;无需依赖项**/(function() {var courseCode;var timer;var autoFill …

预计2024年之前载人登月!NASA授予马斯克贝索斯公司大单

来源&#xff1a;小小据外媒报道&#xff0c;当地时间周四&#xff0c;美国宇航局(NASA)宣布选中埃隆马斯克(Elon Musk)旗下美国太空探索技术公司SpaceX、杰夫贝索斯(Jeff Bezos)的蓝色起源公司&#xff08;Blue Origin&#xff09;和Dynetics为其设计和建造月球着陆系统&#…

java 遗传算法_[原]遗传算法Java实现源代码

【Title】[原]遗传算法Java实现源代码【Date】2013-04-07【Abstract】以前学习遗传算法时&#xff0c;用Java实现的遗传算法程序&#xff0c;现整理分享出来。【Keywords】wintys、遗传、算法、algorithm、种群、基因、个体、进化、染色体、适应度、Rosenbrock【Environment】W…

防止表单按钮多次提交

1. <form namefm method"POST" action"/"><p>按钮变灰</p>name: <input type"text" name"name"/><input type"button" value"提交" οnclick"javascript:{this.disabledtrue;doc…

理解进化的五座“桥”

来源&#xff1a;原理古往今来&#xff0c;达尔文是不是最具革命性的科学家之一&#xff1f;如果革命指的是把一个已经公认的学说颠倒过来&#xff0c;那挑战者还有很多&#xff0c;至少包括牛顿、爱因斯坦和量子力学的奠基者。这些物理学家超群绝伦的智慧能量&#xff0c;可能…

ACM训练计划建议(转)

ACM训练计划建议 From&#xff1a;freecode# Date&#xff1a;2015/5/20 前言&#xff1a; 老师要我们整理一份训练计划给下一届的学弟学妹们&#xff0c;整理出来了&#xff0c;费了不少笔墨&#xff0c;就也将它放到博客园上供大家参考。 菜鸟之作&#xff0c;大牛勿喷&…

java下载文件夹_java如何通过共享目录下载文件夹(有子文件夹)到本地目录?...

有没有大神会操作的&#xff1f;下面的代码只能下载文件夹下只是文件的&#xff0c;不能下载文件夹下包含子文件夹的文件public static void getShareFile(){System.out.println("开始");NtlmPasswordAuthentication auth new NtlmPasswordAuthentication("192…

【AI】【机器人】AI与机器人的42个终极问题与解答

来源&#xff1a;产业智能官 未来智能实验室的主要工作包括&#xff1a;建立AI智能系统智商评测体系&#xff0c;开展世界人工智能智商评测&#xff1b;开展互联网&#xff08;城市&#xff09;云脑研究计划&#xff0c;构建互联网&#xff08;城市&#xff09;云脑技术和企业图…