电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

python+requests接口自動(dòng)化框架的實(shí)現(xiàn)

瀏覽:4日期:2022-07-12 17:47:18

為什么要做接口自動(dòng)化框架

1、業(yè)務(wù)與配置的分離

2、數(shù)據(jù)與程序的分離;數(shù)據(jù)的變更不影響程序

3、有日志功能,實(shí)現(xiàn)無人值守

4、自動(dòng)發(fā)送測(cè)試報(bào)告

5、不懂編程的測(cè)試人員也可以進(jìn)行測(cè)試

正常接口測(cè)試的流程是什么?

確定接口測(cè)試使用的工具----->配置需要的接口參數(shù)----->進(jìn)行測(cè)試----->檢查測(cè)試結(jié)果----->生成測(cè)試報(bào)告

測(cè)試的工具:python+requests

接口測(cè)試用例:excel

一、接口框架如下:

python+requests接口自動(dòng)化框架的實(shí)現(xiàn)

1、action包:用來存放關(guān)鍵字函數(shù)

2、config包:用來存放配置文件

3、TestData:用來存放測(cè)試數(shù)據(jù),excel表

4、Log包:用來存放日志文件

5、utils包:用來存放公共的類

6、運(yùn)行主程序interface_auto_test.py

7、Readme.txt:告訴團(tuán)隊(duì)組員使用改框架需要注意的地方

二、接口的數(shù)據(jù)規(guī)范設(shè)計(jì)---Case設(shè)計(jì)

一個(gè)sheet對(duì)應(yīng)數(shù)據(jù)庫里面一張表

python+requests接口自動(dòng)化框架的實(shí)現(xiàn)

APIsheet存放編號(hào);從1開始接口的名稱(APIName);請(qǐng)求的url(RequestUrl);請(qǐng)求的方法(RequestMethod);傳參的方式(paramsType):post/get請(qǐng)求方法不一樣用例說明(APITestCase)是否執(zhí)行(Active)部分接口已測(cè)通,下次不用測(cè)試,直接把這里設(shè)置成N,跳過此接口

post與get的區(qū)別

查看post詳情

post請(qǐng)求參數(shù)一般是json串,參數(shù)放在from表單里面;參數(shù)一般不可見,相對(duì)來說安全性高些

python+requests接口自動(dòng)化框架的實(shí)現(xiàn)

查看get詳情

get請(qǐng)求參數(shù)一般直接放在url里面

python+requests接口自動(dòng)化框架的實(shí)現(xiàn)

2.1注冊(cè)接口用例

python+requests接口自動(dòng)化框架的實(shí)現(xiàn)

RequestData:請(qǐng)求的數(shù)據(jù)(開發(fā)制定的傳參方式)RelyData:數(shù)據(jù)依賴ResponseCode:響應(yīng)codeResponseData:響應(yīng)數(shù)據(jù)DataStore:存儲(chǔ)的依賴數(shù)據(jù);如果存在數(shù)據(jù)庫里面,在表里增加一個(gè)字段用來存依賴的數(shù)據(jù)(存儲(chǔ)的方式是編寫接口自動(dòng)化的人員來設(shè)定的存儲(chǔ)方式)CheckPoint:檢查點(diǎn)Active:是否執(zhí)行Status:執(zhí)行用例的狀態(tài),方便查看用例是否執(zhí)行成功ErrorInfo:case運(yùn)行失敗,失敗的錯(cuò)誤信息;eg:是也本身的原因還是case設(shè)置失敗,還是其他原因

2.2登錄接口用例

python+requests接口自動(dòng)化框架的實(shí)現(xiàn)

RequestData:請(qǐng)求的數(shù)據(jù)(開發(fā)制定的傳參方式)RelyData:數(shù)據(jù)依賴(存儲(chǔ)的方式是編寫接口自動(dòng)化的人員來設(shè)定的存儲(chǔ)方式)ResponseCode:響應(yīng)codeResponseData:響應(yīng)數(shù)據(jù)DataStore:存儲(chǔ)的依賴數(shù)據(jù);如果存在數(shù)據(jù)庫里面,在表里增加一個(gè)字段用來存依賴的數(shù)據(jù)(存儲(chǔ)的方式是編寫接口自動(dòng)化的人員來設(shè)定的存儲(chǔ)方式)CheckPoint:檢查點(diǎn)Active:是否執(zhí)行Status:執(zhí)行用例的狀態(tài),方便查看用例是否執(zhí)行成功ErrorInfo:case運(yùn)行失敗,失敗的錯(cuò)誤信息;eg:是也本身的原因還是case設(shè)置失敗,還是其他原因

