簡單介紹下:
為了減少基本功能點點的測試,因此考慮到重復性勞動的不便利,因此我就打算用ui自動化的方式來解決
在冒煙測試的階段,有很多是之前的功能,迭代版本並沒有改動,但為了防止代碼之間的相互影響,最好之前的流程最好也要測一遍
因此就有了UI自動化
為了更好的管理測試用例,我這里用的是Excel
總結一下涉及到的模塊:
Common:公共模塊(日志類,瀏覽器驅動配置項,關鍵字驅動)
Data:存放excel數據(用例數據)
Log:存放生成日志文件
Testcase:封裝了關鍵字驅動Excel數據類
Email:存放發送郵件模塊
關鍵字驅動類:(主要封裝了selenium中的各種操作方法)
from time import sleep from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.support.select import Select from selenium.webdriver.support.wait import WebDriverWait from UiProject.Common.Options import Options def open_browser(type_): '''基於反射機制簡化代碼''' try: driver = getattr(webdriver,type_)(options=Options().option_conf()) except Exception as e: print(e) driver = webdriver.Chrome(options=Options().option_conf()) return driver class WebKey: '''初始化driver對象''' def __init__(self,type_): self.driver = open_browser(type_) self.driver.implicitly_wait(8) # 訪問地址url def get(self,txt): self.driver.get(txt) # 關閉瀏覽器,釋放資源 def quit(self): self.driver.quit() # 關閉游標 def close(self): self.driver.close() # 定位元素 def locator(self,name,value): return self.driver.find_element(name,value) # 點擊操作 def click(self,name,value): self.locator(name,value).click() # 輸入操作(輸入內容可以是文本,也可以是路徑) def input(self,name,value,txt): self.locator(name,value).send_keys(txt) # 通過js執行器獲得文本信息,然后進行斷言 def assert_not_in_text(self,name,value,variable,txt): try: content =self.js_handler(name,value,variable) assert txt not in content,'斷言失敗' return True except Exception as e: print(e) return False # 文本斷言 def assert_text(self,name,value,txt): try: text =self.locator(name,value).text assert text==txt return True except Exception as e: return False # 切換窗口 def switch_window(self): handles = self.driver.window_handles self.driver.switch_to.window(handles[1]) # 切換iframe def switch_frame(self,name,value): if name=='id': self.driver.switch_to.frame(value) element = self.locator(name,value) self.driver.switch_to.frame(element) # 退出iframe def quit_iframe(self): self.driver.switch_to.default_content() # 強制等待 def sleep(self,txt): sleep(txt) # 顯示等待 def wait(self,name,value): return WebDriverWait(self.driver,8,0.5).until(lambda el:self.locator(name,value),message="等待失敗") # 鼠標懸停操作 def hover(self,name,value): element = self.locator(name,value) # 創建Action對象 actions = ActionChains(self.driver) actions.move_to_element(element) # 處理彈窗 # 切換到彈窗 '''確認彈窗''' def accept_alert(self): self.driver.switch_to.alert.accept() # 取消彈窗 def dismiss_alert(self): self.driver.switch_to.alert.dismiss() # 獲取彈窗文本 def get_alerttext(self): return self.driver.switch_to.alert.text # prompt彈窗輸入內容 def alert_input(self,text): return self.driver.switch_to.alert.send_keys(text) # Select下拉菜單選項 def select_index(self,name,value,index): # 先定位下拉菜單位置 el = Select(self.driver.find_element(name,value)) # 按下拉菜單的位置選擇,從0開始 el.select_by_index(index) def select_value(self,name,value,option_text): # 先定位下拉菜單位置 el = Select(self.driver.find_element(name,value)) ##按下拉菜單的內容選擇,頁面中option標簽的值 el.select_by_value(option_text) def select_visible_text(self,name,value,text): # 先定位下拉菜單位置 el = Select(self.driver.find_element(name, value)) #按下來菜單的顯示文本內容選擇 el.select_by_visible_text(text) # js執行器 def js_handler(self,name,value,variable): elment =self.locator(name,value) text =self.driver.execute_script(variable,elment) return text
ChromeOptions谷歌瀏覽器驅動配置項
''' 封裝Chrome的配置類 ''' # ChromeOption類的封裝 from selenium import webdriver class Options: def option_conf(self): '''配置Chrome配置項''' options = webdriver.ChromeOptions() # 默認啟動窗體最大化 options.add_argument('start-maximized') # 去掉自動化提示條 options.add_experimental_option('excludeSwitches',['enable-automation']) # 添加本地緩存 # options.add_argument(r'--user-data-dir=C:\Users\15414\AppData\Local\Google\Chrome\User Data') # 添加無頭指令 # options.add_argument('--headless') # 添加去掉密碼彈窗管理 prefs = {} prefs["credentials_enable_service"] = False prefs["profile.password_manager_enabled"] = False options.add_experimental_option("prefs", prefs) # 開始無痕模式 options.add_argument('incognito') # 指定窗口大小 # options.add_argument('window-size=8000,3000') # 默認瀏覽器啟動的位置 # options.add_argument('window-position=200,400') return options
Excel數據驅動(暫時還沒有封裝)
''' 進行excel數據驅動,excel數據驅動類底層代碼 ''' import openpyxl from openpyxl.styles import PatternFill,Font,colors,Alignment from UiProject.Common.Log import Log from UiProject.Common.WebKey import WebKey logger = Log().Setlog() # 讀取excel logger.info('正在讀取Excel文件') excel = openpyxl.load_workbook('../Data/excel_data/testcase03.xlsx') # 獲取sheet頁 sheets = excel.sheetnames # 遍歷sheet頁 for sheet in sheets: logger.info('正在讀取表格{0}'.format(sheet)) sheet_temp = excel[sheet] # 判斷該表格是否為測試用例:根據表格sheet名是否含有testcase if 'testcase' in sheet: logger.info('正在執行{}'.format(sheet_temp['A1'].value)) # 遍歷sheet頁單元格 for values in sheet_temp.values: # 判斷用例是否已經執行過,有執行結果的代表,用例已經執行過了 if 'Pass' or 'Fail' not in values[8]: # 讀取用例執行部分內容 if type(values[0]) is int: logger.info('操作描述:{}'.format(values[6])) # print(values) # 定義字典 data = {} # 元素定位方法 data['name']=values[2] # 元素定位路徑 data['value']=values[3] # 元素變量 data['variable']=values[4] # 輸入的文本值 data['txt']=values[5] # print(data) # 優化數據,刪除為None的數據 for key in list(data.keys()): if data[key] is None: del data[key] # print(data) # 調用關鍵字執行不同操作 if values[1]=='open_browser': wt = WebKey(values[5]) # 如果是斷言,需要寫入,判斷斷言是否成功,成功True,失敗False elif 'assert' in values[1]: # 斷言函數有返回 status =getattr(wt,values[1])(**data) if status: sheet_temp.cell(row=values[0] +2,column=8).value ='Pass' # sheet_temp.cell(row=values[0] +2, column=8).fill = PatternFill("solid", fgColor="#00FA9A") sheet_temp.cell(row=values[0] +2, column=8).font =Font(color=colors.BLUE,bold=True) sheet_temp.cell(row=values[0] +2, column=8).alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) else: sheet_temp.cell(row=values[0] +2,column=8).value ='Fail' # sheet_temp.cell(row=values[0] +2,column=8).fill = PatternFill("solid", fgColor="#FF0000") sheet_temp.cell(row=values[0] +2, column=8).font = Font(color='#A52A2A',bold=True) sheet_temp.cell(row=values[0] +2, column=8).alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) else: getattr(wt,values[1])(**data) else: break else: logger.info('該表格內容不是測試用例') # 寫入后進行保存 logger.info('自動化用例執行完畢') excel.save('../Data/excel_data/testcase03.xlsx')
說下編寫excel的測試用例的規則:
一個excel文件里可以包含多個sheet,可以都是測試用例,不是用例的話,程序不會執行
按照執行順序,從sheet1開始執行
用例命名規范:必須包含testcase,如(testcase_01)
有斷言的話,和預期結果不一致會執行失敗,執行結果會為Fail,執行成功,執行結果為Pass
只有按照規則寫測試用例,就可以自動執行幾百條,幾千條。