Python用Selenium做自動化測試(三):Page Object專題
阿新 • • 發佈:2018-12-19
Page Object專題
頁面物件模型的設計優勢:
- 創造可以被多個測試用例共享的可重用程式碼。
- 減少大量重複的程式碼。
- 如果使用者介面發生改變,則修改只用在一處進行。
圖片來源:
目的:測試程式碼與被測頁面物件程式碼分離,後期如果有頁面元素髮生了更改,只需要修改相應頁面物件的程式碼(即對應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()
參照
的寫法寫了一下,執行時長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()
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()
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")
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()