詳細教程請查看官方文檔:https://requests.kennethreitz.org//zh_CN/latest/user/quickstart.html#urlhtml
入門教程:https://www.cnblogs.com/huaerye/p/9132607.htmlpython
參考文檔:https://www.cnblogs.com/shapeL/p/9045439.htmljson
第一次修改:將get請求和post請求單獨定義,使用過程當中根據不一樣類型的請求直接調用對應的方法;api
def send_get(url,data,headers): res = requests.get(url=url,json=data,headers=headers).json() # return json.dumps(res,sort_keys=True,indent=2) return res def send_post(url,data,headers): res = requests.post(url=url,json=data,headers=headers).json() return json.dumps(res,sort_keys=True,indent=4) #indent默認狀況下爲空,4個空格,sort_keys:按照必定順序展現數據 def run_main(url,headers,method,data=None): res =None if method == 'GET': res = send_get(url,data,headers) else: res = send_post(url,data,headers) return res if __name__=='__main__': url = 'https://oapi.blingabc.com/cms/user-api/student/homework/v2/homeworklist' headers = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI5NTUxNjMxNyIsImV4cCI6MTU3NDMxNzY2NSwiaWF0IjoxNTczNzEyODY1fQ.UjNSQSQpP6umRubppSggYB1W-dkmnfBB5RMNRQUTS9a8IJDmURyPT1bMIWg5nwHL1z7GvvJ-Ch5PKGLEnwOh6g", 'Content-Type': "application/json", } # 數據 data = {"stuNum":"795571161","page":1,"size": 5,"type":0} #url = 'https://oapi.t.blingabc.com/bms/admin-api/specialsubject/v1/save-phonics?id=285' print(send_post(url,data,headers))
第二次修改:用class進行封裝,主函數中建立一個實例run來調用類中的方法服務器
import requests import json class Runmain(): def send_get(self,url,data,headers): res = requests.get(url=url,json=data,headers=headers).json() # return json.dumps(res,sort_keys=True,indent=2) return res def send_post(self,url,data,headers): res = requests.post(url=url,json=data,headers=headers).json() return json.dumps(res,sort_keys=True,indent=4) #indent默認狀況下爲空,4個空格,sort_keys:按照必定順序展現數據 def run_main(self,url,headers,method,data=None): res =None if method == 'GET': res = self.send_get(url,data,headers) else: res = self.send_post(url,data,headers) return res if __name__=='__main__': run = Runmain url = 'https://oapi.blingabc.com/cms/user-api/student/homework/v2/homeworklist' headers = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI5NTUxNjMxNyIsImV4cCI6MTU3NDMxNzY2NSwiaWF0IjoxNTczNzEyODY1fQ.UjNSQSQpP6umRubppSggYB1W-dkmnfBB5RMNRQUTS9a8IJDmURyPT1bMIWg5nwHL1z7GvvJ-Ch5PKGLEnwOh6g", 'Content-Type': "application/json", } # 數據 data = {"stuNum":"795571161","page":1,"size": 5,"type":0} #url = 'https://oapi.t.blingabc.com/bms/admin-api/specialsubject/v1/save-phonics?id=285' print(run.run_main(url,data,headers))
第三次修改:第二次修改,每次都須要實例化後再調用對應的方法;cookie
改進辦法:使用__init__
方法實現:只要實例化類時候就會調用__init__方法app
import requests import json class Runmain(): def __init__(self,url,headers,method,data=None): self.res = self.run_main(url,headers,method,data) def send_get(self,url,data,headers): res = requests.get(url=url,json=data,headers=headers).json() # return json.dumps(res,sort_keys=True,indent=2) return res def send_post(self,url,data,headers): res = requests.post(url=url,json=data,headers=headers).json() return json.dumps(res,sort_keys=True,indent=4) #indent默認狀況下爲空,4個空格,sort_keys:按照必定順序展現數據 def run_main(self,url,headers,method,data=None): res =None if method == 'GET': res = self.send_get(url,data,headers) else: res = self.send_post(url,data,headers) return res if __name__=='__main__': url = 'https://oapi.blingabc.com/cms/user-api/student/homework/v2/homeworklist' headers = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI5NTUxNjMxNyIsImV4cCI6MTU3NDMxNzY2NSwiaWF0IjoxNTczNzEyODY1fQ.UjNSQSQpP6umRubppSggYB1W-dkmnfBB5RMNRQUTS9a8IJDmURyPT1bMIWg5nwHL1z7GvvJ-Ch5PKGLEnwOh6g", 'Content-Type': "application/json", } # 數據 data = {"stuNum":"795571161","page":1,"size": 5,"type":0} #url = 'https://oapi.t.blingabc.com/bms/admin-api/specialsubject/v1/save-phonics?id=285' run = Runmain(url,headers,data,'post') print(run.res)
最後修改後的文件:將形參寫到構造方法中,params=None,data=None,須要時能夠傳入參數;框架
demo.py使用requests get以及post方法進行了封裝,主要是根據傳遞的參數method來對get以及post方法進行分別調用函數
import requests import json class RunMethod(): def __init__(self,url,method,data,headers=None,params=None,): self._url = url self._params = params self._data = data self._headers = headers self._method = method def send_get(self,url,params,headers): res = requests.get(url=url,params=params,headers=headers).json() #return json.dumps(res,sort_keys=True,indent=2) return res def send_post(self,url,data,headers): res = requests.post(url=url,json=data,headers=headers).json() return json.dumps(res,ensure_ascii=False,sort_keys=True,indent=2) def run_method(self): if self._method == 'GET': return self.send_get(self._url,self._params,self._headers) else: return self.send_post(self._url,self._data,self._headers) if __name__=='__main__': # url = 'https://oapi.blingabc.com/cms/user-api/student/homework/v2/homeworklist' headers = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI3OTU1NzExNiIsImV4cCI6MTU3NzE5ODU1MCwiaWF0IjoxNTc2NTkzNzUwfQ.FPTq3sW7MvP9V6GcHuiOgaBQDKbAyv48gqVOiTrE9mxISi53Of3wZwyRG5JtdE_AE4TFgoYk8HK2LrPQqmjQMg", 'Content-Type': "application/json", } # 數據 # data = {"stuNum":"795571161","page":1,"size": 5,"type":0} url = 'https://oapi.t.blingabc.com/bms/admin-api/specialsubject/v1/save-phonics?id=285' #run = RunMethod(url,'post',data,headers,).run_method() run = RunMethod(url,'GET',headers,).run_method() print(run)
詳細用法請參考:https://www.cnblogs.com/huaerye/p/9361892.html工具
在test_method.py文件中則建立測試類以及test方法,在test方法中調用demo.py中的run_main方法,即便用requests模塊向傳遞的接口url地址和請求方式以及請求體發送對應的請求,這裏使用setUp方法則是利用其優先調用而對RunMain類進行實例化
import unittest from demo import Runmain class TestMethod(unittest.TestCase): def test_01(self): url = 'https://oapi.t.blingabc.com/bms/admin-api/specialsubject/v1/save-phonics?id=285' headers = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI5NTUxNjMxNyIsImV4cCI6MTU3NDMxNzY2NSwiaWF0IjoxNTczNzEyODY1fQ.UjNSQSQpP6umRubppSggYB1W-dkmnfBB5RMNRQUTS9a8IJDmURyPT1bMIWg5nwHL1z7GvvJ-Ch5PKGLEnwOh6g", 'Content-Type': "application/json", } res1 = Runmain(url,headers,'GET').run_main() self.assertEqual(res1['code'],10000,"測試經過") #添加斷言 print(res1) def test_02(self): url = 'https://oapi.blingabc.com/cms/user-api/student/homework/v2/homeworklist' headers = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI5NTUxNjMxNyIsImV4cCI6MTU3NDMxNzY2NSwiaWF0IjoxNTczNzEyODY1fQ.UjNSQSQpP6umRubppSggYB1W-dkmnfBB5RMNRQUTS9a8IJDmURyPT1bMIWg5nwHL1z7GvvJ-Ch5PKGLEnwOh6g", 'Content-Type': "application/json", } data = {"stuNum":"795571161","page":1,"size": 5,"type":0} res2 = Runmain(url,headers,'post',data).run_main() self.assertEqual(res2['code'],10000,"測試經過") print(res2) if __name__=='__main__': unittest.main() #三、還能夠將要測試的case添加到unittest.TestSuite集合中執行想要執行的case,若想要所有都執行則須要一個一個的添加 # suite = unittest.TestSuite() # suite.addTest(TestMethod("test_01"))
設計一個接口自動化測試框架
根據接口地址丶接口類型丶請求數據丶預期結果來進行設計,對於須要登陸後才能進行操做的接口那麼則須要進行header cookie等數據的傳遞,自動化測試的難點就是數據依賴。
python操做excel得到內容
python操做excel,須要安裝兩個包,分別是xlrd和xlwt這兩個庫,xlrd這個庫是負責讀取excel數據的,而xlwt庫是負責向excel寫入數據的;
安裝方式:pip3 install xlrd
項目目錄下建立utils工具包,在該包下建立operation_excel.py文件,在該文件中經過導入xlrd包,對excel表的數據進行讀取操做
case表測試用例以下:
重構操做excel函數
根據上一步驟讀取excel表的內容代碼後,進行了一個簡單的封裝,提升代碼的通用性,實現代碼以下:
import xlrd data = xlrd.open_workbook('../case/interface.xls') tables = data.sheets()[0] #獲取表格數據對象 print(tables.nrows) #打印表格行數 print(tables.cell_value(1,2)) #打印excel表格數據,須要傳遞所在座標(x,y) print("*"*50+"封裝先後數據對比"+"*"*50) class OperationExcel(): def __init__(self,file_name=None,sheet_id=None): if file_name: self.file_name = file_name self.sheet_id = sheet_id else: self.file_name='../case/interface.xls' self.sheet_id = 0 self.data = self.get_data() #獲取sheets的內容 def get_data(self): data = xlrd.open_workbook(self.file_name) tables = data.sheets()[self.sheet_id] return tables #獲取單元格的行數 def get_lines(self): tables = self.data return tables.nrows #獲取某一個單元格的內容 def get_cell_value(self,row,col): tables = self.data cell = tables.cell_value(row,col) return cell if __name__=='__main__': opers = OperationExcel() print(opers.get_data().nrows) print(opers.get_lines()) print(opers.get_cell_value(1,2))
結果對比:
學習操做json文件
若是把請求數據所有放到excel裏面,數據量大時,看起來不是很美觀,因此將請求數據單獨弄成一個json文件,將入參名傳入excel就能夠了;
在項目下新建一個dataconfig文件用於存json文件,在該文件下建立student.json,文件內容以下:
在utils工具包下建立operation_json.py文件,在文件中對login.json文件內容進行讀取操做,以及重構json代碼:
import json fp = open('../dataconfig/student.json') res = json.load(fp) #加載某個文件 print(res) print(res['student_login']) print(res['student_login']['mobile']) print("="*50+"封裝先後數據對比"+"="*50) class OperationJson(): def __init__(self, file_path="../dataconfig/student.json"): self.file_path = file_path self.data = self.get_data() def get_data(self): with open(self.file_path) as f: data = json.load(f) return data def get_key_words(self,key=None): if key: return self.data[key] else: return None if __name__=='__main__': opjson = OperationJson() print(opjson.get_key_words()) print(opjson.get_key_words('student_login')) print(opjson.get_key_words('student_login')['mobile'])
數據結果對好比下圖:
封裝獲取常量方法
首先打開excel表格,查看須要獲取的字段有哪些
對excel表的字段進行獲取,在項目目錄下建立名爲data的python包,在該包下建立data_conf.py,代碼就是簡單的獲取對應的變量值,具體以下:
class global_var(): id = '0' # id module = '1' # 接口描述 url = '2' # 接口地址 run = '3' # 是否運行 request_way = '4' # 請求方式 request_header = '5' #是否攜帶header case_depend = '6' # case依賴 response_data_depend = '7' # 依賴的返回數據 data_depend = '8' # 數據依賴字段 request_header_data = '9' #header值 request_data = '10' # 請求數據 expect_result = '11' # 預期結果 reality_result = '12' # 實際結果 def get_id(): return global_var.id def get_module(): return global_var.module def get_url(): return global_var.url def get_run(): return global_var.run def get_request_way(): return global_var.request_way def get_request_header(): return global_var.request_header #case依賴 def get_case_depend(): return global_var.case_depend #依賴的返回數據 def get_response_data_depend(): return global_var.response_data_depend #數據依賴字段 def get_data_depend(): return global_var.data_depend #header值 def get_request_header_data(): return global_var.request_header_data def get_request_data(): return global_var.request_data def get_expect_result(): return global_var.expect_result def get_reality_result(): return global_var.reality_result def get_header_value(): header = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI3OTU1NzExNiIsImV4cCI6MTU3NDI1NDg2MCwiaWF0IjoxNTc0MjU0MjYwfQ.2izK6WXjahTHHI_hupOhio9P5HMPr60HgNLAvg0UQA_EtkP_qC4F4yCHPXXU1mUzPVC1E9CrrrPyUu9KSMlgQA", 'Content-Type': "application/json", } return header
封裝獲取接口數據
在data目錄下建立get_data.py文件,在該文件中對excel表數據以及json數據結合上一步封裝的常量方法整合後的實現,代碼以下:
from util.operation_excel import OperationExcel from util.operation_json import OperationJson from data import data_config class GetData(): def __init__(self): self.op_excel = OperationExcel() def get_case_lines(self): """獲取表格行數""" return self.op_excel.get_lines() def get_is_run(self,row): """獲取case是否運行""" flag = None col = int(data_config.get_run()) run_model = self.op_excel.get_cell_value(row.col) if run_model == 'yes': flag = True else: flag = False return flag def get_is_header(self,row): """是否攜帶header""" col = data_config.get_request_header() header = self.op_excel.get_cell_value(row,col) if header != 'yes': return data_config.get_request_header() else: return None def get_request_method(self,row): """獲取請求方式""" col = data_config.get_request_way() request_method = self.op_excel.get_cell_value(row,col) return request_method def get_request_url(self,row): """獲取url地址""" col = data_config.get_url() url = self.op_excel.get_cell_value(row,col) return url def get_request_data(self,row): """獲取請求數據""" col = data_config.get_url() request_data = self.op_excel.get_cell_value(row,col) if request_data == '': return None return request_data def get_header_value(self, row): """經過excel中的關鍵字去獲取json數據""" op_json = OperationJson() data = op_json.get_key_words(self.get_request_data(row)) return data def get_expect_data(self,row): """獲取預期結果數據""" col = data_config.get_expect_result() expect_data = self.op_excel.get_cell_value(row,col) if expect_data == '': return True return expect_data
def get_request_header_data(self,row): """獲取excel表中的header的數據""" col = int(data_config.get_request_header_data()) header_data = self.op_excel.get_cell_value(row,col) if header_data =='': return None return header_data def get_data_for_header(self,row): '''經過在excel表中獲取的關鍵字數據到json表中獲取對應的數據''' op_header = OperationJson() header_data = op_header.get_key_words(self.get_request_header_data(row)) return header_data
json文件、cese截圖以下:
def get_module_name(self,row): """獲取模塊名""" col = int(data_config.get_module()) module_name = self.op_excel.get_cell_value(row,col) return module_name
截圖以下:
主程序入口修改以下:
結果:
post、get基類的封裝
在util文件下新建立了run_method.py文件,將開始的demo文件複製了過來,其餘未做改動,headers默認參數設置爲了None,用時可傳入headers參數;
import requests import json class RunMethod(): def __init__(self,url,method,data,headers=None,params=None,): self._url = url self._params = params self._data = data self._headers = headers self._method = method def send_get(self,url,params,headers): res = requests.get(url=url,params=params,headers=headers).json() print('status:',res['code']) return json.dumps(res,ensure_ascii=False,sort_keys=True,indent=2) #return res def send_post(self,url,data,headers): res = requests.post(url=url,json=data,headers=headers).json() print('status:',res['code']) return json.dumps(res,ensure_ascii=False,sort_keys=True,indent=2) def run_method(self): if self._method == 'GET': return self.send_get(self._url,self._params,self._headers) else: return self.send_post(self._url,self._data,self._headers) if __name__=='__main__': # url = 'https://oapi.blingabc.com/cms/user-api/student/homework/v2/homeworklist' headers = { 'token': "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJjb20ueGRmLmJsaW5nIiwiYXVkIjoiY2xpZW50IiwidXNlcmNvZGUiOiI3OTU1NzExNiIsImV4cCI6MTU3NzE5ODU1MCwiaWF0IjoxNTc2NTkzNzUwfQ.FPTq3sW7MvP9V6GcHuiOgaBQDKbAyv48gqVOiTrE9mxISi53Of3wZwyRG5JtdE_AE4TFgoYk8HK2LrPQqmjQMg", 'Content-Type': "application/json", } # 數據 # data = {"stuNum":"795571161","page":1,"size": 5,"type":0} url = 'https://oapi.t.blingabc.com/bms/admin-api/specialsubject/v1/save-phonics?id=285' #run = RunMethod(url,'post',data,headers,).run_method() run = RunMethod(url,'GET',headers,).run_method() print(run)
主流程封裝及錯誤解決調試
首先在項目目錄下新建一個名爲main的python包,在該包下建立名爲run_test的py文件,該文件爲主程序啓動文件,代碼的邏輯就是將前面封裝的方法進行了調用核心就是讀取excel表的數據,經過讀取到的數據,發送請求,其中包括某一些變量的判斷,根據該判斷而後到json數據中獲取請求的數據,代碼以下
from util.run_method import RunMethod from data.get_data import GetData class RunTest(): def __init__(self): self.data = GetData() def run(self): res = None row_counts = self.data.get_case_lines() # 獲取excel表格行數 #print(row_counts) for row_count in range(1,row_counts): #循環行數,第一行排除, url = self.data.get_request_url(row_count) # y行不變,遍歷獲取x列的請求地址 method = self.data.get_request_method(row_count) # y行不變,遍歷獲取x列的請求方式 is_run = self.data.get_is_run(row_count) # y行不變,遍歷獲取x列的是否運行 data = self.data.get_data_for_json(row_count) # y行不變,遍歷獲取x列的請求數據 #header = self.data.get_is_header(row_count) header = self.data.get_data_for_header(row_count) module = self.data.get_module_name(row_count) expect = self.data.get_expect_data(row_count) case_dependent = self.data.get_case_dependent(row_count) # case依賴 print("模塊名:", module) print('請求地址:', url) print('請求方式:', method) print('是否運行:', is_run) print('請求數據:', data) print('請求頭:', header) print('預期結果:', expect) if is_run: res = RunMethod(url,method,data,header).run_method() return res if __name__=='__main__': #run = RunTest() #run.run() print('res:', RunTest().run())
運行run_test,成功的將excel以及json數據正確打印出來,返回res服務器返回結果:
獲取接口返回狀態
在發送請求數據核心代碼中,進行打印返回的狀態碼status值
結果數據:
判斷預期結果與返回結果是否一致
import json class CommonUtil: def is_contains(self,expect,reality): """ 判斷一個字符串是否在另一個字符串中 :param expect: 查找的字符串 :param reality: 被查找的字符串 """ flag = None reality = json.loads(reality) expect = json.loads(expect) if expect['code'] == reality['code']: flag = True else: flag = False return flag
case截圖:
run_test.py主程序入口修改:導入common_assert文件類並實例化類,調用is_contains方法來根據其返回值判斷測試是否經過,須要註釋掉res響應數據,利於查看測試結果
結果以下:
將測試結果寫入到excel中
首先在operation_excel.py中定義一個方法,該方法實現讀取excel的數據,並進行copy複製,而後再write方法將數據寫入到座標位置
def write_reality_result_data(self,row,col,value): """將實際結果寫入excel對應字段中""" read_data = xlrd.open_workbook(self.file_name) # 打開excel文件 write_data = copy(read_data) # 拿到excel內容句柄 sheet_data = write_data.get_sheet(0) # 複製文件,讓xlutils相關處理 sheet_data.write(row,col,value) # 將數據寫入到ex文件的指定單元格中 write_data.save(self.file_name) # 保存
而後在get_data.py中須要定義一個方法,在該方法中核心邏輯爲獲取y座標的值
def write_reality_data(self,row,value): """寫入數據""" col = int(data_config.get_reality_result()) self.op_excel.write_reality_result_data(row,col,value)
最後在啓動文件中,調用get_data模塊中的write_reality_data方法,並將剩餘的x座標的值以及data數據傳遞給最終的核心方法write_reality_result_data來完成對excel表中的實際結果數據的寫入;
結果如圖:
數據依賴問題從設計思路開始
一個接口的返回結果下一個接口的請求值中用到;
好比個人訂單接口以及返回數據:
以及個人訂單詳情接口:
數據依賴問題方法封裝之經過case_id獲取case數據
在excel測試數據中case依賴丶依賴的返回數據丶數據依賴這三個字段是根據當前的接口的請求數據中是否須要從其餘接口的響應中獲取,根據上一步中的分析,進行以下填寫:
注意:在excel表中依賴返回數據中添加的返回響應的關鍵字必須是以這種格式進行層級關係的填寫;
在operation_excel.py中定義以下方法,根據傳入的case_id值來獲取excel表字段的行數據
# 如下的4個方法根據傳入的case_id值來獲取excel表字段的行數據 def get_rows_data(self, case_id): """根據對應case_id找到對應行的內容""" row_num = self.get_row_num(case_id) row_datas = self.get_row_values(row_num) #print(row_datas) return row_datas def get_row_num(self, case_id): """根據對應的case_id找到對應的行號""" num = 0 col_datas = self.get_col_values() for col_data in col_datas: if case_id == col_data: return num num+=1 return num def get_row_values(self,row=None): """根據行號,找到該行的全部數據""" tables = self.data if row is not None: row_data = tables.row_values(row) else: row_data = tables.row_values(1) return row_data def get_col_values(self,col=None): """根據列號,找到該列的數據""" if col !=None: col_data = self.data.col_values(col) else: col_data = self.data.col_values(0) return col_data
調用以上方法測試獲取case_id爲student_01所在的行全部數據
數據依賴問題之根據規則提取響應數據
在data目錄下新建一個dependent_data.py文件用於處理數據依賴,就是獲取到傳入的case_id所在的行的全部數據,再從該數據中將數據依賴字段提取orderCode值便可;
from util.operation_excel import OperationExcel # 導入操做excel類 from util.run_method import RunMethod # 導入執行接口類 from data.get_data import GetData # 導入獲取數據類 from jsonpath_rw import jsonpath,parse import json class DependentData: def __init__(self,case_id): self.case_id = case_id self.oper_excel = OperationExcel() # 操做excel的類 self.data = GetData() # 獲取excel 數據的類 self.run = RunMethod() #發送接口數據 def get_case_line_data(self): """經過case_id去獲取依賴case_id的整行數據""" rows_data = self.oper_excel.get_rows_data(self.case_id) return rows_data def run_dependent_case(self): """"執行依賴測試,獲取依賴case所在的整行數據並返回結果""" row_num = self.oper_excel.get_row_num(self.case_id) # 根據case_id獲取行號 request_url = self.data.get_request_url(row_num) # 獲取依賴的url request_method = self.data.get_request_method(row_num) #獲取請求方式 request_header = self.data.get_data_for_header(row_num) # 獲取依賴的header request_data = self.data.get_data_for_json(row_num) # 獲取依賴的請求數據 is_run = self.data.get_is_run(row_num) if is_run: res = self.run.run_method(request_url,request_method,request_data,request_header) #print(res) #print(json.loads(res['data'])) return json.loads(res)
'''對上一部分中的返回響應結果進行關鍵字提取,將提取代碼封裝,
首先是調用data_get模塊中的get_dependent_key方法獲取依賴的返回數據中的key,也就是excel表中的value值,
而後再調用run_dependent_case方法獲取返回的響應數據,經過依賴的返回數據中的key,來提取響應數據中的value值,
這裏須要安裝jsonpath-rw,經過其parse方法來定義path規則,經過該規則找到返回的響應數據中的key的數據集,經過列表生成式將第0個元素進行返回'''
def get_data_for_key(self,row): """獲取依賴字段的響應數據:經過執行依賴測試case來獲取響應數據,響應中某個字段數據做爲依賴key的value """ depend_data = self.data.get_depend_key(row) #獲取依賴的返回數據key, data.list[0].orderCode response_data = self.run_dependent_case() #執行依賴case返回結果 student_01的響應結果 json_rule = parse(depend_data) #查找到響應結果 madle = json_rule.find(response_data) return [match.value for match in madle][0] # for循環遍歷
而後在json文件中,須要定義orderCode的json數據,請留意請求數據中的orderCode得值,由於在接下來的測試代碼中會自動的去跟新orderCode的值
回到run_test模塊中的for循環中進行獲取,判斷當excel表中的數據依賴字段的值不爲空是,則經過實例化HandleData,並調用類中的核心方法get_data_for_key,在該核心方法中又調用run_dependent_case向接口發送請求數據,並將服務器返回的數據返回回來,在get_data_for_key中使用jsonpath_rw中的parse方法進行創建path規則,最終提取到咱們想要的返回數據中的orderCode鍵的值,進行打印測試,
run_test.py
from util.run_method import RunMethod from data.get_data import GetData from util.common_assert import CommonUtil from data.dependent_data import DependentData class RunTest(): def __init__(self): self.data = GetData() self.com_util = CommonUtil() self.runmethod = RunMethod() def run(self): res = None row_counts = self.data.get_case_lines() # 獲取excel表格行數 #print(row_counts) for row_count in range(1,row_counts): #循環行數,第一行排除, url = self.data.get_request_url(row_count) # y行不變,遍歷獲取x列的請求地址 method = self.data.get_request_method(row_count) # y行不變,遍歷獲取x列的請求方式 is_run = self.data.get_is_run(row_count) # y行不變,遍歷獲取x列的是否運行 data = self.data.get_data_for_json(row_count) # y行不變,遍歷獲取x列的請求數據 #header = self.data.get_is_header(row_count) header = self.data.get_data_for_header(row_count) module = self.data.get_module_name(row_count) expect = self.data.get_expect_data(row_count) data_dependent = self.data.get_data_dependent(row_count) #數據依賴 case_dependent = self.data.get_case_dependent(row_count) # case依賴 # 當數據依賴不爲空時,則實例化Dependent_data模塊中的DependentData類,並調用類中的get_data_for_key方法將須要的數據獲取到 if data_dependent != None: self.dd = DependentData(case_dependent) dependent_response_data = self.dd.get_data_for_key(row_count) #dependent_response_data:返回獲取的訂單編號 print(dependent_response_data) data[data_dependent] = dependent_response_data #將請求數據data中的值更新爲藉口依賴返回數據中的值 print("模塊名:", module) print('請求地址:', url) print('請求方式:', method) print('是否運行:', is_run) print('請求數據:', data) print('請求頭:', header) print('預期結果:', expect) if is_run: res = self.runmethod.run_method(url,method,data,header) # if self.com_util.is_contains(expect,res): # print("測試經過") # #self.data.write_reality_data(row_count,'pass') # else: # print("測試失敗") # #self.data.write_reality_data(row_count,'fail') print("*"*60+"分割線"+"*"*60) return res if __name__=='__main__': run = RunTest() print('res:',run.run())
注意:這塊更新訂單號有點問題,稍後在補
case運行結果統計
稍後再補
發送郵件
在util文件夾中新建send_email文件,寫入一下代碼
import smtplib from email.mime.text import MIMEText class SendEmail(object): global send_user global pwd global email_host def send_mail(self,user_list,content,sub): """ :param user_list: 收件人列表 :param content: 郵件內容 :param sub: 主題 :return: """ send_user = "18738563863@163.com" #發送人 password = "" #受權碼 email_host = "smtp.163.com" sender_msg = "flowers"+"<"+send_user+">" message = MIMEText(content, _subtype='plain', _charset='utf-8') # 三個參數:第一個爲文本內容,第二個 plain 設置文本格式,plain表示純文本,第三個 utf-8 設置編碼 message['Subject'] = sub #發送標題 message['From'] = sender_msg #發件人姓名 message['To'] = ";".join(user_list) #接收人 server = smtplib.SMTP() server.connect(email_host) server.login(send_user,password) #login()方法用來登錄smtp服務器 server.sendmail(sender_msg,user_list,message.as_string()) #sendmail()方法就是發郵件,因爲能夠一次發給多我的,因此傳入一個list,郵件正文是一個str,as_string()把MIMEText對象變成str server.close() #定義send_main方法,該方法用於自動化測試結果的統計 def send_main(self, pass_num, fail_num): pass_num = float(pass_num) fail_num = float(fail_num) count_nums = pass_num + fail_num # 計算經過率 # pass_result = "%.2f%%" %(pass_num/count_nums*100) # fail_result = "%.2f%%" %(fail_num/count_nums*100) user_list = ['1297839924@qq.com'] sub = "接口自動化測試報告" content = "本次自動化測試一共運行的接口數爲:%d個, 經過個數爲:%d個, 失敗個數爲:%d個" %(count_nums,pass_num,fail_num) #content = "本次自動化測試一共運行的接口數爲:%d個, 經過個數爲:%d個, 失敗個數爲:%d個, 經過率爲:%s, 失敗率爲:%s" %(count_nums,pass_num,fail_num,pass_result,fail_result) #print(content) self.send_mail(user_list,content,sub) if __name__ == '__main__': user_list = ['1297839924@qq.com'] #接收人 sub = "測試郵件" content = "這是用來測試的郵件!!!" # #SendEmail().send_mail(user_list,content,sub) SendEmail().send_main(15,20)
問題1:接口get方法,取execl也是get,提示不支持請求方法?
若是run_method.py文件中判斷是if self._method == 'GET':,那麼case文件中也要大寫GET;
參考文章:https://blog.csdn.net/qq_41782425/article/details/93235627
僅供參考,尊重原創