Selenium的PageFactory & PageObject 在大型项目中的应用

出路出路,走出去了,总是会有路的;困难苦难,困在家里就是难。

    因为最近遇到的技术问题一直没找到可行的解决办法,一直在翻看selenium的源代码,之前写测试代码的时候就是拿来即用,写什么功能啊,就按手动的操作步骤去转换,近日看到一个文章,又去wiki上查了查,觉得写的不错就记录下来了。

    在使用selenium做UI测试的时候,往往并不是页面的每个功能我们都要测试,总有一些经常要进行回归的功能,再细致一点的说,有一些节点是我们经常操作的,那么我从项目初期开始就进行自动化测试代码编写的话,我们可以设计适应项目的一套自动化测试代码结构,基本的思路就是对每一个页面都创建一个相应的PageObject类,如果是公共的模板页面当然只建立一个就可以了。这样下来就相当于建立了很多基础页面一样,如果项目开发的过程中还有完整的文档或者足够详细的用户故事,那么就简直太完美了~~因为这样你可以减少很多次的IDE----Browser之间的切换、查找、测试工作,真的方便很多。但是这个看项目而定吧,这种细致入微的文档很多团队似乎都没能做到。但是笔者还是真的希望在产品初期或项目开始的时候有完整的文档给我们这些自动化测试的人员手中,这样可以大大加快我们自动化测试代码的编写。绕的有点远了。。。回归正题,如何做这种一个页面一个基础类的实现呢?最实际的,看代码:

public class PageObject {

	private WebElement searchTypeSng;
	private WebElement fromCity;
	private WebElement toCity;
	private WebElement fromDate;

	public String calDate(int nextDays) {
		// 当前日期加 n 天之后
		Date date = DateUtils.addDays(new Date(), nextDays);
		// 格式化时间格式
		return DateFormatUtils.ISO_DATE_FORMAT.format(date);
	}

	public void searchTrip(WebDriver driver,String from, String to ,String date) {
		BaseUtils.clearAndTypeString(driver,fromCity, from);
		BaseUtils.clearAndTypeString(driver,toCity, to);
		BaseUtils.clearAndTypeString(driver,fromDate, date);
		searchTypeSng.submit();
	}

}

测试执行:

public class UsingPageObject {

	public static void main(String[] args) {

		WebDriver driver = new FirefoxDriver();

		EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver);

		eventDriver.register(new MyWebDriverListener());

		eventDriver.get("http://flight.qunar.com/");

		PageObject object = PageFactory.initElements(driver, PageObject.class);

		String date = object.calDate(30);

		object.searchTrip(driver,"北京", "厦门", date);

	}
}

这个时候就完成对搜索这一功能的冒烟测试,测试执行代码没有使用TestNG,只是直接用了一个main函数。为了写博客简单方便,不推荐大家效仿。

如果还需要测试其它功能和使用其它节点,直接在PageObject类中加入相应的Field即可。

分割线-------------------------------------------------------------------------------------------------分割线

写到这里,如果没用过这个方法的人会越看越晕,现在简单的讲解一下它执行的原理:

在PageObject类中我们创建的Field的名称是和页面有一定的对应关系的,不是随意取的,如果像上面代码这么写,默认的selenium会根据Id最先进行元素查找,如果没有查找到再通过name进行查找,下面的我就不说了,因为你已经想到了。。。如果你担心页面的不规范或者复杂度比较高,容易产生ID,name,Css等的冲突,selenium不能准确的识别元素, 那么请往下看:

selenium还提供了一种注解的方式,还是直接上代码:

public class PageObject {
	private WebElement searchTypeSng;
	@FindBy(name="fromCity")
	private WebElement fromCity;
	@FindBy(name="toCity")
	private WebElement toWhere;
	private WebElement fromDate;

	public String calDate(int nextDays) {
		// 当前日期加 n 天之后 n=30
		Date date = DateUtils.addDays(new Date(), nextDays);
		// 格式化时间格式
		return DateFormatUtils.ISO_DATE_FORMAT.format(date);
	}

	public void searchTrip(WebDriver driver,String from, String to ,String date) {
		BaseUtils.clearAndTypeString(driver,fromCity, from);
		BaseUtils.clearAndTypeString(driver,toWhere, to);
		BaseUtils.clearAndTypeString(driver,fromDate, date);
		searchTypeSng.submit();
	}

}

当你看到这两个annotations的时候,你已经明白了,是的,selenium提供注解的方式对页面的元素进行准确的定位,可以参考的关键字有:className、css、id、linkText、name、partialLinkText、tagName、xpath.

另外selenium还提供了2个关键字,一个是how,另一个是using,如何使用它们就不在这里写了,因为笔者觉得,用这两个关键字更麻烦,理解起来也麻烦。

关于PageObject & PageFactory的使用,就简单的写了这么多,关于PageFactory还有很多知识,我会抽出时间写在下篇文章里,如果有正在使用这种模式的朋友,请多多批评和指点,相互讨论学习。

时间: 2024-06-11 02:08:20

Selenium的PageFactory & PageObject 在大型项目中的应用的相关文章

Selenium的PageFactory在大型项目中的应用

因为最近遇到的技术问题一直没找到可行的解决办法,一直在翻看selenium的源代码,之前写测试代码的时候就是拿来即用,写什么功能啊,就按手动的操作步骤去转换,近日看到一个文章,又去wiki上查了查,觉得写的不错就记录下来了. 在使用selenium做UI测试的时候,往往并不是页面的每个功能我们都要测试,总有一些经常要进行回归的功能,再细致一点的说,有一些节点是我们经常 操作的,那么我从项目初期开始就进行自动化测试代码编写的话,我们可以设计适应项目的一套自动化测试代码结构,基本的思路就是对每一个页

大型项目使用Automake/Autoconf完成编译配置(2)——步步为营

大型项目使用Automake/Autoconf完成编译配置(2)--步步为营 在第一篇里面,我们已经提纲挈领的讲述了操作步骤,整个过程步骤有8步,但其中有5步你只需要简单的敲一个命令即可,只有剩下的三步需要你动手写一些东西,对应上面步骤中的蓝色黑体字部分,而本篇的重点就是如何在大型项目中完成这三歩.   步步为营:三步完成编译配置 [第一步:修改configure.ac文件] 从上面的步骤可以看到,使用autoscan工具扫描后就会生成一个简单的configure.ac文件,这已经是一个完整的c

PHP开发大型项目的一点经验

项目 一.变量 最好是把所有的变量存储在一个数组中,这样在程序的开发中可以带来很多的方便,特别是当程序很大的时候.变量的命名就当适合自己的习惯,不管是用拼音还是英语,至少应当有一定的意义,以便适合记忆.变量的命名尽量规范化,不要与PHP中的关键字相冲突. 二.函数 PHP自带了很多函数,这给我们程序的编写带来了很多的方便.当然,在大型程序中我们往往自己要定义许多个函数,几十甚至上百个.当然在使用了类的程序中就不叫函数了,就应该叫方法,这里暂且不谈类的使用方法.函数多了,难免就会搞混了.有什么方法

大型项目使用Automake/Autoconf完成编译配置(1)——提纲挈领

           大型项目使用Automake/Autoconf完成编译配置 使用过开源C/C++项目的同学们都知道,标准的编译过程已经变成了简单的三部曲:configure/make/make install, 使用起来很方便,不像平时自己写代码,要手写一堆复杂的Makefile,而且换个编译环境,Makefile还需要修改(Eclipse也是这样).   这么好的东东当然要拿来用了,但GNU的Autotool系列博大精深,工具数量又多,涉及的语言也多,要是自己从头看到尾,黄花菜都凉了,项

iOS大型项目解耦方案有难度?BeeHive设计优化来帮助

在2017年在线技术峰会--阿里开源项目最佳实践上,来自天猫的戴鹏带来了BeeHive关于iOS大型项目解耦方案的分享.他从多人开发的问题介绍了业界的三种模块方案,将传统Init与BeeHive Module进行了比较,对BeeHive的架构进行了分析,并对Module Manager和Module的实现进行了详细介绍.   以下内容根据直播视频整理而成.   视频回顾:点击进入 Pdf下载:点击进入   在iOS大型项目中如何抽丝剥茧把对应的需要优化的地方进行优化.多人协作开发中如何避免冲突?

C/C++大型项目错误管理

         在C/C++大型项目中,错误管理在项目中起着举足轻重的作用,以我自己的项目经验以及观摩其他项目,错误管理对项目框架以及开发效率有着很大的影响.对于错误管理的认识大致分为三类: 刚刚开始写程序的新手,满篇程序看不到一处关于返回出错的处理,更不用说出错管理了.说明他没认识到出错管理的重要性 程序中到处都能看到关于出错的处理.认识到了错误,但是处理方式欠缺 程序中几乎不会很明显的看到关于错误的处理.这是错误管理的最高境界.          错误管理,涉及到程序的健壮性,可恢复性,可

大型项目开发:谨慎使用智能指针

智能指针使用上的问题 智能指针的使用太普遍了,它让程序员摆脱了内存管理的恶梦,但实际上智能指针本身也可能引入另一个恶梦.主要包括两个问题点: 性能问题.因为需要引入一些变量(bookkeeping),甚至在多线程下的一些互斥操作,它所带来的性能开销往往比想像的要高.比如以智能指针作为函数参数以及返回值时. 对象释放的时机不明确.比如std::auto_ptr,总让人感觉不明不白.而有时一些循环引用,又会导致内存泄露. 所以即便有了智能指针,程序员还是要认真考虑使用它们的时机. 智能指针的本质是所

大型项目开发: 头文件顺序

经验告诉我们,某些编码实践虽然在C++中完全合法,但是绝对不能应用于大型项目环境中. 大型项目环境下必须有适当的约束,否则很容易变得难以控制并很难维护(摘自<<大规模C++程序设计>>).下面以Chromium中运用的两个Coding Style中定义的头文件顺序为例. 头文件顺序的差异 WebKit/Blink遵循业界标准的定义,其实也是Lakos在<<大规模C++程序设计>>中建议的顺序 : 编译单元对应的头文件 (Related header file

大型项目开发: 隔离 (《大规模C++程序设计》书摘)

书中第六章 隔离. 主要在撰述什么需要定义在头文件?什么应当移到编译单元中? 核心仍然是先区分接口定义与实现细节.实现细节的改变会导致客户代码的重新编译,从逻辑上也表示与客户代码间可能存在着强耦合. 实现细节与隔离 主要考察以下实现细节,它们会在接口中引入实现细节,也是需要考虑进行隔离的内容: 继承 分层 简单的说就是类的成员中有另一个类的实例时,如Foo mFoo. 这个类就会依赖于Foo的定义.而转为持有地址时,即将关系从HasA改为HoldA时,就不存在这个问题.也就是定义为Foo* mF