python單機版自動化測試框架源代碼(selenium+Appium+requests+unittest+Excel用例+HTMLTestRunner報告)


一、自動化測試框架:

1、框架和項目源代碼下載

https://gitee.com/rmtic/autoTest

說明:框架可以支持web界面UI、安卓Android,ios蘋果、接口API等自動化測試。文檔和代碼持續維護更新,有問題可以交流。

2、依賴包安裝

2.1、jdk

jdk安裝

2.2、python安裝

下載地址:

http://python.org/getit/ 

http://npm.taobao.org/mirrors/python/

2.3、python依賴包

執行autoTest目錄下的install.bat,即autoTest\install.bat

 

2.3、chrome driver

2.3.1、chrome driver的下載地址:

http://npm.taobao.org/mirrors/chromedriver/

2.3.2、安裝

下載解壓放到chrome的安裝目錄下...\Google\Chrome\Application\

設置path環境變量,把chrome的安裝目錄(我的:C:\ProgramFiles\Google\Chrome\Application)

注:

1、因信息安全原因,刪除了真實項目配置文件中密碼和http網頁真實地址

2、以業務物流追蹤(ipadWuLiuZhuiZong.py)中國港口功能為樣例,做了界面檢查、數據庫與界面數據對比、字體顏色(紅綠)檢查等功能,僅供參考

3、建議windows綻放配置為100%,否則可能會影響部分功能穩定性

 

 

 

二、簡介:

  1. 外部工具:上面自動化包目錄“autoTest\basic\browsermob-proxy”中已經包含Browsermob-Proxy
  2. autoTest\conf\config.ini可以配置日志級別
  3. autoTest\caseexcel\ipadWebCase.xls是ipad網頁項目Excel用例,“ipadApiCase.xls"是API接口用例,"大屏WebCase.xls"是大屏項目用例,"#url.xls"是生產和測試等網頁地址配置文件
  4. autoTest\basic是基礎腳本,基本所有項目通用,mySysCommon.py為系統常用函數功能class,webTestCase.py為UI自動化測試常用函數功能class
  5. autoTest\report是用於存放測試報告和過程圖片
  6. autoTest\log是用於存放過程日志
  7. autoTest\cases\Zd為某項目自動化腳本,allData.json為公共數據變量文件,publicOperation.py為當前項目共用函數,comm.py中編寫unittest的test開頭用例,ipadDanJi.py和ipadWuLiuZhuiZong.py是各測試模塊。commApi.py為API接口入口用例,ipadApi.json為API接口配置文件。
  8. main.py為主執行文件(可以通過main.bat執行),默認處理main.py處理autoTest\caseexcel目錄中所有*.xls用例(但不包括子目錄),完成后生成測試報告如下。如果有錯誤用例,編號記錄在autoTest\log\retryCase.txt文件中

     

     

  9. retry.py可單獨執行main.py中錯誤用例(可以通過retry.bat執行),即讀取autoTest\log\retryCase.txt文件
  10. selenium_debug.py用於單獨調試comm.py中對應test開頭的自動化測試用例,但不讀Excel用例數據
  11. 定時任務task.py(可以通過task.bat執行)自動定時先執行main.bat,再執行retry.bat,如果有錯誤用例發送通知

 

三、用例編寫入門(詳細使用說明)

 1、新建模塊用例文件

 

2、在comm.py中import上面模塊用例的class

並用CLASS Comm繼承IpadWuLiuZhuiZong

 

3、模塊用例中寫具體的點擊菜單和其它操作代碼

 

 

 

4、在comm.py中添加模塊入口用例

 

 

self.mySysParameterLoginEx用於IpadUserAdminID

self.params_in和self.checkPoint分別為輸入參數和檢查參數,可以分別獲取excel用例中“輸入參數”和“檢查點”

 

 

ipadPbLoginOK為登錄函數,輸入用戶、密碼、和url

ipadWuLiuZhuiZongOK即調用模塊用例入口

 

 

5、在Excel用例中添加與comm.py中相同名稱的模塊名

即模塊名testIpadWuLiuZhuiZongOK,就可調用對應的函數。

用例執行時會從上向下按行逐個執行。

如果有多個文件也是按名稱逐個執行。