重點(diǎn)說明下RelyData:數(shù)據(jù)依賴采取的是字典:key:value來存儲(chǔ)數(shù)據(jù)格式;{'request':{'username':'register->1','password':'register->1'},'response':{'code':'register->1'}}

格式化之后:

{ 'request':{ 'username':'register->1', 'password':'register->1' }, 'response':{ 'code':'register->1' }}

三、創(chuàng)建utils包:用來存放公共的類

3.1 ParseExcel.py 操作封裝excel的類(ParseExcel.py)

#encoding=utf-8import openpyxlfrom openpyxl.styles import Border, Side, Fontimport timeclass ParseExcel(object): def __init__(self): self.workbook = None self.excelFile = None self.font = Font(color = None) # 設(shè)置字體的顏色 # 顏色對(duì)應(yīng)的RGB值 self.RGBDict = {’red’: ’FFFF3030’, ’green’: ’FF008B00’} def loadWorkBook(self, excelPathAndName): # 將excel文件加載到內(nèi)存,并獲取其workbook對(duì)象 try: self.workbook = openpyxl.load_workbook(excelPathAndName) except Exception as err: raise err self.excelFile = excelPathAndName return self.workbook def getSheetByName(self, sheetName): # 根據(jù)sheet名獲取該sheet對(duì)象 try: # sheet = self.workbook.get_sheet_by_name(sheetName) sheet = self.workbook[sheetName] return sheet except Exception as err: raise err def getSheetByIndex(self, sheetIndex): # 根據(jù)sheet的索引號(hào)獲取該sheet對(duì)象 try: # sheetname = self.workbook.get_sheet_names()[sheetIndex] sheetname = self.workbook.sheetnames[sheetIndex] except Exception as err: raise err # sheet = self.workbook.get_sheet_by_name(sheetname) sheet = self.workbook[sheetname] return sheet def getRowsNumber(self, sheet): # 獲取sheet中有數(shù)據(jù)區(qū)域的結(jié)束行號(hào) return sheet.max_row def getColsNumber(self, sheet): # 獲取sheet中有數(shù)據(jù)區(qū)域的結(jié)束列號(hào) return sheet.max_column def getStartRowNumber(self, sheet): # 獲取sheet中有數(shù)據(jù)區(qū)域的開始的行號(hào) return sheet.min_row def getStartColNumber(self, sheet): # 獲取sheet中有數(shù)據(jù)區(qū)域的開始的列號(hào) return sheet.min_column def getRow(self, sheet, rowNo): # 獲取sheet中某一行,返回的是這一行所有的數(shù)據(jù)內(nèi)容組成的tuple, # 下標(biāo)從1開始,sheet.rows[1]表示第一行 try: rows = [] for row in sheet.iter_rows():rows.append(row) return rows[rowNo - 1] except Exception as err: raise err def getColumn(self, sheet, colNo): # 獲取sheet中某一列,返回的是這一列所有的數(shù)據(jù)內(nèi)容組成tuple, # 下標(biāo)從1開始,sheet.columns[1]表示第一列 try: cols = [] for col in sheet.iter_cols():cols.append(col) return cols[colNo - 1] except Exception as err: raise err def getCellOfValue(self, sheet, coordinate = None, rowNo = None, colsNo = None): # 根據(jù)單元格所在的位置索引獲取該單元格中的值,下標(biāo)從1開始, # sheet.cell(row = 1, column = 1).value, # 表示excel中第一行第一列的值 if coordinate != None: try:return sheet[coordinate] except Exception as err:raise err elif coordinate is None and rowNo is not None and colsNo is not None: try:return sheet.cell(row = rowNo, column = colsNo).value except Exception as err:raise err else: raise Exception('Insufficient Coordinates of cell !') def getCellOfObject(self, sheet, coordinate = None, rowNo = None, colsNo = None): # 獲取某個(gè)單元格的對(duì)象,可以根據(jù)單元格所在位置的數(shù)字索引, # 也可以直接根據(jù)excel中單元格的編碼及坐標(biāo) # 如getCellObject(sheet, coordinate = ’A1’) or # getCellObject(sheet, rowNo = 1, colsNo = 2) if coordinate != None: try:# return sheet.cell(coordinate = coordinate)return sheet[coordinate] except Exception as err:raise err elif coordinate == None and rowNo is not None and colsNo is not None: try:return sheet.cell(row = rowNo,column = colsNo) except Exception as err:raise err else: raise Exception('Insufficient Coordinates of cell !') def writeCell(self, sheet, content, coordinate = None, rowNo = None, colsNo = None, style = None): #根據(jù)單元格在excel中的編碼坐標(biāo)或者數(shù)字索引坐標(biāo)向單元格中寫入數(shù)據(jù), # 下標(biāo)從1開始,參style表示字體的顏色的名字,比如red,green if coordinate is not None: try:# sheet.cell(coordinate = coordinate).value = contentsheet[coordinate] = contentif style is not None: sheet[coordinate]. font = Font(color = self.RGBDict[style])self.workbook.save(self.excelFile) except Exception as e:raise e elif coordinate == None and rowNo is not None and colsNo is not None: try:sheet.cell(row = rowNo,column = colsNo).value = contentif style: sheet.cell(row = rowNo,column = colsNo). font = Font(color = self.RGBDict[style])self.workbook.save(self.excelFile) except Exception as e:raise e else: raise Exception('Insufficient Coordinates of cell !') def writeCellCurrentTime(self, sheet, coordinate = None,rowNo = None, colsNo = None): # 寫入當(dāng)前的時(shí)間,下標(biāo)從1開始 now = int(time.time()) #顯示為時(shí)間戳 timeArray = time.localtime(now) currentTime = time.strftime('%Y-%m-%d %H:%M:%S', timeArray) if coordinate is not None: try:sheet.cell(coordinate = coordinate).value = currentTimeself.workbook.save(self.excelFile) except Exception as e:raise e elif coordinate == None and rowNo is not None and colsNo is not None: try:sheet.cell(row = rowNo, column = colsNo ).value = currentTimeself.workbook.save(self.excelFile) except Exception as e:raise e else: raise Exception('Insufficient Coordinates of cell !')if __name__ == ’__main__’: # 測(cè)試代碼 pe = ParseExcel() pe.loadWorkBook(r’D:ProgramSourceCodePython Source CodeWorkSpaceInterfaceFrame2018inter_test_data.xlsx’) sheetObj = pe.getSheetByName(u'API') print('通過名稱獲取sheet對(duì)象的名字:', sheetObj.title) # print help(sheetObj.rows) print('通過index序號(hào)獲取sheet對(duì)象的名字:', pe.getSheetByIndex(0).title) sheet = pe.getSheetByIndex(0) print(type(sheet)) print(pe.getRowsNumber(sheet)) #獲取最大行號(hào) print(pe.getColsNumber(sheet)) #獲取最大列號(hào) rows = pe.getRow(sheet, 1) #獲取第一行 for i in rows: print(i.value) # # 獲取第一行第一列單元格內(nèi)容 # print pe.getCellOfValue(sheet, rowNo = 1, colsNo = 1) # pe.writeCell(sheet, u’我愛祖國’, rowNo = 10, colsNo = 10) # pe.writeCellCurrentTime(sheet, rowNo = 10, colsNo = 11)

