雖然之前的api自動化測試框架還有很多可完善的地方,但是由于基本滿足了我目前的使用場景,于是這兩天我又在ui自動化測試框架上進行了一番簡單的臨摹學(xué)習(xí),實現(xiàn)了一個基礎(chǔ)架構(gòu)报破,接下來一小段時間會努力在豐富一下的。然后會和之前的api測試部分整合起來。
Page Object Model
這個ui自動化測試框架愤惰,應(yīng)用到的一種模式叫做PO模式,Page Object Model(頁面對象模型)赘理。這個模式主要是說將每一個頁面看做是一個對象宦言,具體頁面操作與測試流程相分離,單獨一個方面的更改并不會影響到對方商模。
主要應(yīng)用
- 利用selenium進行元素定位及操作
- 利用pytest進行測試驗證奠旺。
- 其它輔助工具幫助更好的執(zhí)行自動化,例如測試數(shù)據(jù)的讀寫施流、日志記錄响疚、html記錄以及截屏圖像等。
框架結(jié)構(gòu)
整體框架主要分為四個部分:
- Page Model:包括封裝selenium操作瞪醋,及各個頁面元素定位忿晕。
- TestCase:主要有測試用例文件、測試請求數(shù)據(jù)以及測試結(jié)果存儲數(shù)據(jù)银受。
- Utils:包含框架用到的工具践盼,例如讀寫excel、截屏宾巍、日志咕幻、發(fā)送郵件、html報告存儲等顶霞。
-
Config:一些配置肄程,例如url、環(huán)境配置等。
框架結(jié)構(gòu)
PageModel
PageModel主要包括page軟件包以及base_page.py文件蓝厌。
頁面元素定位及操作設(shè)置
建立page
軟件包玄叠,內(nèi)部存儲各個頁面的元素定位信息,以及需要執(zhí)行的自動化操作拓提。
首先是入口頁需執(zhí)行測試的對象诸典。
#unique_page.py
from selenium.webdriver.common.by import By
elements = [
{'name': 'choose1', 'desc': '選擇一', 'by': (By.XPATH, '/html/body/div[1]/'),
'action': 'click()'},
{'name': 'choose2', 'desc': '選擇二', 'by': (By.XPATH, '/html/body/div[2]'),
'action': 'click()'},
{'name': 'create_btn', 'desc': '點擊生成', 'by': (By.XPATH, '/html/body/div[3]/'),
'action': 'click()'}
]
以及結(jié)果頁需要執(zhí)行測試的對象。
#result.py
from selenium.webdriver.common.by import By
elements = [
{'name': 'description', 'desc': '描述', 'by': (By.XPATH, '/html/body/div[4]/'),
'action': 'text'},
]
元素操作封裝
在base_page.py文件中崎苗,進行各項元素定位及操作的獲取狐粱,并封裝執(zhí)行的操作。
獲取元素
通過import_module方法胆数,以字符串為參數(shù)肌蜻,動態(tài)引用頁面元素的位置及操作。即上方unique_page.py/result.py文件中的elements必尼。
#base_page.py
import importlib
# 通過傳入字符串來引用一個模塊
def get_page_elements(page):
m = importlib.import_module(page)
element = m.elements
return element
封裝頁面操作
通過上方的get_page_elements方法獲取到元素后蒋搜,先在Page類中定義一些初始化變量。
#base_page.py
class Page(object):
def __init__(self, driver, page):
self.driver = driver
self.page = page
self.elements = get_page_elements(page)
self.by = ()
Page類中建立get_each_elem方法判莉,獲取元素的具體定位豆挽。
def get_each_elem(self, elem):
for each in self.elements:
if each['name'] == elem:
self.by = each['by']
Page類中建立selenium_elem方法,封裝瀏覽器查找元素位置券盅。這里的find_element方法括號內(nèi)的參數(shù)帮哈,必須加*號變?yōu)槲恢脜?shù),否則執(zhí)行時會報錯:Message: invalid argument: 'using' must be a string
锰镀。(我至今還沒有明白為什么...)
def selenium_elem(self, args=None):
element = self.driver.find_element(*self.by)
return element
Page類中建立operate_elem方法娘侍,封裝元素點擊操作。相似的各種操作都可以在這之后建立泳炉,例如獲取文案(.text)等等憾筏。
#執(zhí)行元素點擊操作
def operate_elem(self, elem, args=None):
self.get_each_elem(elem)
element = self.selenium_elem()
return self.driver.execute_script("arguments[0].click();", element)
#執(zhí)行獲取文案操作
def get_elem(self, elem, args=None):
self.get_each_elem(elem)
element = self.selenium_elem().text
return element
TestCase
測試用例軟件包中,主要包括Case(各個頁面的測試用例)花鹅、data(測試數(shù)據(jù))以及result_data(需要保存的結(jié)果數(shù)據(jù))氧腰。
測試用例中,直接調(diào)用PageModel中標(biāo)明的頁面元素以及操作方法刨肃。
#test_unique.py
from selenium import webdriver
from PageModel.base_page import Page
def test_one():
driver = webdriver.Chrome()
driver.get('https://***.com')
driver.switch_to.frame(0)#所測頁面在一個frame中古拴,需要先轉(zhuǎn)入。
#進入入口頁操作元素
obj = Page(driver, 'PageModel.page.unique_page')#第二個參數(shù)是字符串之景,動態(tài)引入頁面元素定位
obj.operate_elem('choose1')#對元素執(zhí)行點擊操作
obj.operate_elem('choose2')#對元素執(zhí)行點擊操作
obj.operate_elem('create_btn')#對元素執(zhí)行點擊操作
#進入結(jié)果頁操作元素
result = Page(driver, 'PageModel.page.result')
desc = result.get_elem('description')
assert desc == 'Success'
終端運行pytest test_unique.py
即可斤富。
Utils
如果需要操作數(shù)據(jù)膏潮,比如從數(shù)據(jù)庫表讀取參數(shù)锻狗,或者將結(jié)果寫入數(shù)據(jù)庫表。可以增加excel的讀寫方法轻纪。
讀取數(shù)據(jù)
#read_excel.py
import pandas as pd
def read_excel(file):
read_data = pd.read_excel(file)
data = []
for i in read_data.index.values:
row_data = read_data.loc[i, :].to_dict()
data.append(row_data)
return data
寫入數(shù)據(jù)
#write_excel.py
import pandas as pd
def write_excel(data, file):
df = pd.DataFrame(data)
df.to_excel(file, index=False)
至此油额,一個簡單的UI自動化測試框架搭建完成,現(xiàn)階段刻帚,實現(xiàn)的只有結(jié)構(gòu)圖標(biāo)記已完成的部分潦嘶,還需要不斷的去填充和學(xué)習(xí)。目前的目錄如下~
未來一小段日子會繼續(xù)豐富的~~~
歷時了三天崇众,終于寫完了~
這兩天補充了兩個模塊掂僵,截圖和打印日志,直接上對應(yīng)的記錄鏈接顷歌,所以現(xiàn)在的目錄如下~
自我記錄锰蓬,有錯誤歡迎指正~