狀態為“無效”時,則不執行。為空值或其它時則執行。

 

 

6、在Excel用例中配置config頁和在"#url.xls"的config頁中配置url

項目名填寫Zd,即路徑“autoTest\cases\Zd”中的Zd

文件名,即comm.py中的comm

模塊名,即文件comm.py中class名Comm

類型填寫web

瀏覽器填寫chrome或api,chrome即谷歌瀏覽器,api即接口測試

url即web測試地址,如下圖

 

在"#url.xls"的config頁中配置url,文件名和模塊名與用例中config中的對應。類型為“無效”則不執行。如果上面用例excel中配置了url,則執行用例中的,不執行這里。用例excel中沒有配置,則執行這里。如下圖:

 

 

如果某個用例只在部分地址執行,則配置用例狀態為“3”或“1;3”,如下圖:

  

 其中,“3”即不執行對應url類型的如下圖第3行地址,“1;3”即不執行對應類型的如下圖第1和3行地址,如下圖

 

 

 

 

7、函數注釋說明

在函數開始注釋中一般會有各函數使用說明,PyCharm等工具調用時浮窗也可以看到

 

 

8、UI自動化常用函數(webTestCase.py)

選擇單個控件

def myWtFindElement(self, element, myby, myCtrlIdent, ifPrintErr=1, ifDisEna=1, maxWaittime=-1):

例:self.myWtFindElement(driver, By.CLASS_NAME, 'info')

選擇多個控件

def myWtFindElements(self, element, myby, myCtrlIdent, ifPrintErr=1, ifFindElt=0):

例:self.myWtFindElements(driver, By.CLASS_NAME, 'itemBox')

WEB網頁,輸入框輸入對應text值

def myWtSendKeysWebEx(self, element, myby, myCtrlIdent, text, ifPrintErr=1, ifDisEna=1, clear=0):

例:self.myWtSendKeysWebEx(driver, By.CLASS_NAME, "input-text", '123456')

控件點擊

def myWtClickEx(self, element, myby, myCtrlIdent, ifPrintErr=1, ifDisEna=1, maxWaittime=-1):

例:self.myWtClickEx(driver, By.XPATH, "//span[text()='登錄']")

獲取控制台js log日志信息,如果控制台日志報錯則打印error日志

def myWtGetJsLog(self, driver, jsLogExclude=[]):

例:self.myWtGetJsLog(driver, self.jsLogExclude)

獲取Google Chrome網頁devtools的Network接口請求和返回信息

def myWtPerformanceNetworkLog(self, driver, beginWaitTime=1, endWaitTime=10):

例:self.myWtPerformanceNetworkLog(driver)

 

9、系統常用函數(mySysCommon.py)

斷言

self.mySysAssert("沒有對應的類型")
例:self.mySysAssert('沒有找到數據:{}'.format(fontfamily))

處理輸入的文件名,返回處理后的文件名

def mySysProcessFileName(self, fileName)

函數說明:字符串清理,去除\r和\n

def mySysStringCleanup(self, textStr):

網絡下載文件

def mySysDownloadFile(self, urlStr, saveFilename)

ping ip

def mySysPing(self, ip):

發郵件

def mySysSendEmail(self, smtpserver="smtp.sohu.com", sender="ocean@sohu.com", username="ocean@sohu.com", password="123456", receivers=["jianghy003@qianhai.com.cn", "52@qq.com"], textSubject=None, textBody=None, attachmentList=None)

生成帶logo的二維碼圖片

def mySysMakeQRCode(self, fileName, data, logo=None)

判斷字符串是否全數字

def mySysIsAllNumber(self, word):

讀Excel,返回所有sheet name

def mySysReadExcelSheetName(self, filename):

讀Excel,返回某行所有內容

def mySysReadExcelRow(self, filename, sheetname, rowNum)

讀Excel,返回某列所有內容

def mySysReadExcelCol(self, filename, sheetname, colNum)

接口API

def mySysApi(self, url, requestMethod, header, datas, jsons)

oracle操作

def mySysOracleExecute(self, oracleIP, oraclePort, oracleUsername, oraclePassword, serviceName, sql, sshIP=None, sshPort=None, sshUsername=None, sshPassword=None)

 

10、項目常用函數(publicOperation.py)

ipad登錄成功

ipadPbLoginOK(self, driver, userName, password, url):

選擇主菜單

ipadPbSelectMainMenu(self, driver, menuStr1='', menuStr2='', menuStr3='')

接口

def myApi(self, url, requestMethod, datas, jsons):

oracle操作執行SQL

def myPbOracleExecute(self, sql):

生成SQL

def myPbMybatis(self, fileName, sql_id, params):

檢查數據,數據庫SQL查出的數值與傳入的值對比

def myPbOracleValueListCheck(self, actualValue, fileName, sql_id, params):

def myPbOracleValueDictCheck(self, actualValue, fileName, sql_id, params):

ipad檢查控件顏色

def ipadPbCheckTextColor(self, elt, color='red'):
例:self.ipadPbCheckTextColor(elt, 'green')

取和檢查控件中文本大小(檢查樣例和報告如下圖),且可以在截圖中自動用紅框標注位置

def ipadPbGetCheckTextSize(self, driver, paramsIn, checkPoint, uiPath, inputList=None, trby=None, trCtrlIdent=None, tdby=None, tdCtrlIdent=None, excludeTextList=[], tableWidth='N', tagList=['div', 'span', 'li', 'th', 'td', 'p']):

例如可以發現如下換行錯誤

 

 

 且在截圖中自動用紅框標注位置,如下圖

注:使用這個功能時建議windows縮放為100%,如下圖。如果用125%或以上可能會造成不准確

 

 

 

 

 

四、mySysCommon.py函數列表

def mySysAssert(self, text):
def mySysDialogOpenFile(self, filePathName):
def mySysGetDatetime(self):
def mySysGetDate(self, year=0, day=0, hour=0, minute=0, second=0):
def mySysGetLocalTime(self):
def mySysGetLocalMillisecond(self):
def mySysParameterLogin(self, paramsIn):
def mySysParameterLoginEx(self, paramsIn, ParName, ParPassword, iFForce=0):
def mySysParameterAssignment(self, paramsIn, ParNameA, ParNameB):
def mySysParameterValueReplaceJson(self, paramsIn, paramsKey):
def mySysParameterDefault(self, paramsIn, paramsKey, defaultValue):
def mySysParameterSplit(self, paramsIn, type):
def mySysParameterGetValue(self, paramsIn, paramsKey):
def mySysParameterIfNew(self, paramsIn):
def mySysGetRandChineseName(self):
def mySysGetPhoneNum(self):
def mySysGetPhoneRandomNum(self):
def mySysGetIdCardNum(self):
def mySysGetIdCardRandomNum(self):
def mySysCopyFile(self, oldFilename, newFilename):
def mySysMoveFile(self, oldFilename, newFilename):
def mySysRemoveFile(self, filename):
def mySysRemoveFileInDir(self, targetDir):
def mySysWriteFile(self, textStr, FileName='D:/order.txt'):
def mySysProcessFileName(self, fileName):
def mySysJsonLoad(self, FileName):
def mySysJsonWrite(self, data, FileName):
def mySysStringCleanup(self, textStr):
def mySysCloseProcess(self, ProcessName):
def mySysGetPathEachFile(self, filePath):
def mySysReadFileLines(self, fileName):
def mySysDateDifference(self, startDate, endDate):
def mySysListAddLimit(self, list, newMember, maxNum):
def mySysTimeGapSec(self, d1):
def mySysDownloadFile(self, urlStr, saveFilename):
def mySysPing(self, ip):
def mySysSendEmail(self, smtpserver="smtp.sohu.com", sender="ocean@sohu.com", username="ocean@sohu.com", password="123456", receivers=["jianghy003@qianhai.com.cn", "52@qq.com"], textSubject=None, textBody=None, attachmentList=None):
def mySysImagePaste(self, toImage, fileName, loc):
def mySysMakeQRCode(self, fileName, data, logo=None):
def mySysReadPdf(self, pdf):
def mySysDatePmtAgt(self):
def mySysIsChinese(self, ch):
def mySysIsExistChinese(self, word):
def mySysIsAllChinese(self, word):
def mySysGetChineseNum(self, word):
def mySysIsNumber(self, uchar):
def mySysIsExistNumber(self, word):
def mySysIsAllNumber(self, word):
def mySysIsAllNumberExclude(self, word):
def mySysGetNumberNum(self, word):
def mySysIsAlphabet(self, uchar):
def mySysIsExistAlphabet(self, word):
def mySysIsAllAlphabet(self, word):
def mySysGetAlphabetNum(self, word):
def mySysIsother(self, uchar):
def mySysSetClipboardText(self, clipboard):
def mySysReadExcelSheetName(self, filename):
def mySysReadExcelRow(self, filename, sheetname, rowNum):
def mySysReadExcelCol(self, filename, sheetname, colNum):
def mySysApi(self, url, requestMethod, header, datas, jsons):
def mySysOracleExecute(self, oracleIP, oraclePort, oracleUsername, oraclePassword, serviceName, sql, sshIP=None, sshPort=None, sshUsername=None, sshPassword=None):
def mySysTextCheck(self, actualText, expectText, ifFuzzy=0):
def mySysHsv2Rgb(self, h, s, v):
def mySysRgb2Hsv(self, r, g, b):

 