3.2 封裝get/post請(qǐng)求(HttpClient.py)

import requestsimport jsonclass HttpClient(object): def __init__(self): pass def request(self, requestMethod, requestUrl, paramsType,requestData, headers =None, **kwargs): if requestMethod == 'post': print('---', requestData, type(requestData)) if paramsType == 'form':response = self.__post(url = requestUrl, data = json.dumps(eval(requestData)), headers = headers, **kwargs)return response elif paramsType == 'json':response = self.__post(url = requestUrl, json = json.dumps(eval(requestData)), headers = headers, **kwargs)return response elif requestMethod == 'get': request_url = requestUrl if paramsType == 'url':request_url = '%s%s' %(requestUrl, requestData) response = self.__get(url = request_url, params = requestData, **kwargs) return response def __post(self, url, data = None, json = None, headers=None,**kwargs): print('----') response = requests.post(url=url, data = data, json=json, headers=headers) return response def __get(self, url, params = None, **kwargs): response = requests.get(url, params = params, **kwargs) return responseif __name__ == '__main__': hc = HttpClient() res = hc.request('get', 'http://39.106.41.11:8080/getBlogContent/', 'url',’2’) print(res.json())

3.3 封裝MD5(md5_encrypt)

import hashlibdef md5_encrypt(text): m5 = hashlib.md5() m5.update(text.encode('utf-8')) value = m5.hexdigest() return valueif __name__ == '__main__': print(md5_encrypt('sfwe'))

