Python-基於數據驅動模式的自動化測試框架搭建的的逐步實現(二)
------封裝走起!!
後續關於 <Python-基於數據驅動模式的自動化測試框架搭建的的逐步實現> 的博客例子全部基於:126郵箱登錄並新建聯繫人,這個例子來實現的;
大家好,我們繼續 <Python-基於數據驅動模式的自動化測試框架搭建的的逐步實現> 之旅,本篇博客開始我們要進入封裝的旅途。
首先我們建一個工程,這裏面我用的IDE是pycharm,個人覺得還是比較好用的;
這裏給初學語言的小朋友們一點小建議:
開始練習編寫的時候不建議使用IDE,因爲大部分IDE具備聯想功能,這樣不利於記憶常用命令。我最開始的時候就用的寫字板,着實好用,除了空格要手動敲,沒有顏色以外,真心不錯,可以強化記憶。
這裏我給本次工程取的名字叫:data_driven_framework
在本篇博客中,我們要先封裝5個packages出來:Until、Conf、PageObject、ProjectVar、TestData
1、Util(相當於底層工具,複用次數多)U
Util中包括一下文件:讀寫Excel的方法、獲取頁面元素的方法、讀取配置文件的方法、獲得driver的方法、
1.1 獲取頁面元素的封裝【driver.find_element_by(LocateType,LocateExpression)】-----ObjectMap.py
從Python-基於數據驅動模式的自動化測試框架搭建的的逐步實現(一)中我們可以看到,好多代碼是重複編寫的,比如:driver.find_element_by(LocateType,LocateExpression),那麼就可以把這個獲取元素的操作封裝起來,後面要對元素進行操作的時候,直接調用獲取元素的方法就好了,這樣就降低了代碼的冗餘度;
話不多說,上代碼:
#encoding=utf-8 from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import Select import time def getEelement(driver,locateType,locateExpression): #獲取頁面單個元素 try: wait=WebDriverWait(driver,10) return wait.until(lambda x:x.find_element(locateType,locateExpression)) except Exception,e: raise e def getElements(driver,locateType,locateExpression): #獲取頁面多個元素 try: wait=WebDriverWait(driver,10) return wait.until(lambda x:x.find_elements(locateType,locateExpression)) except Exception,e: raise e #對於下拉框標籤是select的元素的獲取特有操作 def getSelectElementWithIndex(driver,index_num): #獲取select下拉框元素---index select_element=Select(driver.find_element_by_xpath('//select')) #打印已選中的文本 print select_element.all_selected_options[0].text return select_element.select_by_index(index_num) def getSelectElementWithText(driver,text): #獲取select下拉框元素----text select_element=Select(driver.find_element_by_xpath('//select')) #打印已選中的文本 print select_element.all_selected_options[0].text return select_element.select_by_visible_text(text) def getSelectElementWithValue(driver,value): #獲取select下拉框元素---value select_element=Select(driver.find_element_by_xpath('select')) #打印已選中的文本 print select_element.all_selected_options[0].text return select_element.select_by_value(value)
1.2 Excel操作的封裝-----Excel.py
由於用的是數據驅動框架類型,這裏我使用excel來讀取測試數據、記錄測試結果,那麼就避免不了excel的大量操作,所以把excel的大部分操作封裝起來,後續調用---我常用的excel操作是查詢和插入,見代碼:
#encoding=utf-8 from openpyxl import Workbook from openpyxl import load_workbook from ProjectVar.Var import * from openpyxl.styles import Border,Side,Font class Excel(object): def __init__(self): self.font=Font(color=None) self.colorDict={'red':'FFFF3030','green':'FF008B00'} #test_path表示excel的路徑,在另外一個package裏面封裝的,封裝的內容有工程目錄的絕對路徑,是公用的,該工程目錄下的其他文件路徑只要在此基礎上拼接字符串即可 self.wb=load_workbook(test_path) #表示默認選中的是第一個表格 self.ws=self.wb.active def rename(self,new_name): #給表格重命名 self.ws.title=new_name self.wb.save(test_path) def GetSheetName(self): #獲取所有表格名稱 return self.wb.get_sheet_names() def GetSheetByName(self,sheet_name): #通過表格名稱獲取表格 self.ws=self.wb.get_sheet_by_name(sheet_name) return self.ws def GetCurrentSheetName(self): #獲取當前表格名稱 return self.ws.title def GetCellContent(self,col_num,row_num): #獲取單元格內容 return self.ws.cell(row=row_num,column=col_num).value def WriteCellContent(self,col_num,row_num,content): #往指定的單元格里面寫入內容 self.ws.cell(row=row_num,column=col_num).value=content self.wb.save(test_path) def GetMaxRow(self): #獲取最大行號 return self.ws.max_row def GetMaxColumn(self): #獲取最大列號 return self.ws.max_column
1.3 配置文件的基本操作的封裝----GetConf.py
GetConf.py主要的功能是用來提取頁面元素的定位方式locateType和定位表達式locateExpression的;
代碼如下:
#encoding=utf-8 import ConfigParser from ProjectVar.Var import * class ParsePageObjectRepositoryConfig(object): def __init__(self): self.cf=ConfigParser.ConfigParser() self.cf.read(page_object_repository_path) def getItemsFromSection(self,sectionName): items=self.cf.items(sectionName) return dict(items)
1.4 Driver.py 得到driver
代碼如下:
#encoding=utf-8 from selenium import webdriver driver=webdriver.Chrome(executable_path='c:\\Python27\\chromedriver')
2、ProjectVar
2.1 將工程中用到的已知元素封裝起來,在腳本中直接傳遞變量名稱即可---var.py
見代碼:
#encoding=utf-8 import os #當前文件路徑 file_path=__file__ #工程路徑 #os.path.dirname(__file__)當前文件所在路徑 project_path=os.path.dirname(os.path.dirname(__file__)).decode('utf-8') test_path=project_path+u'//TestData//126郵箱聯繫人.xlsx' page_object_repository_path=project_path+'//Conf//PageObjectRepository .ini' url='http:\\www.126.com'
3、Conf(配置文件)
3.1 頁面元素的路徑全部封裝在配置文件PageObjectRepository.ini中,這樣即使路徑變更不會直接修改代碼,減少了維護成本;----PageObjectRepository .ini
這裏將要操作的頁面元素的定位路徑全都寫在這個配置文件,按照頁面來寫,每個操作頁面的寫在不同的標籤欄裏面;
本次例子需要的頁面元素如下:
[configparse操作配置文件的時候有坑] [ini中的內容要全部小寫,否則讀取出來的時候會自動轉換成小寫,這樣就會發生匹配不上的情況] [126mail_login] loginpage.frame=xpath>//iframe[@id='x-URS-iframe'] loginpage.username=xpath>//span[.='@126.com']//preceding-sibling::input loginpage.password=xpath>//label[.='密碼']//following-sibling::input[2] loginpage.loginbutton=xpath>//a[@id='dologin'] [126mail_homepage] home_age.addressbook=xpath>//div[text()='通訊錄'] [126mail_addcontactspage] addcontacts_page.create_contacts_btn=xpath>//span[text()='新建聯繫人'] addcontacts_page.contact_person_name=xpath>//a[@title='編輯詳細姓名']/preceding-sibling::div/input addcontacts_page.contact_person_email=xpath>//*[@id='iaddress_MAIL_wrap']//input addcontacts_page.star_contacts=xpath>//span[text()='設爲星標聯繫人']/preceding-sibling::span/b addcontacts_page.contact_person_mobile=xpath>//*[@id='iaddress_TEL_wrap']//dd//input addcontacts_page.contact_person_comment=xpath>//textarea addcontacts_page.save_contace_person=xpath>//span[.='確 定'] 4 、PageObject(獲取頁面元素) 此次例子分爲登錄、首頁-通訊錄、添加聯繫人三個步驟 4.1 登錄頁面的元素獲取----login_page.py
#encoding=utf-8 from ProjectVar.Var import * from Util.GetConf import * from Util.ObjectMap import * from Util.Driver import * class LoginPage(object): def __init__(self): self.cf=ParsePageObjectRepositoryConfig() #section需要修改 self.login_page_items=self.cf.getItemsFromSection('126mail_login')#得到的是字典 def iframe(self): #獲取iframe locateType=self.login_page_items['loginpage.frame'].split('>')[0] locateExpression=self.login_page_items['loginpage.frame'].split('>')[1] return getEelement(driver,locateType,locateExpression) def username(self): #獲取iframe locateType=self.login_page_items['loginpage.username'].split('>')[0] locateExpression=self.login_page_items['loginpage.username'].split('>')[1] return getEelement(driver,locateType,locateExpression) def password(self): #獲取iframe locateType=self.login_page_items['loginpage.password'].split('>')[0] locateExpression=self.login_page_items['loginpage.password'].split('>')[1] return getEelement(driver,locateType,locateExpression) def login_button(self): #獲取iframe locateType=self.login_page_items['loginpage.loginbutton'].split('>')[0] locateExpression=self.login_page_items['loginpage.loginbutton'].split('>')[1] return getEelement(driver,locateType,locateExpression)
4.2首頁,通訊錄元素獲取---home_page.py
#encoding=utf-8 from ProjectVar.Var import * from Util.GetConf import * from Util.ObjectMap import * from Util.Driver import * class HomePage(object): def __init__(self): self.cf=ParsePageObjectRepositoryConfig() #section需要修改 self.login_page_items=self.cf.getItemsFromSection('126mail_homepage') def addressbook(self): #獲取addressbook locateType=self.login_page_items['home_age.addressbook'].split('>')[0] locateExpression=self.login_page_items['home_age.addressbook'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression)
4.3添加聯繫人頁面元素獲取----address_book.py
#encoding=utf-8 from ProjectVar.Var import * from Util.GetConf import * from Util.ObjectMap import * from Util.Driver import * class AddressBook(object): def __init__(self): self.cf=ParsePageObjectRepositoryConfig() #section需要修改 self.login_page_items=self.cf.getItemsFromSection('126mail_addcontactspage') def AddContactsButton(self): #獲取addressbook locateType=self.login_page_items['addcontacts_page.create_contacts_btn'].split('>')[0] locateExpression=self.login_page_items['addcontacts_page.create_contacts_btn'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression) def PersonName(self): #聯繫人名字 locateType=self.login_page_items['addcontacts_page.contact_person_name'].split('>')[0] locateExpression=self.login_page_items['addcontacts_page.contact_person_name'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression) def Email(self): #聯繫人郵箱 locateType=self.login_page_items['addcontacts_page.contact_person_email'].split('>')[0] locateExpression=self.login_page_items['addcontacts_page.contact_person_email'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression) def Star(self): #星級聯繫人 locateType=self.login_page_items['addcontacts_page.star_contacts'].split('>')[0] locateExpression=self.login_page_items['addcontacts_page.star_contacts'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression) def Mobile(self): #電話 locateType=self.login_page_items['addcontacts_page.contact_person_mobile'].split('>')[0] locateExpression=self.login_page_items['addcontacts_page.contact_person_mobile'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression) def Comment(self): #備註 locateType=self.login_page_items['addcontacts_page.contact_person_comment'].split('>')[0] locateExpression=self.login_page_items['addcontacts_page.contact_person_comment'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression) def Save(self): #保存 locateType=self.login_page_items['addcontacts_page.save_contace_person'].split('>')[0] locateExpression=self.login_page_items['addcontacts_page.save_contace_person'].split('>')[1] print locateExpression,locateType return getEelement(driver,locateType,locateExpression)
5、 TestData ----數據和結果excel表格(數據驅動)
到目前爲止,我的目錄結構是這樣的: