Page Object设计模式python
Page object是selenium自动化测试项目开发时间的最佳设计模式之一,主要体如今对界面交互细节的封装。web
1.认识page object
优势以下:
1.减小代码的重复
2.提升测试用例的可读性
3.提升测试用例的可维护性,特别是针对UI频繁变化的项目。设计模式
2.page object实例
下面以登陆新浪邮箱为例,经过page object设计模式来实现。浏览器
#po_model.py
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
class Page(object):
'''基础类,用于页面对象类的继承'''
login_url='https://ui.ptlogin2.qq.com/cgi-bin/login'
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):
'''新浪邮箱登陆页面模型'''
url='/'
#定位器
username_loc=(By.ID,"u")
password_loc=(By.ID,"p")
submint_loc=(By.ID,"go")
#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.submint_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='xxxxxxxx'
password='xxxxxxxxxx'
test_user_login(driver,username,password)
time.sleep(10)
text=driver.find_element_by_class_name("qm_toolbarTitle").text
assert(text == u'xxxxxxx - 退出'),u"用户名称不匹配,登陆失败!"
finally:
#关闭浏览器窗口
driver.close()
if __name__=='__main__':
main()
Page object设计模式的实现方法显然使结构变得复杂了不少,下面对其逐段分析,来体会这样设计的好处。函数
1.建立page类测试
class Page(object): '''基础类,用于页面对象类的继承''' login_url='xxxxx' 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()类ui
Page类中定义的这些方法都是页面操做的基本方法,下面根据登陆页的特色再建立LoginPage类并继承Page类,这也是Page Object设计模式中最重要的对象层。url
class LoginPage(Page): '''新浪邮箱登陆页面模型''' url='/' #定位器 username_loc=(By.ID,"u") password_loc=(By.ID,"p") submint_loc=(By.ID,"go") #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.submint_loc).click()
LoginPage类中主要对登陆页面上的元素进行封装,使其成为更具体的操做方法。例如:用户名、密码和登陆按钮都被封装成了方法。spa
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='xxxxx' password='xxxxx' test_user_login(driver,username,password) time.sleep(10) text=driver.find_element_by_class_name("qm_toolbarTitle").text assert(text == u'xxxxx - 退出'),u"用户名称不匹配,登陆失败!" finally: #关闭浏览器窗口 driver.close() if __name__=='__main__': main()
main()函数更接近与用户的操做行为。对用户来讲,要进行邮箱的登陆,须要关心的就是经过哪一个浏览器打开邮箱地址、登陆的用户名和密码是什么,至于输入框、按钮是如何定位的,则不须要关心。
这样分层的好处:不一样的层关心不一样的问题,页面对象层只关心元素的定位问题,测试用例只关心测试的数据。
章小结:介绍了三个知识点:利用HTMLTestRunner生成测试报告、集成自动发邮件功能和page object设计模式,虽然他们之间没有直接的联系,可是合理化的运行到自动化测试项目中将有助于自动化测试项目的开展。