3.4 封裝Log

import loggingimport logging.configfrom config.public_data import baseDir# 讀取日志配置文件logging.config.fileConfig(baseDir + 'configLogger.conf')# 選擇一個(gè)日志格式logger = logging.getLogger('example02')#或者example01def debug(message): # 定義dubug級(jí)別日志打印方法 logger.debug(message)def info(message): # 定義info級(jí)別日志打印方法 logger.info(message)def warning(message): # 定義warning級(jí)別日志打印方法 logger.warning(message)

3.5 封裝發(fā)送Email類

import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.header import Headerfrom ProjVar.var import *import osimport smtplibfrom email import encodersfrom email.mime.base import MIMEBasefrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.header import Headerfrom email.utils import formataddrdef send_mail(): mail_host='smtp.126.com' #設(shè)置服務(wù)器 mail_user='testman1980' #用戶名 mail_pass='wulaoshi1980' #口令 sender = ’testman1980@126.com’ receivers = [’2055739@qq.com’,'testman1980@126.com'] # 接收郵件,可設(shè)置為你的QQ郵箱或者其他郵箱 # 創(chuàng)建一個(gè)帶附件的實(shí)例 message = MIMEMultipart() message[’From’] = formataddr(['光榮之路吳老師', 'testman1980@126.com']) message[’To’] = ’,’.join(receivers) subject = ’自動(dòng)化測(cè)試執(zhí)行報(bào)告’ message[’Subject’] = Header(subject, ’utf-8’) message['Accept-Language']='zh-CN' message['Accept-Charset']='ISO-8859-1,utf-8,gbk' # 郵件正文內(nèi)容 message.attach(MIMEText(’最新執(zhí)行的自動(dòng)化測(cè)試報(bào)告,請(qǐng)參閱附件內(nèi)容!’, ’plain’, ’utf-8’)) # 構(gòu)造附件1,傳送測(cè)試結(jié)果的excel文件 att = MIMEBase(’application’, ’octet-stream’) att.set_payload(open(ProjDirPath+'testdatatestdata.xlsx', ’rb’).read()) att.add_header(’Content-Disposition’, ’attachment’, filename=(’gbk’, ’’, '自動(dòng)化測(cè)試報(bào)告.xlsx')) encoders.encode_base64(att) message.attach(att) ''' # 構(gòu)造附件2,傳送當(dāng)前目錄下的 runoob.txt 文件 att2 = MIMEText(open(’e:a.py’,’rb’).read(), ’base64’, ’utf-8’) att2['Content-Type'] = ’application/octet-stream’ att2['Content-Disposition'] = ’attachment; filename='a.py'’ message.attach(att2) ''' try: smtpObj = smtplib.SMTP(mail_host) smtpObj.login(mail_user, mail_pass) smtpObj.sendmail(sender, receivers, message.as_string()) print('郵件發(fā)送成功') except smtplib.SMTPException as e: print('Error: 無法發(fā)送郵件', e)if __name__ == '__main__': send_mail()

四、 創(chuàng)建config包 用來存放公共的參數(shù)、配置文件、長時(shí)間不變的變量值

創(chuàng)建public_data.py