五、webTestCase.py函數列表

 

def setUp(self):
def tearDown(self):
def __upLoadImg(self, driver, testName, timeStr, type):
def myWtGet_screenshot_as_fileEx(self, driver, picName, printlog=0):
def myWtScreenshotAsFile(self, driver):
def myWtScreenshotByElementAsFile(self, driver, element):
def myWtScreenshotByElement(self, driver, element):
def myWtScreenshotByXyAsFile(self, driver, x=0, y=210 , width=300, height=150):
def myWtImageCompare(self, oldImage, newImage, percent=10):
def myWtScreenRecordAsFileArd(self):
def myWtExportFromArdToPC(self, fileNameList):
def myWtGetProxyResult(self):
def myWtGetProxyNewResult(self):
def myWtGetProxyNewAloneResult(self, localList, url):
def myWtCheckProxyResult(self):
def myWtGetJsLog(self, driver, jsLogExclude=[]):
def __getAppPathConf(self):
def myWtFindElement(self, element, myby, myCtrlIdent, ifPrintErr=1, ifDisEna=1, maxWaittime=-1):
def myWtFindElements(self, element, myby, myCtrlIdent, ifPrintErr=1, ifFindElt=0):
def myWtElementEx(self, element, ifPrintErr=1, ifDisEna=1, maxWaittime=-1):
def myWtSendKeys(self, element, text, clear=0):
def myWtSendKeysElements(self, element, myby, myCtrlIdent, text, clear=0):
def myWtSendKeysEx(self, element, myby, myCtrlIdent, text, ifPrintErr=1, ifDisEna=1, clear=0):
def myWtSendKeysWebEx(self, element, myby, myCtrlIdent, text, ifPrintErr=1, ifDisEna=1, clear=0):
def myWtClick(self, element, ifPrintErr=1, maxWaittime=-1):
def myWtClickEx(self, element, myby, myCtrlIdent, ifPrintErr=1, ifDisEna=1, maxWaittime=-1):
def myWtCheckboxRadioSelect(self, element, myby, myCtrlIdent, selected=1, ifPrintErr=1, ifDisEna=1):
def myWtSelectByText(self, driver, text):
def myWtEltNonexiContinue(self, element, myby, myCtrlIdent, ifPrintErr=0, maxWaittime=2):
def myWtFindElementsCpnText(self, driver, myby, myCtrlIdent, text, maxWaittime=-1):
def myWtElementsClickNumber(self, element, myby, myCtrlIdent, serialNumber=1, ifFindElt=0):
def myWtElementsChooseTextClick(self, eltList, text, ifBreak=1, serialNumber=0, maxWaittime=-1):
def myWtElementsChooseTextClickEx(self, driver, myby, myCtrlIdent, text, ifBreak=1, serialNumber=0, maxWaittime=-1):
def myWtElementsSimilarTextClick(self, eltList, text, ifBreak=1, serialNumber=0, maxWaittime=-1):
def myWtElementsChooseClickEx(self, element, myby, myCtrlIdent, elementEnd, mybyEnd, myCtrlIdentEnd):
def myWtElementsChooseAttributeClick(self, eltList, attributeName, text):
def myWtTablesChooseTextClickElt(self, eltList, text, myby, myCtrlIdent):
def myWtTablesChooseTextClickEltEx(self, eltList, text, myby, myCtrlIdent, myText):
def myWtElementsChooseTextSendKeys(self, eltList, text, inputStr):
def myWtElementsChooseAttributeSendKeys(self, eltList, attributeName, text, inputStr):
def myWtActionKeydown(self, driver, key):
def myWtTouchActionTap(self, driver, elt):
def myWtTouchActionLongpress(self, driver, elt):
def myWtCursorMoveFatherClickElt(self, driver, elt, myby, myCtrlIdent):
def myWtSelectCheck(self, driver, expectText):
def myWtInputCheck(self, driver, expectText):
def myWtTextCheck(self, driver, expectText, ifFuzzy=0):
def myWtAttributeCheck(self, driver, expectText, attributeName, ifFuzzy=0):
def myWtH5FlickUp(self, driver, elt, frequency=1, sleepTime=0, y1Temp=200):
def myWtH5FlickDown(self, driver, elt, frequency=1, sleepTime=0, y1Temp=-200):
def myWtGetWinSize(self, driver):
def myWtPhoneTap(self, driver, lx, ly):
def myWtPhoneSwipeAuto(self, driver, element, sleepTime=0):
def myWtPhoneSwipe(self, driver, x1, y1, x2, y2, frequency=1, sleepTime=0):
def myWtPhoneSwipeUp(self, driver, frequency=1, sleepTime=0, y1Temp=0.75, y2Temp=0.25):
def myWtPhoneSwipeDown(self, driver, frequency=1, sleepTime=0, y1Temp=0.25, y2Temp=0.75):
def myWtPhoneSwipeLeft(self, driver, frequency=1, sleepTime=0, x1Temp=0.75, x2Temp=0.25):
def myWtPhoneSwipeRight(self, driver, frequency=1, sleepTime=0, x1Temp=0.25, x2Temp=0.75):
def myWtPhonePasteText(self, driver, elt, text, x=0, y=0):
def myWtPhoneSetTypewriting(self):

 

