Selenium Page Object 自動化測試框架-Page Object設計
pages
封裝測試過程針對頁面的操作方法,主要包括basepage、mainpage、loginpage、registepage等函數。pages目錄創建時選擇「Python Package」格式。
1.Basepage
BasePage是自定義頁面基類,封裝了基本的頁面操作的方法,有find_element,send_keys 2個公共方法,具體的方法可根據測試需要進行擴展。
find_element:定位元素,識別測試頁面中需驅動的元素。
Send_keys:發送鍵值,模擬鍵盤輸入測試數據。
Logger = Logger(logger="BasePage").getlog()是產生一個共有日誌類,在當前頁面基類中調用。
from common.logger import Logger中表示導入框架中common文件夾下的logger模塊。
我把多數代碼加了注釋,便於大家閱讀學習。
具體代碼如下:
from selenium import webdriver
#載入元素顯示超時設置函數from selenium.webdriver.support.wait import WebDriverWait#導入截圖函數from common.cappic import Cappic#載入預期處理函數
from selenium.webdriver.support import expected_conditions as ECimport timeimport os.path#導入日誌處理函數from common.loggen import Loggerlogger = Logger(logger="BasePage").getlog()#定義基礎頁面類文件,該類僅包含查找元素及輸入數據兩個子函數class BasePage(object): def __init__(self, driver, url):self.driver = driver
self.base_url = url #定義查找元素超時設置,當頁面中某個元素在10秒內沒有顯示,則拋出異常,並在日誌中記錄 def find_element(self, *loc): try: # loc是表示屬性元組本身,*loc表述屬性元組的值,EC.visibility_of_element_located需要傳入2個參數,但*loc是三個參數 # 因此,此處只能loc WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc)) # 此處返回元素的屬性及屬性值,故使用*loc return self.driver.find_element(*loc)except:
#當元素找不到的時候調用截圖函數 Cappic(self.driver) #元素找不到時在日誌中記錄信息 http://logger.info(u"%s 頁面中未能找到 %s 元素" % (self, loc)) def send_keys(self, loc, vaule,): try: #獲取元素的屬性值,以便於識別元素 loc = getattr(self, "_%s" % loc) #查找元素並輸入相關數據self.find_element(*loc).send_keys(vaule)
except AttributeError: #當元素找不到的時候調用截圖函數 Cappic(self.driver) #元素找不到時在日誌中記錄信息 http://logger.info(u"%s 頁面中未能找到 %s 元素" % (self, loc))2.Loginpage
LoginPage類是封裝用戶登陸業務所需的對象驅動方法,繼承自BasePage類,有Input_username輸入用戶名,input_password輸入密碼,click_submit點擊登陸按鈕。Loginpage繼承Basepage基類方法,故需載入Basepage,執行代碼from .basepage import BasePage。
利用Firefox中Firebug對登陸頁面中的用戶名、密碼及登陸按鈕三個對象的屬性分析,Loginpage中的對象識別使用By.NAME方法。
具體代碼如下:
from selenium import webdriver
from pages.basepage import BasePagefrom selenium.webdriver.common.by import Byfrom common.loggen import Loggerfrom common.geturl import geturllogger = Logger(logger="LoginPage").getlog()#創建登陸操作類,頁面中的元素通過name方式識別class LoginPage(BasePage): #設置登陸操作中所用到的三個元素屬性,並以元組形式保存 username = (By.NAME, username)password = (By.NAME, password)
submit = (By.NAME, submit) #定義用戶名元素識別及輸入函數,並將此操作寫入日誌 def input_username(self, username): self.find_element(*self.username).send_keys(username) http://logger.info("輸入用戶名:%s." % username) #定義密碼元素識別及輸入函數,並將此操作寫入日誌 def input_password(self, password): self.find_element(*self.password).send_keys(password) http://logger.info("輸入密碼:%s." % password)#定義提交按鈕元素識別及輸入函數,並將此操作寫入日誌
def click_submit(self): self.find_element(*self.submit).click() http://logger.info("點擊登陸按鈕")3.mainpage
MainPage繼承BasePage基類,封裝了首頁的open打開主頁方法,show_userid獲取用戶登陸id及exit_sys退出系統方法。
可通過show_userid獲取用戶登陸後的id信息,便於判斷登陸是否成功,本次測試並未增加該項判斷,讀者自自行研究如何判斷登陸是否成功。
利用Firefox中Firebug對主頁中的userid及退出元素的屬性分析,mainpage中的對象識別使用XPATH方法。
import os.path
from .basepage import BasePagefrom selenium.webdriver.common.by import By
from common.loggen import Loggerfrom selenium import webdriverimport timelogger = Logger(logger="MainPage").getlog()#定義主頁面中所涉及到的元素,userid及退出按鈕,通過xpath方式識別class MainPage(BasePage): userid_loc = (By.XPATH, .//*[@id=ECS_MEMBERZONE]/font/font) goodstext_loc = (By.ID,keyword) searchbtn_loc = (By.XPATH,//*[@id="searchForm"]/table/tbody/tr/td[2]/input) goodsinfo_loc = (By.CSS_SELECTOR,.goodsItem > p:nth-child(3) > a:nth-child(1)) buybtn = (By.XPATH,//*[@id="ECS_FORMBUY"]/ul/li[7]/table/tbody/tr/td[1]/a/img) paybtn = (By.XPATH,/html/body/div[6]/div[1]/table/tbody/tr/td[2]/a/img) posttype = (By.XPATH,//*[@id="shippingTable"]/tbody/tr[3]/td[1]/input) paytype = (By.XPATH,//*[@id="paymentTable"]/tbody/tr[4]/td[1]/input) ordersubmit = (By.XPATH,//*[@id="theForm"]/div[15]/div[2]/input[1]) ordernumber = (By.XPATH,/html/body/div[6]/div/h6/font) exit_btn_loc=(By.XPATH, .//*[@id=ECS_MEMBERZONE]/font/a[2]) # 定義打開超鏈接方法,並將此操作寫入日誌 def open(self,base_url): self._open(self.base_url, self.pagetitle) http://logger.info("打開鏈接: %s." % base_url) #定義顯示userid信息,並將此操作寫入日誌 def show_userid(self): userid = self.find_element(*self.userid_loc).text http://logger.info("當前用戶id是:%s." % userid) return userid def search_goods(self,testdata): self.find_element(*self.goodstext_loc).send_keys(testdata) self.find_element(*self.searchbtn_loc).click() time.sleep(3) goods = self.find_element(*self.goodsinfo_loc) goodsname = goods.text if goodsname == testdata: http://logger.info(已查詢到%s商品,執行購買操作 %testdata) goods.click() else: http://logger.info(沒有匹配的商品,無法完成購買操作) def buy_goods(self): self.find_element(*self.buybtn).click() self.find_element(*self.paybtn).click() self.find_element(*self.posttype).click() self.find_element(*self.paytype).click() self.find_element(*self.ordersubmit).click() orderno = self.find_element(*self.ordernumber).text if orderno != : http://logger.info(已生成編號為:%s的訂單 %orderno) else: http://logger.info(訂單生成失敗) #定義退出操作,點擊退出按鈕,並寫入日誌 def exit_sys(self): self.find_element(*self.exit_btn_loc).click() http://logger.info("退出測試系統")4.registepage
與用戶登陸類似,registepage集成Basepage基類,用戶註冊操作涉及用戶名、email、密碼、確認密碼、登陸操作。
利用Firefox中Firebug對註冊頁面中的相關元素的屬性分析,registepage中的對象識別使用By.ID和XPATH方法。
from selenium import webdriver
from .basepage import BasePagefrom selenium.webdriver.common.by import Byfrom common.loggen import Loggerfrom common.geturl import geturllogger = Logger(logger="UserRegiste").getlog()#定義註冊頁面中元素的識別及操作方式,通過id及xpath識別元素class RegistePage(BasePage): username = (By.ID, username) email = (By.ID, email) password=(By.ID,password1) confirmpw=(By.ID,conform_password) submit = (By.XPATH, html/body/div[6]/div/form/table/tbody/tr[7]/td[2]/input[3]) #定義用戶名輸入操作函數,並寫入日誌 def input_username(self, username): self.find_element(*self.username).send_keys(username) http://logger.info("輸入用戶名:%s." % username) #定義email輸入操作函數,並寫入日誌 def input_email(self,email): self.find_element(*self.email).send_keys(email) http://logger.info("輸入email:%s." % email) #定義密碼輸入操作函數,並寫入日誌 def input_password(self, password): self.find_element(*self.password).send_keys(password) http://logger.info("輸入密碼:%s." % password) #定義確認密碼輸入操作函數,並寫入日誌 def input_comfirpwd(self, comfirpwd): self.find_element(*self.confirmpw).send_keys(comfirpwd) http://logger.info("輸入確認密碼:%s." % comfirpwd) #定義提交操作函數,並寫入日誌 def click_submit(self): self.find_element(*self.submit).click() http://logger.info("點擊註冊按鈕")推薦閱讀:
※UI自動化測試入門 - (1) Selenium 的使用
※selenium自動化測試02 瀏覽器的登錄和操作
※核心實驗:Selenium IDE->測試Agileone的公告管理
※移動端測試探索之路
※工具應用:Robot Framework-安裝配置與基礎使用