import os# 整個(gè)項(xiàng)目的根目錄絕對(duì)路勁baseDir = os.path.dirname(os.path.dirname(__file__))# 獲取測(cè)試數(shù)據(jù)文件的絕對(duì)路徑file_path = baseDir + '/TestData/inter_test_data.xlsx'API_apiName = 2API_requestUrl = 3API_requestMothod = 4API_paramsType = 5API_apiTestCaseFileName = 6API_active = 7CASE_requestData = 1CASE_relyData = 2CASE_responseCode = 3CASE_responseData = 4CASE_dataStore = 5CASE_checkPoint = 6CASE_active = 7CASE_status = 8CASE_errorInfo = 9# 存儲(chǔ)請(qǐng)求參數(shù)里面依賴的數(shù)據(jù)REQUEST_DATA = {}# 存儲(chǔ)響應(yīng)對(duì)象中的依賴數(shù)據(jù)RESPONSE_DATA = {}if __name__=='__main__': print(file_path) print(baseDir)

五、創(chuàng)建TestData目錄,用來存放測(cè)試文件

inter_test_data.xlsx

六、創(chuàng)建action包,用來存放關(guān)鍵字函數(shù)

6.1 解決數(shù)據(jù)依賴 (GetRely.py)

from config.public_data import REQUEST_DATA, RESPONSE_DATAfrom utils.md5_encrypt import md5_encryptREQUEST_DATA = {'用戶注冊(cè)':{'1':{'username':'zhangsan', 'password':'dfsdf23'}, 'headers':{'cookie':'asdfwerw'}}}RESPONSE_DATA = {'用戶注冊(cè)':{'1':{'code':'00'}, 'headers':{'age':2342}}}class GetRely(object): def __init__(self): pass @classmethod def get(self, dataSource, relyData, headSource = {}): print(type(dataSource)) print(dataSource) data = dataSource.copy() for key, value in relyData.items(): if key == 'request':#說明應(yīng)該去REQUEST_DATA中獲取for k, v in value.items(): interfaceName, case_idx = v.split('->') val = REQUEST_DATA[interfaceName][case_idx][k] if k == 'password': data[k] = md5_encrypt(val) else: data[k] = val elif key == 'response':# 應(yīng)該去RESPONSE_DATA中獲取for k, v in value.items(): interfaceName, case_idx = v.split('->') data[k] = RESPONSE_DATA[interfaceName][case_idx][k] elif key == 'headers':if headSource: for key, value in value.items(): if key == 'request': for k, v in value.items():for i in v: headSource[i] = REQUEST_DATA[k]['headers'][i] elif key == 'response': for i, val in value.items():for j in val: headSource[j] = RESPONSE_DATA[i]['headers'][j] return '%s' %dataif __name__ == '__main__': s = {'username': '', 'password': '','code':''} h = {'cookie':'123', 'age':332} rely = {'request': {'username': '用戶注冊(cè)->1', 'password': '用戶注冊(cè)->1'}, 'response':{'code':'用戶注冊(cè)->1'}, 'headers':{'request':{'用戶注冊(cè)':['cookie']},'response':{'用戶注冊(cè)':['age']}} } print(GetRely.get(s, rely, h))

6.2 解決數(shù)據(jù)存儲(chǔ)(RelyDataStore.py)