六、publicOperation.py函數列表

 

def __getJsonConf(self):
def ipadPbLoginOK(self, driver, userName, password, url):
def ipadPbLoginPasswordError(self, driver, userName, password, url):
def ipadPbwebLoginComm(self, driver, userName='', password='', url=''):
def ipadPbSelectMainMenu(self, driver, menuStr1='', menuStr2='', menuStr3=''):
def ipadPbRefreshWaiting(self, driver):
def ipadPbLeftBack(self, driver, maxWaittime=None):
def ipadPbCloseTopRight(self, driver, maxWaittime=None):
def ipadPbSelectShowDate(self, driver, datetype, date, maxWaittime=-1):
def ipadPbShowDate(self, driver, dType, year, month, day=None, maxWaittime=-1):
def ipadPbGetCheckTextSize(self, driver, paramsIn, checkPoint, uiPath, inputList=None, trby=None, trCtrlIdent=None, tdby=None, tdCtrlIdent=None, excludeTextList=[], tableWidth='N', tagList=['div', 'span', 'li', 'th', 'td', 'p']):
def __ipadPbGetCheckTextSize(self, driver, paramsIn, checkPoint, data, eltList, trby=None, trCtrlIdent=None, tdby=None, tdCtrlIdent=None, excludeTextList=[], tableWidth='N'):
def ipadPbGetStrStdWidth(self, string, fontfamily='Bebas'):
def ipadPbCheckTextColor(self, elt, color='red'):
def pbJudgeRGBColor(self, rgb):
def myApi(self, url, requestMethod, datas, jsons):
def myGetWebToken(self):
def dapingPbLoginOK(self, driver, userName, password, url):
def dapingPbLoginPasswordError(self, driver, userName, password, url):
def dapingPbwebLoginComm(self, driver, userName='', password='', url=''):
def dapingPbRefreshWaiting(self, driver):
def dapingPbCheckTextColor(self, elt, color='red'):
def myPbOracleExecute(self, sql):
def myPbMybatis(self, fileName, sql_id, params):
def myPbOracleValueCheck(self, actualValue, fileName, sql_id, params):

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM