selenium +python之Page Obiect设计模式
PageObject是selenium自动化测试项目开发实践的最佳设计模式之一,它主要体现对界面交互细节的封装,这样可以使测试案例更关注于业务而非界面细节,从而提高测试案例的可读性。
1.认识PageObject
PageObject设计模式的优点如下:
*减少代码的重复
*提高测试用例的可读性
*提高测试用例的可维护性,特别针对UI频繁变动的项目。
当为web页面编写测试是,需要操作该web页面上的元素。然而,如果在测试代码中直接操作HTML元素,代码是及其脆弱的,因为ui的变动性会很大。我们可以将page对象封装成一个HTML页面,然后通过提供应用程序特定的API来操作页面元素。而不是在HTML中来定位。
page对象的一个基本经验法则是:凡是人能够做的事,page对象通过软件客户端都能够做到。因此,他应该提供一个易于编程的接口并隐藏窗口底层的部件。所以访问一个文本框应该通过一个访问方法(accessor method)来实现字符串的获取与返回,复选框应当使用布尔值,按钮应当被表示为行为导向的方法名。page对象应当将在GUI控件上所有查询和操作数据的行为封装为方法
一个好的经验法则是:即使改变具体的控件,page对象的接口也不应当发生改变
尽管该术语是:“页面”对象,但是并不意味着需要针对每个页面建立一个这样的对象。例如:页面有重要意义的元素可以独立为一个page对象。经验法则的目的是通过给页面建模,时期对应用程序的使用者变得更有意义。
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep class Page(object):
"""
基础类,用于页面对象类的继承
"""
login_url = 'http://mail.163.com/' def __init__(self, selenium_driver, base_url=login_url):
self.base_url = base_url
self.driver = selenium_driver
self.timeout = 30 def on_page(self):
return self.driver.current_url == (self.base_url + self.url) def _open(self, url):
url = self.base_url + url
self.driver.get(url)
assert self.on_page(), 'Did not land on %s' % url def open(self):
self._open(self.url) def find_element(self, *loc):
return self.driver.find_element(*loc) class LoginPage(Page):
"""
126邮箱登陆页面模型
"""
url = '/'
# 定位器
username_loc = (By.ID, "idInput")
password_loc = (By.ID, "pwdInput")
submit_loc = (By.ID, "loginBtn") # Action
def type_username(self, username):
self.find_element(*self.username_loc).send_keys(username) def type_password(self, password):
self.find_element(*self.password_loc).send_keys(password) def submit(self):
self.find_element(*self.submit_loc).click() def test_user_login(driver, username, password):
"""
测试获取的用户名/密码是否可以登陆
"""
login_page = LoginPage(driver)
login_page.open()
login_page.type_username(username)
login_page.type_password(password)
login_page.submit() def main():
try:
driver = webdriver.Chrome()
username = 'fengyiru6369@163.com'
password = '********'
test_user_login(driver, username, password)
sleep(3)
text = driver.find_element_by_xpath("//span[@id = 'spnUid']").text
assert (text == 'fengyiru6369@163.com'), "用户名称不匹配,登陆失败!"
finally:
# 关闭浏览器窗口
driver.close() if __name__ == '__main__':
main()
代码解释如下:
1、创建page类
class Page(object):
"""
基础类,用于页面对象类的继承
"""
login_url = 'http://mail.163.com/' def __init__(self, selenium_driver, base_url=login_url):
self.base_url = base_url
self.driver = selenium_driver
self.timeout = 30 def on_page(self):
return self.driver.current_url == (self.base_url + self.url) def _open(self, url):
url = self.base_url + url
self.driver.get(url)
assert self.on_page(), 'Did not land on %s' % url def open(self):
self._open(self.url) def find_element(self, *loc):
return self.driver.find_element(*loc)
首先创建一个基础类Page,在初始化方法__init__()中定义驱动(driver),基本的URL(base_url)和超时时间(timeout)等,定义open()方法用于打开URL网站,但是它本身并未做这件事情,而是交由
_open()方法来实现。关于Url地址的断言部分,则交由on_page()方法来实现,而find_element()方法用于元素的定位。
2.创建LoginPage类
Page类中定义的这些方法都是页面操作的基本方法。下面根据登陆页的特点再创建LoginPage类并继承page类,这也是page object设计模式中最重要的对象层。
class LoginPage(Page):
"""
126邮箱登陆页面模型
"""
url = '/'
# 定位器
username_loc = (By.ID, "idInput")
password_loc = (By.ID, "pwdInput")
submit_loc = (By.ID, "loginBtn") # Action
def type_username(self, username):
self.find_element(*self.username_loc).send_keys(username) def type_password(self, password):
self.find_element(*self.password_loc).send_keys(password) def submit(self):
self.find_element(*self.submit_loc).click()
LoginPage类中主要对登陆页面上的元素进行封装,使其成为更具体的操作方法。例如,用户名,密码和登陆按钮都被封装成了方法。
3.创建test_user_login()函数
def test_user_login(driver, username, password):
"""
测试获取的用户名/密码是否可以登陆
"""
login_page = LoginPage(driver)
login_page.open()
login_page.type_username(username)
login_page.type_password(password)
login_page.submit()
test_user_login()函数将单个的元素操作组成一个完整的动作,而这个动作包含了打开浏览器,输入用户名/密码,点击登陆等单步操作。在使用该函数时需要将driver,username、password等信息作为函数的入参,这样该函数具有很强的可重用性。
4.创建main()函数
def main():
try:
driver = webdriver.Chrome()
username = 'fengyiru6369@163.com'
password = '********'
test_user_login(driver, username, password)
sleep(3)
text = driver.find_element_by_xpath("//span[@id = 'spnUid']").text
assert (text == 'fengyiru6369@163.com'), "用户名称不匹配,登陆失败!"
finally:
# 关闭浏览器窗口
driver.close() if __name__ == '__main__':
main()
main()函数更接近于用户的操作行为,对用户来说,要进行邮箱登陆,需要关心的就是通过哪个浏览器打开邮箱网址,登陆的用户名和密码是什么,至于输入框,按钮时如何定位的,则不需要关心。
这样分层的好处是,不同的层关心不同的问题。页面对象层只关心元素定位的问题,测试用例只关心测试数据。
一个有分歧的地方是page对象是否应自身包含断言,或者仅仅提供数据给测试脚本来设置断言。在page对象中包含断言的倡导者认为,这又助于避免在测试脚本中出现重复的断言,可以更容易的提供更好的错误信息,并且提供更接近只做不问风格的API。不在page对象中包含断言的倡导者认为,包含断言会混合访问页面数据和实现断言逻辑的职责,并且导致page对象过于臃肿。
在page对象中不包含断言,虽然我们可以通过为常用的断言提供断言库的方式来消除重复,提供更好的诊断,但从用户的角度去自动化的观点来看,判断是否登陆成功是用户需要做的事情,不该交由页面对象层来完成。
使用page object模式之后的另外一个好处就是有助于降低冗余。如果需要在10个用例中输入不同的用户名/密码登陆,那么main()方法竟会变得非常简洁。
selenium +python之Page Obiect设计模式的更多相关文章
- python+ selenium&APPium自动化 page Object 设计模式
题记: 之前公司项目比较稳定, 在进行了系统测试,想用自动化测试进行冒烟测试,或者对主要功能进行测试, 因此用到了PO模式 因此做个记录: Page Object Page Object模式是使用Se ...
- selenium+Python(Page Object 设计模式实例)
以下实例演示了采用了page Object设计模式的方式登录qq空间: 1.创建基础类page:在初始方法__init__()定义驱动的(driver),基本url(base_url)和超时时间(ti ...
- Selenium+Python :WebDriver设计模式( Page Object )
Page Object 设计原理 Page Object设计模式是Selenium自动化测试项目的最佳设计模式之一,强调测试.逻辑.数据和驱动相互分离. Page Object模式是Selenium中 ...
- Python+selenium之Page Object设计模式
Page Object是selenium自动化测试项目开发实践的最佳设计模式之一,他主要提现在对界面交互细节的封装,这样可以使测试案例隔你给加关注于业务而非界面细节,从而提高测试案例的可读性. Pag ...
- web端自动化——selenium Page Object设计模式
Page Object设计模式的优点如下: ① 减少代码的重复. ② 提高测试用例的可读性. ③ 提高测试用例的可维护性,特别是针对UI频繁变化的项目. 当为Web页面编写测试时,需 ...
- Page Object Model (Selenium, Python)
时间 2015-06-15 00:11:56 Qxf2 blog 原文 http://qxf2.com/blog/page-object-model-selenium-python/ 主题 Sel ...
- Selenium自动化测试Python五:WebDriver设计模式
WebDriver 设计模式 欢迎阅读WebDriver进阶讲义.本篇讲义将会重点介绍Selenium WebDriver 自动化框架的设计,着重使用Page Object设计模式,以及使用HTML测 ...
- Selenium+java - Page Object设计模式
前言 Page Object(页面对象)模式,是Selenium实战中最为流行,并且被自动化测试同学所熟悉和推崇的一种设计模式之一.在设计测试时,把页面元素定位和元素操作方法按照页面抽象出来,分离成一 ...
- Selenium(十九):unittest单元测试框架(五) Page Object设计模式
1. Page Object设计模式 Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,它主要体现在对界面交互细节的封装,这样可以使测试方案更关注于业务而非界面细节.从 ...
随机推荐
- 错误: 实例 "ahwater-linux-core" 执行所请求操作失败,实例处于错误状态。: 请稍后再试 [错误: Exceeded maximum number of retries. Exceeded max scheduling attempts 3 for instance 7c1609c9-9d0f-4836-85b3-cefd45f942a7. Last exception: [u
错误: 实例 "ahwater-linux-core" 执行所请求操作失败,实例处于错误状态.: 请稍后再试 [错误: Exceeded maximum number of ret ...
- <正则吃饺子> :关于oracle 中 with的简单使用
oracle中 with的简单使用介绍,具体可以参见其他的博文介绍,在这里只是简单的介绍: with 构建了一个临时表,类似于存储过程中的游标,我是这么理解的. 一.数据准备: select * fr ...
- 21.运行Consent Page
服务端把这个地方修改为true,需要设置 运行测试.服务端和客户端都运行起来 我们使用的用户是在这里配置的 服务端修改ConsentController 再次运行,但是页面都是乱码 openId和pr ...
- QDUOJ 炸老师与他的女朋友们 bfs+状压
炸老师与他的女朋友们 Description qdu最帅的炸老师今天又要抽空去找他的女朋友们了,但是考虑到他的好gay友ycb仍是个单身狗,炸老师作为基友不希望打击他.所以他在找女朋友们的路途中必须要 ...
- logging 模块使用
1. logging 1.1 什么是 logging logging 模块是 Python 内置的日志管理模块,不需要额外安装. 使用: import logging logging.critical ...
- 【Java面试题系列】:Java基础知识常见面试题汇总 第一篇
文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后,一般都会让先做一份笔试题,然后公司会根据笔试题的回答结果,确定 ...
- apply的使用技巧
1.什么是apply?他和call有什么区别? apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性. Function.apply(obj,args)方法能接收两个参数 obj:这个对象 ...
- git从远程仓库gitLab上拉取指定分支到本地仓库
例如:将gitLab 上的dev分支拉取到本地 1>与远程仓库建立连接:git remote add origin XXXXX.git 2>使用git branch 查看本地是否具有dev ...
- node.js安装与配置
node.js是一个基于Chrome V8引擎的javascrit运行环境. node.js使用了一个事件驱动.非阻塞式I/O的模型,使其轻量又高级. node.js的包管理器npm,是全球最大的开源 ...
- 分享| 语义SLAM的未来与思考(泡泡机器人)
相比典型的点云地图,语义地图能够很好的表示出机器人到的地方是什么,机器人“看”到的东西是什么.比如进入到一个房间,点云地图中,机器人并不能识别显示出来的一块块的点云到底是什么,但是语义地图的构建可以分 ...