from config.public_data import RESPONSE_DATA, REQUEST_DATAclass RelyDataStore(object): def __init__(self): pass @classmethod def do(cls, storePoint, apiName, caseId, request_source = {}, response_source = {}, req_headers={}, res_headers = {}): for key, value in storePoint.items(): if key == 'request':# 說明需要存儲(chǔ)的依賴數(shù)據(jù)來自請(qǐng)求參數(shù),應(yīng)該將數(shù)據(jù)存儲(chǔ)到REQUEST_DATAfor i in value: if i in request_source: val = request_source[i] if apiName not in REQUEST_DATA: # 說明存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)還未生成,需要指明數(shù)據(jù)存儲(chǔ)結(jié)構(gòu) REQUEST_DATA[apiName]={str(caseId): {i: val}} else: #說明存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)中最外層結(jié)構(gòu)已存在 if str(caseId) in REQUEST_DATA[apiName]:REQUEST_DATA[apiName][str(caseId)][i] = val else:# 說明內(nèi)層結(jié)構(gòu)不完整,需要指明完整的結(jié)構(gòu)REQUEST_DATA[apiName][str(caseId)] = {i: val} else: print('請(qǐng)求參數(shù)中不存在字段' + i) elif key == 'response':#說明需要存儲(chǔ)的依賴數(shù)據(jù)來自接口的響應(yīng)body,應(yīng)該將數(shù)據(jù)存儲(chǔ)到RESPONSE_DATAfor j in value: if j in response_source: val = response_source[j] if apiName not in RESPONSE_DATA: # 說明存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)還未生成,需要指明數(shù)據(jù)存儲(chǔ)結(jié)構(gòu) RESPONSE_DATA[apiName]={str(caseId): {j: val}} else: #說明存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)中最外層結(jié)構(gòu)已存在 if str(caseId) in RESPONSE_DATA[apiName]:RESPONSE_DATA[apiName][str(caseId)][j] = val else:# 說明內(nèi)層結(jié)構(gòu)不完整,需要指明完整的結(jié)構(gòu)RESPONSE_DATA[apiName][str(caseId)] = {j: val} else: print('接口的響應(yīng)body中不存在字段' + j) elif key == 'headers':for k, v in value.items(): if k == 'request': # 說明需要往REQUEST_DATA變量中寫入存儲(chǔ)數(shù)據(jù) for item in v: if item in req_headers:header = req_headers[item]if 'headers' in REQUEST_DATA[apiName]: REQUEST_DATA[apiName]['headers'][item] = headerelse: REQUEST_DATA[apiName]['headers'] = {item: header} elif k == 'response': # 說明需要往RESPONSE_DATA變量中寫入存儲(chǔ)數(shù)據(jù) for it in v: if it in res_headers:header = res_headers[it]if 'headers' in RESPONSE_DATA[apiName]: RESPONSE_DATA[apiName]['headers'][it] = headerelse: RESPONSE_DATA[apiName]['headers'] = {item: header} print(REQUEST_DATA) print(RESPONSE_DATA)if __name__ == '__main__': r = {'username': 'srwcx01', 'password': 'wcx123wac1', 'email': 'wcx@qq.com'} req_h = {'cookie':'csdfw23'} res_h = {'age':597232} s = {'request': ['username', 'password'], 'response': ['userid'],'headers':{'request':['cookie'], 'response':['age']}} res = {'userid': 12, 'code': '00'} RelyDataStore.do(s, 'register', 1, r, res, req_headers=req_h, res_headers=res_h) print(REQUEST_DATA) print(RESPONSE_DATA)

6.3 校驗(yàn)數(shù)據(jù)結(jié)果(CheckResult.py)

import reclass CheckResult(object): def __init__(self): pass @classmethod def check(self, responseObj, checkPoint): responseBody = responseObj.json() # responseBody = {'code': '', 'userid': 12, 'id': '12'} errorKey = {} for key, value in checkPoint.items(): if key in responseBody:if isinstance(value, (str, int)): # 等值校驗(yàn) if responseBody[key] != value: errorKey[key] = responseBody[key]elif isinstance(value, dict): sourceData = responseBody[key] if 'value' in value: # 模糊匹配校驗(yàn) regStr = value['value'] rg = re.match(regStr, '%s' %sourceData) if not rg: errorKey[key] = sourceData elif 'type' in value: # 數(shù)據(jù)類型校驗(yàn) typeS = value['type'] if typeS == 'N': # 說明是整形校驗(yàn) if not isinstance(sourceData, int):errorKey[key] = sourceData else:errorKey[key] = '[%s] not exist' %key return errorKeyif __name__ == '__main__': r = {'code': '00', 'userid': 12, 'id': 12} c = {'code': '00', 'userid': {'type': 'N'}, 'id': {'value': 'd+'}} print(CheckResult.check(r, c))

6.4 往excel里面寫結(jié)果

