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 的主要体现于对界面交互细节的封装,这样可以使测试案例更关注与业务而非界面细节,提高测试案 ...
随机推荐
- c++中文件读取
对于C++编译运行文件,我使用过两个编译器,一个是visual studio 2013,另外一个是devcpp,推荐使用devcpp. vs的特点是界面整洁清晰,但是需要收费,这是微软的,并且在电脑上 ...
- chrome中Timeline的使用(译)
一.概括 Timeline面板包括以下四个部分: 控制面板.开始记录.停止记录.配置捕获信息: 概况.页面性能的整体概况: flame chart.直观展示cpu堆的情况.你能够看到三条虚线,蓝色的代 ...
- 读书笔记(02) - 可维护性 - JavaScript高级程序设计
编写可维护性代码 可维护的代码遵循原则: 可理解性 (方便他人理解) 直观性 (一眼明了) 可适应性 (数据变化无需重写方法) 可扩展性 (应对未来需求扩展,要求较高) 可调试性 (错误处理方便定位) ...
- windows平台安装php_memcache模块
要求 必备知识 熟悉基本编程环境搭建. 运行环境 windows 7(64位);php-5.3; memcached-1.2.6 下载地址 环境下载 什么是PHP Memcache模块 Memcach ...
- POJ2418 Hardwood Species—二叉查找树应用
1. Hardwood Species原题描述 Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 14326 Acce ...
- Maven 入门——认识 Maven
Maven /ˈmāvən/ ,可以翻译成"专家",是一款来自 Apache 组织的开源项目,用于项目管理.主要服务于基于 Java 平台的项目构建.依赖管理和项目信息管理. 构建 ...
- 简单聊聊SOA和微服务
转自:https://juejin.im/post/592f87feb123db0064e5ef7c (2017-06) 简单聊聊SOA和微服务 架构设计中的朴素主义 前两天和一个朋友聊天,他向我咨 ...
- SAP HANA项目过程中优化分析以及可行性验证
在项目开发过程中,经常会遇到HANA模型运行效率的问题: 以我们项目为例,HANA平台要求模型运行时间不能超过10秒,但是在大数量和计算逻辑复杂的情况下(例如:ERP中的BKPF和BSEG量表的年数据 ...
- Redis列表操作
列表类似于双向链表结构,可从序列两端推入或者弹出元素. (列表常用命令) RPUSH : RPUSH key-name value [value1 value2,...] ------------将 ...
- Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝订单退款)
上一篇写到支付宝的支付,这代码copy下来就能直接用了, 我写学习文档时会经常贴 官方参数文档的案例地址, 因为我觉得 请求参数,响应参数说明 官方文档整理的很好,毕竟官方不会误导大家. 我学一个 ...