Python用Selenium做自动化测试(三):Page Object专题

Page Object专题

页面对象模型的设计优势:

  • 创造可以被多个测试用例共享的可重用代码。
  • 减少大量重复的代码。
  • 如果用户界面发生改变,则修改只用在一处进行。

Python用Selenium做自动化测试(三):Page Object专题_第1张图片

图片来源:

https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html

目的:测试代码与被测页面对象代码分离,后期如果有页面元素发生了更改,只需要修改相应页面对象的代码(即对应Class文件),而不需要修改测试的代码。

尽量使用XPath来寻找页面元素。

    from selenium import webdriver
  2 from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
  3 import time
  4 
  5 binary=FirefoxBinary('/usr/local/firefox/firefox')
  6 driver=webdriver.Firefox(firefox_binary=binary)
  7 print('Before login================')
  8 title=driver.title
  9 print(title)
 10 now_url=driver.current_url
 11 print(now_url)
 12 
 13 driver.implicitly_wait(10)
 14 driver.get("https://mail.qq.com/")
 15 driver.switch_to_frame("login_frame")
 16 driver.find_element_by_id("u").clear()
 17 driver.find_element_by_id("u").send_keys("*")
 18 driver.find_element_by_xpath("//*[@id='p']").clear()
 19 driver.find_element_by_xpath("//*[@id='p']").send_keys("*")
 20 driver.find_element_by_xpath("//*[@id='login_button']").click()
 21 print('After login===================')
 22 title=driver.title
 23 print(title)
 24 now_url=driver.current_url
 25 print(now_url)
 26 user=driver.find_element_by_xpath("//*[@id='useralias']").text
 27 print(user)
 28 driver.quit()

用PageObject改造后:page.py,element.py,locators.py,测试文件是test_qq.py

参照

的写法写了一下,执行时长11s.

test_qq.py

  1 import unittest
  2 from selenium import webdriver
  3 from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
  4 import page
  5 import time
  6 
  7 
  8 class LoginQQ(unittest.TestCase):
  9     def setUp(self):
 10         binary=FirefoxBinary('/usr/local/firefox/firefox')
 11         self.driver = webdriver.Firefox(firefox_binary=binary)
 12         self.driver.implicitly_wait(10)
 13         self.driver.get("https://mail.qq.com/")
    		#跳转表单,这里没有分割出来,需要改进
 14         self.driver.switch_to_frame("login_frame")
 15     def test_login(self):
 16         main_page = page.MainPage(self.driver)
            #测试数据
 17         main_page.input_username="*"
 18         main_page.input_password="*"
 19         main_page.click_button()
 20     def tearDown(self):
 21         self.driver.close()
 22 if __name__ == "__main__":        
 23     unittest.main()

page.py

  1 from element import BasePageElement
  2 from locators import MainPageLocators
  6 class UsernameElement(BasePageElement):
  7     #元素定位
		locator='u'
  8 class PasswordElement(BasePageElement):    
  9     locator='p'
 10 class BasePage(object):
 11     def __init__(self,driver):
 12         self.driver=driver
 13 class MainPage(BasePage):
 14     input_username=UsernameElement()
 15     input_password=PasswordElement()
 16     def click_button(self):
 17         element=self.driver.find_element(*MainPageLocators.login_loc)
 18         element.click()

element.py

  1#元素操作
  2 class BasePageElement(object):
  3     def __set__(self,obj,value):
  4         driver=obj.driver
  5         driver.find_element_by_id(self.locator).clear()
  6         driver.find_element_by_id(self.locator).send_keys(value)
  7        
  8     def __get__(self,obj,owner):
  9         driver=obj.driver
 10         element=driver.find_element_by_id(self.locator)
 11         return element.get_attribute("value")

locators.py

  1 from selenium.webdriver.common.by import By
  2 class MainPageLocators(object):
  3     login_loc = (By.XPATH,"//*[@id='login_button']")

又经过虫师的书以及网上一些参考,进一步优化PageObject如下。

主要思想:将一个page对象封装成一个HTML页面,然后通过提供的应用程序特定的API来操作页面元素。一个API是关于应用的,一个API是关于HTML的。因此,page对象提供一个易于编程的接口并隐藏窗口中底层的部件。

  • 访问一个文本框通过一个访问方法(accessor method)来实现字符串的获取和返回
  • 复选框使用布尔值
  • 按钮被表示为行为导向的方法名。

即page对象应当将GUI控件上所有查询和操作数据的行为封装为方法

test_qq.py

#coding=utf-8                                                                              
  2 import unittest
  3 
  4 from po_model import LoginPage
  5 from selenium import webdriver                                                             
  6 from selenium.webdriver.firefox.firefox_binary import FirefoxBinary                        
  7 from po_model import test_user_login                                                       
  8 from time import sleep                                                                     
  9 class test_qq(unittest.TestCase):                                                          
 10     def setUp(self):                                                                       
 11         binary=FirefoxBinary('/usr/local/firefox/firefox')                                 
 12         self.driver=webdriver.Firefox(firefox_binary=binary)                               
 13         self.driver.implicitly_wait(30)                                                    
 14     def test_login(self):
 15         username='*'                                                        
 16         password='*'                                                         
 17         test_user_login(self.driver,username,password)
 18         sleep(3)
 19         text = self.driver.find_element_by_xpath("//*[@id='useraddr']").text               
 20         assert(text == '[email protected]',"用户名称不匹配,登录失败")                 
 21     def tearDown(self):                                                                    
 22         self.driver.quit()
 23 if __name__ == "__main__":                                                                 
 24     unittest.main()

po_model.py

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.by import By
from time import sleep

class Page(object):
    '''
    基础类,用于页面对象类的继承
    '''
    login_url="https://mail.qq.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)
    def open(self):
        self._open(self.url)
    def switch(self):
        return self.driver.switch_to_frame(self.framename)
    def find_element(self,*loc):
        return self.driver.find_element(*loc)
class LoginPage(Page):
    '''
    qq邮箱登录页面模型
    '''
    url='/'
    #定位器
    username_loc=(By.ID,"u")
    password_loc=(By.ID,"p")
    login_loc = (By.XPATH,"//*[@id='login_button']")
    #Action
    def type_username(self,username):
        self.find_element(*self.username_loc).clear()
        self.find_element(*self.username_loc).send_keys(username)
    def type_password(self,password):
        self.find_element(*self.password_loc).clear()
        self.find_element(*self.password_loc).send_keys(password)
    def submit(self):    
        self.find_element(*self.login_loc).click()

def test_user_login(driver,username,password):
    '''
    测试获取的用户名/密码是否可以登录

    '''

    login_page=LoginPage(driver)
    login_page.open()
    driver.switch_to_frame("login_frame")
    login_page.type_username(username)
    login_page.type_password(password)
    login_page.submit()

你可能感兴趣的:(软件测试,Linux)