from config.public_data import *def write_result(wbObj, sheetObj, responseData, errorKey, rowNum): try: # 寫響應(yīng)body wbObj.writeCell(sheetObj, content='%s' %responseData, rowNo = rowNum, colsNo=CASE_responseData) # 寫校驗(yàn)結(jié)果狀態(tài)及錯(cuò)誤信息 if errorKey: wbObj.writeCell(sheetObj, content='%s' %errorKey, rowNo=rowNum, colsNo=CASE_errorInfo) wbObj.writeCell(sheetObj, content='faild', rowNo=rowNum, colsNo=CASE_status, style='red') else: wbObj.writeCell(sheetObj, content='pass', rowNo=rowNum, colsNo=CASE_status, style='green') except Exception as err: raise err

七、創(chuàng)建Log目錄用來存放日志

八、主函數(shù)

#encoding=utf-8import requestsimport jsonfrom action.get_rely import GetRelyfrom config.public_data import *from utils.ParseExcel import ParseExcelfrom utils.HttpClient import HttpClientfrom action.data_store import RelyDataStorefrom action.check_result import CheckResultfrom action.write_result import write_resultfrom utils.Log import *def main(): parseE = ParseExcel() parseE.loadWorkBook(file_path) sheetObj = parseE.getSheetByName('API') activeList = parseE.getColumn(sheetObj, API_active) for idx, cell in enumerate(activeList[1:], 2): if cell.value == 'y': #需要被執(zhí)行 RowObj = parseE.getRow(sheetObj, idx) apiName = RowObj[API_apiName -1].value requestUrl = RowObj[API_requestUrl - 1].value requestMethod = RowObj[API_requestMothod - 1].value paramsType = RowObj[API_paramsType - 1].value apiTestCaseFileName = RowObj[API_apiTestCaseFileName - 1].value # 下一步讀取用例sheet表,準(zhǔn)備執(zhí)行測(cè)試用例 caseSheetObj = parseE.getSheetByName(apiTestCaseFileName) caseActiveObj = parseE.getColumn(caseSheetObj, CASE_active) for c_idx, col in enumerate(caseActiveObj[1:], 2):if col.value == 'y': #需要執(zhí)行的用例 caseRowObj = parseE.getRow(caseSheetObj, c_idx) requestData = caseRowObj[CASE_requestData - 1].value relyData = caseRowObj[CASE_relyData - 1].value responseCode = caseRowObj[CASE_responseCode - 1].value responseData = caseRowObj[CASE_responseData - 1].value dataStore = caseRowObj[CASE_dataStore -1].value checkPoint = caseRowObj[CASE_checkPoint - 1].value #發(fā)送接口請(qǐng)求之前需要做一下數(shù)據(jù)依賴的處理 if relyData: logging.info('處理第%s個(gè)接口的第%s條用例的數(shù)據(jù)依賴!') requestData = GetRely.get(eval(requestData), eval(relyData)) httpC = HttpClient() response = httpC.request(requestMethod=requestMethod, requestData=requestData, requestUrl=requestUrl, paramsType=paramsType ) # 獲取到響應(yīng)結(jié)果后,接下來進(jìn)行數(shù)據(jù)依賴存儲(chǔ)邏輯實(shí)現(xiàn) if response.status_code == 200: responseData = response.json() # 進(jìn)行依賴數(shù)據(jù)存儲(chǔ) if dataStore: RelyDataStore.do(eval(dataStore), apiName, c_idx - 1, eval(requestData), responseData) # 接下來就是校驗(yàn)結(jié)果 else: logging.info('接口【%s】的第【%s】條用例,不需要進(jìn)行依賴數(shù)據(jù)存儲(chǔ)!' %(apiName, c_idx)) if checkPoint: errorKey = CheckResult.check(response, eval(checkPoint)) write_result(parseE, caseSheetObj, responseData, errorKey, c_idx) else: logging.info('接口【%s】的第【%s】條用例,執(zhí)行失敗,接口協(xié)議code非200!' %(apiName, c_idx))else: logging.info('第%s個(gè)接口的第%s條用例,被忽略執(zhí)行!' %(idx -1, c_idx-1)) else: logging.info('第%s行的接口被忽略執(zhí)行!' %(idx -1))if __name__=='__main__': main()

框架待完善~~請(qǐng)各路神仙多多指教~~

