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++ 操作符、局部 全局变量及自动转换原则
1.&:表示与操作,eg:2&1=2&&:表示and操作,eg:1&&0=0|:表示或操作,eg:2|1=3||:表示or操作,eg:1||0=12.全 ...
- Android之混淆心得与亲身体验
project.properties 中设置 proguard.config=proguard-project.txt proguard-project.txt 中设置 -optimizationp ...
- 安装的Android SDK下无doc文件夹问题 以及关联Android帮助文档和查看文档 以及查看在线文档
参考连接:https://blog.csdn.net/fangzicheng/article/details/78344521 https://jingyan.baidu.com/article/29 ...
- CNN初探
CNN初探 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7450413.html 前言 这篇博客主要讲解卷积神经网络(CNN) ...
- 微信小程序——动态渲染页面、路径传参
1.动态渲染页面.改变css.样式必须setData渲染过去 this.setData({ userInfo: app.globalData.userInfo, token: app.glob ...
- Java集合——HashMap,HashTable,ConcurrentHashMap区别
Map:“键值”对映射的抽象接口.该映射不包括重复的键,一个键对应一个值. SortedMap:有序的键值对接口,继承Map接口. NavigableMap:继承SortedMap,具有了针对给定搜索 ...
- keepalived之单播----k8sHA准备
一.概述 keepalived主要有三个模块,分别是core.check和vrrp.core模块为keepalived的核心,负责主进程的启动.维护以及全局配置文件的加载和解析.check负责健康检查 ...
- android开发学习笔记系列(5)--fragment与viewpage
前言 在前面的博客写到我针对一个项目完成了动态布局的效果,顿时感觉很爽,那么下面我针对我在前文中所讲的tabhost的实现做出一个新的方法,tabhost基本已经被启用,现在基本使用Fragment与 ...
- ffplay源码分析4-音视频同步
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10307089.html ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg ...
- js实现四叉树算法
最近在看canvas动画方面教程,里面提到了采用四叉树检测碰撞.之前也看到过四叉树这个名词,但是一直不是很懂.于是就又找了一些四叉树方面的资料看了看,做个笔记,就算日后忘了,也可以回来看看. Quad ...