Python+Selenium笔记(十三):Page Object设计模式
(一) 前言
简单的说就是分为2层,页面class 和测试class。
页面class:分为父类和子类(子类指具体的页面,每一个页面都创建一个类),父类中定义公有的属性和方法(操作)。
#对面向对象有了解的,应该很容易理解抽象出公有属性和方法的意思
#父类和子类我是按自己的理解进行描述的,或者可以说basepage对象(父对象,提供公有的属性、方法) 和 page对象(具体哪一个页面)
测试class:按照业务流程,对各个页面的属性、操作进行组合,形成一个测试用例。
使用page object模式,抽象出各个页面的元素、方法,然后再按照测试用例的要求进行组合。这样做的好处是
1、页面修改了,只要对页面类进行修改就好了,对测试类(测试用例)没太大影响
2、可以在多个测试复用部分代码。
3、测试代码(测试类、测试用例)部分变得更易读、灵活、可维护。
我把上一篇的代码按照page object模式修改了下,代码如下。
(二) 父类(BasePage对象,base.py)
from abc import abstractclassmethod
class BasePage(object):
def __init__(self,driver):
self.driver = driver '''验证页面是否是指定的页面。
@abstractclassmethod修饰符指该方法是抽象的'''
@abstractclassmethod
def validate_page(self,driver):
return
(三) 首页(page对象(子类),homepage.py)
from base import BasePage
class HomePage(BasePage):
#用来定位页面元素的ID、NAME、XPTH、CSS表达式等
_login_area = '#login_area'
_register = '注册' def validate_page(self,driver):
return driver.title == '博客园 - 开发者的网上家园'
#定位并点击 注册
def register_click(self):
self.login_area = self.driver.find_element_by_css_selector(self._login_area)
self.login_area.find_element_by_link_text(self._register).click()
(四) 注册页面(page对象(子类),registerpage.py)
from base import BasePage
class RegisterPage(BasePage):
# 用来定位页面元素的ID、NAME、XPTH、CSS表达式等
_user_email = 'Email'
_user_phone_country = 'CountryCode'
_user_phone = 'PhoneNum'
_user_login_name = 'LoginName'
_user_nickname = 'DisplayName'
_user_password = 'Password'
_user_confirm_password = 'ConfirmPassword'
_phone_error = 'PhoneNum-error'
_loginName_error = 'LoginName-error' def validate_page(self,driver):
return driver.title == '用户注册 - 博客园' #输入注册信息
def send_keys(self,email,phone,login_name,nickname,password,confirm_password):
self.driver.find_element_by_id(self._user_email).clear()
self.driver.find_element_by_id(self._user_phone).clear()
self.driver.find_element_by_id(self._user_login_name).clear()
self.driver.find_element_by_id(self._user_nickname).clear()
self.driver.find_element_by_id(self._user_password).clear()
self.driver.find_element_by_id(self._user_confirm_password).clear()
self.driver.find_element_by_id(self._user_email).send_keys(email)
self.driver.find_element_by_id(self._user_phone).send_keys(phone)
self.driver.find_element_by_id(self._user_login_name).send_keys(login_name)
self.driver.find_element_by_id(self._user_nickname).send_keys(nickname)
self.driver.find_element_by_id(self._user_password).send_keys(password)
self.driver.find_element_by_id(self._user_confirm_password).send_keys(confirm_password) #手机号码有误时的提示信息
def phone_err(self):
phone_error = self.driver.find_element_by_id(self._phone_error)
return phone_error.text #登录名不合法时的提示信息
def loginName_error(self):
loginName_error = self.driver.find_element_by_id(self._loginName_error)
return loginName_error.text
(五) 测试类(测试用例,testRegisterNewUser.py)
from selenium import webdriver
from ddt import ddt,data,unpack
import xlrd
from homepage import HomePage
from registerpage import RegisterPage
from basetestcase import BaseTestCase
#读取Excel数据的函数
def get_data(file_name):
rows = []
book = xlrd.open_workbook(file_name)
sheet = book.sheet_by_index(0)
for r_idx in range(1, sheet.nrows):
rows.append(list(sheet.row_values(r_idx,0)))
pthone = rows[r_idx - 1].pop(1)
rows[r_idx - 1].insert(1, str(int(pthone)))
return rows
@ddt
class RegisterNewUserDDT(BaseTestCase):
#重写setUpClass()
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.driver.implicitly_wait(30)
cls.driver.maximize_window()
cls.driver.get('https://www.cnblogs.com/')
#创建HomePage()类的对象实例
home_page = HomePage(cls.driver)
home_page.register_click()
# 读取excel文件的数据作为参数
@data(*get_data('data/reTest.xlsx'))
@unpack
def test_register_new_user(self,email,phone,login_name,nickname,password,confirm_password,expected_result):
#创建RegisterPage()的对象实例
register_page = RegisterPage(self.driver)
self.assertTrue(register_page.validate_page(self.driver))
register_page.send_keys(email,phone,login_name,nickname,password,confirm_password)
if phone == '':
self.assertTrue(register_page.phone_err() == expected_result)
elif login_name == 'b':
self.assertTrue(register_page.loginName_error() == expected_result)
(六) 测试准备(basetestcase.py)
#这部分本来想放到第二步的,不过感觉有点影响对page object的理解,就放到最后了
创建一个类,定义setup()和teardowm()方法,方便所有测试复用。这个类可以理解为是测试类的一部分,我只是把所有测试类(测试用例)都用到的setup()和teardowm()拿出来,方便复用。如果哪个测试用例有特殊要求,也可以重写。
import unittest
from selenium import webdriver class BaseTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.driver.implicitly_wait(30)
cls.driver.maximize_window()
cls.driver.get('https://www.cnblogs.com/')
@classmethod
def tearDownClass(cls):
cls.driver.quit()
Python+Selenium笔记(十三):Page Object设计模式的更多相关文章
- python+ selenium&APPium自动化 page Object 设计模式
题记: 之前公司项目比较稳定, 在进行了系统测试,想用自动化测试进行冒烟测试,或者对主要功能进行测试, 因此用到了PO模式 因此做个记录: Page Object Page Object模式是使用Se ...
- Python+Selenium框架设计--- Page Object Model
POM(Page Object Model):页面对象模型,POM是一种最近几年非常流行的自动化测试模型,或者思想,POM不是一个框架,就是一个解决问题的思想.采用POM的目的,是为了解决前端中UI变 ...
- selenium+Python(Page Object 设计模式实例)
以下实例演示了采用了page Object设计模式的方式登录qq空间: 1.创建基础类page:在初始方法__init__()定义驱动的(driver),基本url(base_url)和超时时间(ti ...
- Python+selenium之Page Object设计模式
Page Object是selenium自动化测试项目开发实践的最佳设计模式之一,他主要提现在对界面交互细节的封装,这样可以使测试案例隔你给加关注于业务而非界面细节,从而提高测试案例的可读性. Pag ...
- web端自动化——selenium Page Object设计模式
Page Object设计模式的优点如下: ① 减少代码的重复. ② 提高测试用例的可读性. ③ 提高测试用例的可维护性,特别是针对UI频繁变化的项目. 当为Web页面编写测试时,需 ...
- Selenium+java - Page Object设计模式
前言 Page Object(页面对象)模式,是Selenium实战中最为流行,并且被自动化测试同学所熟悉和推崇的一种设计模式之一.在设计测试时,把页面元素定位和元素操作方法按照页面抽象出来,分离成一 ...
- Selenium(十九):unittest单元测试框架(五) Page Object设计模式
1. Page Object设计模式 Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,它主要体现在对界面交互细节的封装,这样可以使测试方案更关注于业务而非界面细节.从 ...
- Selenium 2自动化测试实战39(Page Object设计模式)
Page Object设计模式 Page object是selenium自动化测试项目开发时间的最佳设计模式之一,主要体现在对界面交互细节的封装. 1.认识page object优点如下:1.减少代码 ...
- Page Object设计模式实践
Page Object模式是使用Selenium的广大同行最为公认的一种设计模式.在设计测试时,把元素和方法按照页面抽象出来,分离成一定的对象,然后再进行组织. Page Object模式,创建一个对 ...
- Page Object 设计模式介绍
Page Object 是 Selenium 自动化测试项目开发实践的最佳设计模式之一,Page Object 的主要体现于对界面交互细节的封装,这样可以使测试案例更关注与业务而非界面细节,提高测试案 ...
随机推荐
- 基于.Net + SqlServer的分库分表设计方案
在说分库分表之前,先简单介绍下网站架构,这样有助于理解为何需要分库分表这种技术.因为所有的技术,大多都是因为业务的需要而产生的. 1.网站发展的第一阶段 大致架构如下,因为没有多少用户访问,所以单台服 ...
- TFS2018环境搭建一单实例安装(适用于小型团队)
1.服务器配置 阿里云 单核CPU,2GB的RAM,SSD硬盘,安装TFS实例 TFS2018要求SQL Server 2016 (minimum SP1)以上.其要求有以下几点: (1).安装SQL ...
- C#基础篇四数组
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P01A ...
- [Python学习笔记-002] lambda, map, filter and reduce
1. lambda lambda, 即匿名函数,可以理解为跟C语言的宏类似.例如: >>> max = lambda x, y: x if x > y else y >& ...
- WPF 中动态改变控件模板
在某些项目中,可能需要动态的改变控件的模板,例如软件中可以选择不同的主题,在不同的主题下软件界面.控件的样式都会有所不同,这时即可通过改变控件模板的方式实现期望的功能. 基本方法是当用户点击切换主题按 ...
- 简易的命令行聊天室程序(Winsock,服务器&客户端)
代码中使用WinSock2函数库,设计并实现了简单的聊天室功能.该程序为命令行程序.对于服务器和客户端,需要: 服务器:创建监听套接字,并按本地主机绑定:主线程监听并接受来自客户端的请求,并为该客户端 ...
- Solr 清空数据的简便方法
1. 首先访问你的 core,然后点击左侧的 Documents 2. 在 documents type 选择 XML 3. documents 输入下面语句 <delete><qu ...
- c++中友元机制
友元的概念:遵循一定规则而使对象以外的软件系统能够不经过消息传递方式而直接访问对象内封装的数据成员的技术方法便是友元. 只要将外界的某个对象说明为一个类的友元,那么这个外界对象就可以访问这个类对象中的 ...
- 亲身实践 yui-compressor压缩js和css
最近很懒散,个人感情.家庭原因,没有动力去学东西,老是发誓要搞好前端工程化,老中断,唉!没有魄力! 最近老觉得这前端工程化有什么好的,东西那么多,还得学!直到前几天产品提了个优化,说搜索结果页跳商品详 ...
- [Angularjs]ng-bind-html指令
摘要 在为html标签绑定数据的时,如果绑定的内容是纯文本,你可以使用{{}}或者ng-bind.但在为html标签绑定带html标签的内容的时候,angularjs为了安全考虑,不会将其渲染成htm ...