到此這篇關(guān)于python+requests接口自動(dòng)化框架的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)python requests接口自動(dòng)化內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 皮带式输送机械|链板式输送机|不锈钢输送机|网带输送机械设备——青岛鸿儒机械有限公司 | 小青瓦丨古建筑瓦丨青瓦厂家-宜兴市徽派古典建筑材料有限公司 | 西点培训学校_法式西点培训班_西点师培训_西点蛋糕培训-广州烘趣西点烘焙培训学院 | 陶氏道康宁消泡剂_瓦克消泡剂_蓝星_海明斯德谦_广百进口消泡剂 | 间苯二酚,间苯二酚厂家-淄博双和化工 | 壹车网 | 第一时间提供新车_资讯_报价_图片_排行! | 电机铸铝配件_汽车压铸铝合金件_发动机压铸件_青岛颖圣赫机械有限公司 | 植筋胶-粘钢胶-碳纤维布-碳纤维板-环氧砂浆-加固材料生产厂家-上海巧力建筑科技有限公司 | 【法利莱住人集装箱厂家】—活动集装箱房,集装箱租赁_大品牌,更放心 | 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 电缆接头-防爆电缆接头-格兰头-金属电缆接头-防爆填料函 | 自恢复保险丝_贴片保险丝_力特保险丝_Littelfuse_可恢复保险丝供应商-秦晋电子 | SMN-1/SMN-A ABB抽屉开关柜触头夹紧力检测仪-SMN-B/SMN-C-上海徐吉 | 红酒招商加盟-葡萄酒加盟-进口红酒代理-青岛枞木酒业有限公司 | 防伪溯源|防窜货|微信二维码营销|兆信_行业内领先的防伪防窜货数字化营销解决方案供应商 | 质检报告_CE认证_FCC认证_SRRC认证_PSE认证_第三方检测机构-深圳市环测威检测技术有限公司 | 天空彩票天下彩,天空彩天空彩票免费资料,天空彩票与你同行开奖,天下彩正版资料大全 | 步入式高低温测试箱|海向仪器 | 定做大型恒温循环水浴槽-工业用不锈钢恒温水箱-大容量低温恒温水槽-常州精达仪器 | 铝箔袋,铝箔袋厂家,东莞铝箔袋,防静电铝箔袋,防静电屏蔽袋,防静电真空袋,真空袋-东莞铭晋让您的产品与众不同 | 一体化净水器_一体化净水设备_一体化水处理设备-江苏旭浩鑫环保科技有限公司 | 气力输送_输送机械_自动化配料系统_负压吸送_制造主力军江苏高达智能装备有限公司! | 智能终端_RTU_dcm_北斗星空自动化科技| 学习安徽网| 无锡网站建设-做网站-建网站-网页设计制作-阿凡达建站公司 | 禹城彩钢厂_钢结构板房_彩钢复合板-禹城泰瑞彩钢复合板加工厂 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | 两头忙,井下装载机,伸缩臂装载机,30装载机/铲车,50装载机/铲车厂家_价格-莱州巨浪机械有限公司 | 成都热收缩包装机_袖口式膜包机_高速塑封机价格_全自动封切机器_大型套膜机厂家 | 气动球阀_衬氟蝶阀_调节阀_电动截止阀_上海沃托阀门有限公司 | 新能源汽车教学设备厂家报价[汽车教学设备运营18年]-恒信教具 | 首页|专注深圳注册公司,代理记账报税,注册商标代理,工商变更,企业400电话等企业一站式服务-慧用心 | 环境模拟实验室_液体-气体控温机_气体控温箱_无锡双润冷却科技有限公司 | 杭州营业执照代办-公司变更价格-许可证办理流程_杭州福道财务管理咨询有限公司 | DDoS安全防护官网-领先的DDoS安全防护服务商 | 光照全温振荡器(智能型)-恒隆仪器 | 深圳侦探联系方式_深圳小三调查取证公司_深圳小三分离机构 | 大数据营销公司_舆情监测软件_上海SEO公司-文军营销官网 | 阳光模拟试验箱_高低温试验箱_高低温冲击试验箱_快速温变试验箱|东莞市赛思检测设备有限公司 | 过滤器_自清洗过滤器_气体过滤器_苏州华凯过滤技术有限公司 | 购买舔盐、舔砖、矿物质盐压块机,鱼饵、鱼饲料压块机--请到杜甫机械 |