免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      基于數(shù)據(jù)驅(qū)動(dòng)的接口自動(dòng)化框架封裝

      基于數(shù)據(jù)驅(qū)動(dòng)的接口自動(dòng)化框架封裝

      每天進(jìn)步一點(diǎn)點(diǎn),關(guān)注我們哦,每天分享測試技術(shù)文章

      本文章出自【碼同學(xué)軟件測試】

      碼同學(xué)公眾號(hào):自動(dòng)化軟件測試

      碼同學(xué)抖音號(hào):小碼哥聊軟件測試

      1.數(shù)據(jù)驅(qū)動(dòng)框架設(shè)計(jì)

      1.框架結(jié)構(gòu)

      • common: 這是一個(gè)package,主要用來存儲(chǔ)所有的底層代碼封裝
      • logs: 這是一個(gè)目錄,主要用來存放日志文件
      • report: 這是一個(gè)目錄,里邊的data表示測試結(jié)果數(shù)據(jù),里邊的html表示測試報(bào)告,注意這兩個(gè)目錄都是每次執(zhí)行測試時(shí)自動(dòng)生成的
      • testcases: 這是一個(gè)目錄,主要用來存儲(chǔ)excel文件,excel文件里是接口測試的相關(guān)數(shù)據(jù)
      • conftest.py: 重寫pytest自帶的一個(gè)內(nèi)置函數(shù)的,統(tǒng)一管理自定義fixture的
      • pytest.ini: pytest相關(guān)的配置參數(shù)
      • run.py: 是整個(gè)框架執(zhí)行的入口

      2.excel數(shù)據(jù)規(guī)則設(shè)計(jì)

      按照一定的維度進(jìn)行分類,每個(gè)分類可以當(dāng)做一個(gè)sheet工作表

      • 全局變量
      • 主要用來管理我們的公共數(shù)據(jù)

      變量名稱

      變量值

      host

      http://82.xxx74.xx:xxxx

      username

      18866668888

      password

      123456

      • 接口默認(rèn)參數(shù)
      • 通常在一個(gè)項(xiàng)目中,參數(shù)如果很多的時(shí)候,我們針對測試用例去傳遞數(shù)據(jù)就會(huì)很麻煩,所以我們針對每個(gè)接口的默認(rèn)參數(shù)數(shù)據(jù)進(jìn)行單獨(dú)管理,在測試時(shí)只需要針對當(dāng)前測試用例傳遞你要測試的某個(gè)字段值即可,其他字段統(tǒng)統(tǒng)來自于默認(rèn)參數(shù)
      • 填寫參數(shù)的規(guī)則:對于接口參數(shù)可能會(huì)有多種類型,表單的,查詢的,json的,文件的等等

      表單類型時(shí):

      { “data”:{ “xxx”:”xxjsdhdh” }}

      查詢參數(shù):

      { “params”:{ “xxx”:”xxjsdhdh” }}

      json參數(shù):

      { “json”:{ “xxx”:”xxjsdhdh” }}

      混合參數(shù),比如既有表單又有查詢:

      { “params”:{ “xxx”:”xxjsdhdh” }, “data”:{ “ddd”:”ddff” }}

      接口名稱

      默認(rèn)參數(shù)

      登錄

      { “data”:{ “username”:”${username}”, “password”:”${password}” } }

      新增客戶

      { “json”:{ “entity”: { “customer_name”: “沙陌001”, “mobile”: “18729399607”, “telephone”: “01028375678”, “website”: “http://mtongxue.com/”, “next_time”: “2022-05-12 00:00:00”, “remark”: “這是備注”, “address”: “北京市,北京城區(qū),昌平區(qū)”, “detailAddress”: “霍營地鐵口”, “location”: “”, “lng”: “”, “lat”: “” } } }

      新建聯(lián)系人

      { “json”:{ “entity”: { “name”: “沙陌001聯(lián)系人”, “customer_id”:”${customerId}”, “mobile”: “18729399607”, “telephone”: “01028378782”, “email”: “sdsdd@qq.com”, “post”: “采購部員工”, “address”: “這是地址”, “next_time”: “2022-05-10 00:00:00”, “remark”: “這是備注” } } }

      新建產(chǎn)品

      { “json”:{ “entity”: { “name”: “python全棧自動(dòng)化”, “category_id”: 23, “num”: “98888”, “price”: “6980”, “description”: “接口/web/app/持續(xù)集成” } } }

      • 測試集合管理
      • 測試集合管理 主要是為了控制要執(zhí)行哪些測試集合,以及測試集合執(zhí)行的順序
      • 測試集合名稱:對應(yīng)的就是某個(gè)測試集合的sheet工作表名稱
      • 是否執(zhí)行:只有值是y時(shí)才會(huì)被執(zhí)行,其他值不會(huì)被執(zhí)行
      • 測試集合名稱是否執(zhí)行新增客戶接口測試集合y新建聯(lián)系人接口測試集合y新建產(chǎn)品接口測試集合y
      • 測試集合
      • 每個(gè)測試集合在excel里是一個(gè)單獨(dú)的sheet工作表,他負(fù)責(zé)某個(gè)模塊或者某個(gè)接口相關(guān)的測試用例數(shù)據(jù)管理,一個(gè)測試集合中是可以存在多個(gè)測試用例的
        • 序號(hào):僅僅只是個(gè)標(biāo)識(shí),沒啥作用
        • 用例名稱:一個(gè)用例可能會(huì)有多個(gè)接口的先后調(diào)用,在excel里一行數(shù)據(jù)就是針對一個(gè)接口的調(diào)用,多行數(shù)據(jù)就是多個(gè)接口的調(diào)用,如果一個(gè)用例需要用多行數(shù)據(jù),那么這幾行的用例名稱保持一致
        • 接口名稱:該列主要是為了和接口默認(rèn)參數(shù)中的接口名稱進(jìn)行關(guān)聯(lián),通過接口名稱得到該接口對應(yīng)的默認(rèn)參數(shù),然后再根據(jù)測試數(shù)據(jù)來決定參數(shù)是什么
        • 接口地址:表示接口地址,在接口地址里域名幾乎都是相同的,或者說是公共的,所以我們將域名作為了公共變量進(jìn)行存儲(chǔ),那么在這里需要調(diào)用公共變量域名,調(diào)用方式${host},host就是公共變量中的一個(gè)變量
        • 請求方式:get/post/put/delete
        • 接口頭信息:指的就是headers,對于一個(gè)接口來說不一定有特殊的頭信息,那么就不填,如果有需要按照如下格式進(jìn)行填寫,以json格式字符串的方式:
        • token是要從登錄接口的返回值中提取的,提取之后保存到一個(gè)變量中,咱們這里保存的變量名稱叫做token,所以在這里引用了變量token,引用方式就是${token}
        • {“Admin-Token”:”${token}”}
        • 假如特殊的頭信息有多個(gè),寫法就是在json字符串中繼續(xù)追加鍵值對,比如:
        • {“Admin-Token”:”${token}”,”Content-Type”:”application/json”}
        • 測試數(shù)據(jù):指的是在接口發(fā)起調(diào)用時(shí)傳遞的你要測試的某個(gè)數(shù)據(jù),對于一個(gè)接口來說參數(shù)有很多,但是我們每次測試時(shí),可能只是針對一兩個(gè)參數(shù)進(jìn)行測試,可以借助之前所學(xué)的通過jsonpath去匹配某些參數(shù),并且替換他們的值
        • 設(shè)計(jì)思路:
        • 一個(gè)json格式的字符串,其中參數(shù)類型分為data、json、params、files
        • 其中的key是你要替換的目標(biāo)參數(shù)對應(yīng)的jsonpath,value就是該參數(shù)對應(yīng)的新值,也就是測試數(shù)據(jù)
        • { “json”:{ “$.entity.customer_id”:999999999, }}
        • 如果要替換多個(gè)參數(shù):
        • { “json”:{ “$.entity.name”:”自動(dòng)化${{cur_timestamp()}}”, “$.entity.num”:”${timestamp}}” }}
        • 響應(yīng)提?。喉憫?yīng)提取是為了從當(dāng)前接口的返回值中提取某些信息,保存在變量中,以便后續(xù)接口要使用時(shí)進(jìn)行變量引用,這也是我們常說的關(guān)聯(lián)
        • 比如每個(gè)接口都要用到token,token是登錄接口產(chǎn)生的,所以登錄的響應(yīng)提取里要寫提取內(nèi)容,規(guī)則是以json格式的字符串作為標(biāo)準(zhǔn)格式,其中key是要保存的變量名稱,value是要提取的參數(shù)對應(yīng)的jsonpath表達(dá)式
        • { “token”:”$.Admin-Token”}
        • 期望響應(yīng)狀態(tài)碼:http響應(yīng)狀態(tài)碼期望值
        • 期望響應(yīng)信息:表示我們要針對接口的響應(yīng)信息中的某些參數(shù)進(jìn)行斷言,設(shè)計(jì)規(guī)則如下:
        • 依然是json格式的字符串,最外層是一個(gè)列表,里邊套的是多個(gè)字典,一個(gè)字典就是一個(gè)參數(shù)的斷言。
        • 每個(gè)字典的格式是必須包括兩個(gè)鍵值對,一個(gè)actual表示實(shí)際值的key,實(shí)際值的value是參數(shù)對應(yīng)的jsonpath表達(dá)式,一個(gè)expect表示期望值的key,期望值的value是期望內(nèi)容
        • [ { “actual”:”$.code”, “expect”:500, }, { “actual”:”$.msg”, “expect”:”產(chǎn)品編號(hào)已存在,請校對后再添加!”, }]

      2.數(shù)據(jù)驅(qū)動(dòng)框架底層代碼實(shí)現(xiàn)

      1.創(chuàng)建項(xiàng)目

      依賴于設(shè)計(jì)去創(chuàng)建項(xiàng)目結(jié)構(gòu)

      2.excel數(shù)據(jù)讀取

      在common這個(gè)package下創(chuàng)建一個(gè)python文件,叫做testcase_util.py

      # !/usr/bin python3 # encoding: utf-8 -*- # @file : testcase_util.py # @author : 沙陌 Matongxue_2# @Time : 2022-05-10 11:27# @Copyright: 北京碼同學(xué)import openpyxl# 讀取全局變量sheet工作表def get_variables(wb): sheet_data = wb[‘全局變量’] variables = {} # 用來存儲(chǔ)讀到的變量,名稱是key,值是value lines_count = sheet_data.max_row # 獲取總行數(shù) for l in range(2,lines_count+1): key = sheet_data.cell(l,1).value value = sheet_data.cell(l,2).value variables[key] = value return variablesdef get_api_default_params(wb): sheet_data = wb[‘接口默認(rèn)參數(shù)’] api_default_params = {} # 用來存儲(chǔ)讀到的變量,名稱是key,值是value lines_count = sheet_data.max_row # 獲取總行數(shù) for l in range(2,lines_count+1): key = sheet_data.cell(l,1).value value = sheet_data.cell(l,2).value api_default_params[key] = value return api_default_params# 獲取要執(zhí)行的測試集合名稱def get_casesuitename(wb): sheet_data = wb[‘測試集合管理’] lines_count = sheet_data.max_row # 獲取總行數(shù) cases_suite_name = [] # 用來存儲(chǔ)要執(zhí)行的測試集合名稱 for l in range(2,lines_count+1): flag = sheet_data.cell(l,2).value if flag == ‘y’: suite_name = sheet_data.cell(l,1).value cases_suite_name.append(suite_name) return cases_suite_name# 需要根據(jù)要執(zhí)行的測試集合名稱來讀取對應(yīng)的測試用例數(shù)據(jù)def read_testcases(wb,suite_name): sheet_data = wb[suite_name] lines_count = sheet_data.max_row # 獲取總行數(shù) cols_count = sheet_data.max_column # 獲取總列數(shù) “”” 規(guī)定讀出來的測試數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)如下: { “新增客戶正確”:[ [‘apiname’,’接口地址’,’請求方式’,’頭信息’,….], [‘apiname’,’接口地址’,’請求方式’,’頭信息’,….], ], “新增客戶失敗-用戶名為空”:[ [‘apiname’,’接口地址’,’請求方式’,’頭信息’,….] ], “新增客戶失敗-手機(jī)號(hào)格式不正確”:[ [‘apiname’,’接口地址’,’請求方式’,’頭信息’,….] ] } “”” cases_info = {} #用來存儲(chǔ)當(dāng)前測試集合中的所有用例信息的 for l in range(2,lines_count+1): case_name = sheet_data.cell(l,2).value # 測試用例名稱 lines = [] # 用來存儲(chǔ)當(dāng)前行測試數(shù)據(jù)的 for c in range(3,cols_count+1): cell = sheet_data.cell(l,c).value # 當(dāng)前單元格數(shù)據(jù) if cell == None: # 處理空單元格 cell = ” lines.append(cell) # 判斷當(dāng)前用例名稱是否已存在于cases_info中 # 如果不存在,那就是直接賦值 # 否則就是在原來的基礎(chǔ)上追加 if case_name not in cases_info: cases_info[case_name] = [lines] else: cases_info[case_name].append(lines) return cases_info# 整合所有要執(zhí)行的測試用例數(shù)據(jù),將其轉(zhuǎn)成pytest參數(shù)化需要的數(shù)據(jù)結(jié)構(gòu)格式def get_all_testcases(wb): “”” 整合后的數(shù)據(jù)結(jié)構(gòu)是 [ [‘新增客戶接口測試集合’,’新增客戶正確’,[[],[]]], [‘新增客戶接口測試集合’,’新增客戶失敗-用戶名為空’,[[],[]]], [‘新增客戶接口測試集合’,’新增客戶失敗-手機(jī)號(hào)格式不正確’,[[],[]]], [‘新建產(chǎn)品接口測試集合’,’新建產(chǎn)品正確’,[[],[]]], [‘新建產(chǎn)品接口測試集合’,’新建產(chǎn)品失敗-產(chǎn)品編碼重復(fù)’,[[],[]]], ] :param wb: :return: “”” test_data = [] # 用來存儲(chǔ)所有測試數(shù)據(jù) # 獲取所有要執(zhí)行的測試集合名稱 cases_suite_name = get_casesuitename(wb) for suite_name in cases_suite_name: # 遍歷讀取每個(gè)要執(zhí)行的測試集合sheet工作表中的測試用例數(shù)據(jù) cur_cases_info = read_testcases(wb,suite_name) # 是個(gè)字典 for key,value in cur_cases_info.items(): # key實(shí)際上就是測試用例名稱,value實(shí)際上測試用例多行數(shù)據(jù)信息 case_info = [suite_name,key,value] test_data.append(case_info) return test_dataif __name__ == ‘__main__’: wb = openpyxl.load_workbook(‘../testcases/CRM系統(tǒng)接口測試用例.xlsx’) # print(get_variables(wb)) # print(get_api_default_params(wb)) # print(get_casesuitename(wb)) # print(read_testcases(wb,’新增客戶接口測試集合’)) print(get_all_testcases(wb))

      3.接口調(diào)用底層方法封裝

      在common目錄下創(chuàng)建一個(gè)client.py,寫上如下代碼

      # !/usr/bin python3 # encoding: utf-8 -*- # @file : client.py # @author : 沙陌 Matongxue_2# @Time : 2022-05-11 10:01# @Copyright: 北京碼同學(xué)import jsonpathimport requestssession = requests.session()class RequestsClient: def send(self,url,method,**kwargs): try: self.resp = session.request(url=url,method=method,**kwargs) except BaseException as e: raise BaseException(f’接口發(fā)起異常:{e}’) return self.resp # 針對jsonpath的數(shù)據(jù)提取封裝一個(gè)方法 # 第一個(gè)參數(shù)指的是你要匹配的數(shù)據(jù)的jsonpath表達(dá)式 # 第二個(gè)指的是你想返回匹配到的第幾個(gè),默認(rèn)是0返回第一個(gè) def extract_resp(self,json_path,index=0): # 注意有的接口是沒有返回信息的,返回信息是空的 text = self.resp.text # 獲取返回信息的字符串形式 if text != ”: resp_json = self.resp.json() # 獲取響應(yīng)信息的json格式 # 如果能匹配到值,那么res就是個(gè)列表 # 如果匹配不到res就是個(gè)False res = jsonpath.jsonpath(resp_json,json_path) if res: if index < 0: # 如果index小于0 ,我認(rèn)為你要匹配到的所有結(jié)果 return res else: return res[index] else: print('沒有匹配到任何東西') else: raise BaseException('接口返回信息為空,無法提取')if __name__ == '__main__': client = RequestsClient() client.send(url= 'http://82.156.74.26:9099/login', method='post', data={'username':'18866668888','password':'123456'}) print(client.extract_resp('Admin-Token'))

      4.輔助函數(shù)封裝及引用定義

      在我們測試時(shí),有的參數(shù)并不能夠?qū)懰溃赃@個(gè)時(shí)候我們希望某個(gè)參數(shù)在每次執(zhí)行時(shí)都是動(dòng)態(tài)變化的,那么就需要我們封裝一些輔助隨機(jī)函數(shù)來幫我們完成數(shù)據(jù)的動(dòng)態(tài)變化

      在common目錄下建一個(gè)util_func.py的文件,在其中寫上我們需要用到的輔助函數(shù)

      隨機(jī)數(shù)生成我們可以用一個(gè)第三方庫faker

      # !/usr/bin python3 # encoding: utf-8 -*- # @file : run.py # @author : 沙陌 Matongxue_2# @Time : 2022-05-10 11:24# @Copyright: 北京碼同學(xué)import hashlibimport timefrom faker import Fakerfake = Faker(locale=’zh_CN’)def rdm_phone_number(): return fake.phone_number()def cur_timestamp():#到毫秒級(jí)的時(shí)間戳 return int(time.time() * 1000)def cur_date():# 2021-12-25 return fake.date_between_dates()def cur_date_time():# 2021-12-25 10:07:33 return fake.date_time_between_dates()def rdm_date(pattern=’%Y-%m-%d’): return fake.date(pattern=pattern)def rdm_date_time(): return fake.date_time()def rdm_future_date_time(end_date): return fake.future_datetime(end_date=end_date)def md5(data): data = str(data) return hashlib.md5(data.encode(‘UTF-8’)).hexdigest()if __name__ == ‘__main__’: print(rdm_phone_number()) print(rdm_date()) print(rdm_date_time()) print(cur_date()) print(cur_timestamp()) print(cur_date_time()) print(rdm_future_date_time(‘+60d’)) print(md5(‘123456’))

      在excel中需要用到動(dòng)態(tài)函數(shù)時(shí),調(diào)用規(guī)則是${{md5(123456)}} 再比如${{rdm_future_date_time(+60d)}}

      免費(fèi)領(lǐng)取 碼同學(xué)軟件測試 課程筆記+超多學(xué)習(xí)資料+完整視頻+最新面試題,可以轉(zhuǎn)發(fā)文章 + 私信「碼同學(xué)666」獲取資料哦

      5.excel中動(dòng)態(tài)數(shù)據(jù)的正則替換

      • 正則表達(dá)式基本規(guī)則
      • 基本規(guī)則: https://baike.baidu.com/item/正則表達(dá)式/1700215
      • 在線正則調(diào)試:https://tool.oschina.net/regex
      • 代碼封裝
      • 在testcase_util.py文件中增加如下代碼:
      • # 該方法是針對excel中數(shù)據(jù)中存在動(dòng)態(tài)變量時(shí),進(jìn)行變量識(shí)別以及替換的def regx_sub(string,vars_dict): res = re.findall(r’${([A-Za-z_]+?)}’,string) for var_name in res: # print(var_name) value = vars_dict[var_name] # print(value) # 得到變量對應(yīng)的值value,然后用字符串替換的方法替換 string = string.replace(f’${{{var_name}}}’,str(value)) return string# 針對excel數(shù)據(jù)中存在動(dòng)態(tài)函數(shù)調(diào)用時(shí),使用正則匹配并執(zhí)行函數(shù)完成數(shù)據(jù)替換def regx_func_exec(string): res = re.findall(r’${{(.+?)((.*?))}}’,string) for func_method in res: print(func_method) func_name = func_method[0] # 函數(shù)名稱 func_params = func_method[1] # 函數(shù)參數(shù) # 使用python中的反射機(jī)制來實(shí)現(xiàn)函數(shù)執(zhí)行 if hasattr(util_func,func_name): # 如果該函數(shù)在util_func這個(gè)文件中,那么我就去得到該函數(shù)對象 f_method = getattr(util_func,func_name) if func_params == ”: value = f_method() else: value =f_method(func_params) string = string.replace(f’${{{{{func_name}({func_params})}}}}’,str(value)) else: raise BaseException(f'{func_name}不存在’) return string# 統(tǒng)一的針對數(shù)據(jù)做動(dòng)態(tài)變量和動(dòng)態(tài)函數(shù)的替換def regx_sub_data(string,vars_dict): string = regx_sub(string,vars_dict) string = regx_func_exec(string) return string

      6.統(tǒng)一測試方法封裝

      針對框架去封裝一個(gè)執(zhí)行測試的入口,這個(gè)入口是一個(gè)基于pytest參數(shù)化的測試用例,在run.py中實(shí)現(xiàn)

      • 補(bǔ)充json數(shù)據(jù)替換的方法

      在testcases_util.py中增加如下方法:

      def update_value_to_json(json_object,json_path,new_value): json_path_expr = parse(json_path) for match in json_path_expr.find(json_object): path = match.path # 這是獲取到匹配結(jié)果的路徑 if isinstance(path,Index): match.context.value[match.path.index] = new_value elif isinstance(path,Fields): match.context.value[match.path.fields[0]] = new_value return json_object

      • 補(bǔ)充內(nèi)置變量timestamp

      在testcases_util.py中修改下述方法

      def get_variables(wb): sheet_data = wb[‘全局變量’] variables = {} # 用來存儲(chǔ)讀到的變量,名稱是key,值是value lines_count = sheet_data.max_row # 獲取總行數(shù) for l in range(2,lines_count+1): key = sheet_data.cell(l,1).value value = sheet_data.cell(l,2).value variables[key] = value # 增加一個(gè)內(nèi)置變量,叫時(shí)間戳,注意這個(gè)時(shí)間戳是當(dāng)前測試一運(yùn)行就會(huì)產(chǎn)生,產(chǎn)生之后在當(dāng)前測試未完成之前不管調(diào)用 # 多少次,都是一致的 variables[‘timestamp’] = cur_timestamp() return variables

      • run.py里的代碼

      # !/usr/bin python3 # encoding: utf-8 -*- # @file : run.py # @author : 沙陌 Matongxue_2# @Time : 2022-05-10 11:24# @Copyright: 北京碼同學(xué)import openpyxlimport pytestfrom common.client import RequestsClientfrom common.testcase_util import get_all_testcases, get_variables, get_api_default_params, regx_sub_data, update_value_to_jsonwb = openpyxl.load_workbook(‘testcases/CRM系統(tǒng)接口測試用例.xlsx’)# 獲取所有的測試用例數(shù)據(jù)test_data = get_all_testcases(wb)variables = get_variables(wb) # 獲取所有的公共變量,也用來存儲(chǔ)測試過程中產(chǎn)生的動(dòng)態(tài)變量api_default_params = get_api_default_params(wb) # 獲取所有接口的默認(rèn)參數(shù)數(shù)據(jù)@pytest.mark.parametrize(‘suite_name,case_name,case_info_list’,test_data)def test_run(suite_name,case_name,case_info_list): # 創(chuàng)建一個(gè)接口調(diào)用的對象 client = RequestsClient() # case_info_list 是多個(gè)接口的數(shù)據(jù),是一個(gè)列表 for case_info in case_info_list: # case_info 其實(shí)也是一個(gè)列表,表示excel某一行的測試數(shù)據(jù),從接口名稱開始往后 # [‘登錄’, ‘${host}/login’, ‘post’, ”, ”, ‘{“token”:”$.Admin-Token”}’, 200, ‘[{“actual”:”$.code”,”expect”:0}]’] kwargs = {‘verify’:False} #verify表示忽略https的證書 api_name = case_info[0] # 接口名稱 url = case_info[1] # 接口名稱 url = regx_sub_data(url,variables) # 處理url中的動(dòng)態(tài)變量及動(dòng)態(tài)函數(shù)調(diào)用 method = case_info[2] # 接口請求方式 headers = case_info[3] # 接口頭信息 if headers!=”: headers = regx_sub_data(headers,variables) headers = eval(headers) # 將json格式的字符串轉(zhuǎn)換成字典 kwargs[‘headers’] = headers # 測試數(shù)據(jù)并不是接口發(fā)起時(shí)真正的全部參數(shù),需要根據(jù)用戶填入的要測試的數(shù)據(jù)和該接口對應(yīng)的默認(rèn)數(shù)據(jù)進(jìn)行替換以及組合來達(dá)到 # 請求數(shù)據(jù) api_default_param = api_default_params[api_name] # 獲取當(dāng)前行的接口對應(yīng)的默認(rèn)數(shù)據(jù) if api_default_param != ”: api_default_param = regx_sub_data(api_default_param,variables) api_default_param = eval(api_default_param) test_params = case_info[4] # 測試數(shù)據(jù) if test_params != ”: test_params = regx_sub_data(test_params,variables) test_params = eval(test_params) # 解析測試數(shù)據(jù),通過jsonpath去替換默認(rèn)參數(shù)中的數(shù)據(jù) # 邏輯是遍歷測試數(shù)據(jù),判斷測試數(shù)據(jù)中是哪種參數(shù)類型(data/params/json/files),根據(jù)參數(shù)類型去替換默認(rèn)數(shù)據(jù)的對應(yīng)的部分 if ‘json’ in test_params: “”” { “$.entity.name”:”聯(lián)系人${{cur_timestamp()}}”, } “”” for json_path,new_value in test_params[‘json’].items(): api_default_param[‘json’] = update_value_to_json(api_default_param[‘json’],json_path,new_value) if ‘data’ in test_params: for json_path,new_value in test_params[‘data’].items(): api_default_param[‘data’] = update_value_to_json(api_default_param[‘data’],json_path,new_value) if ‘params’ in test_params: for json_path,new_value in test_params[‘params’].items(): api_default_param[‘params’] = update_value_to_json(api_default_param[‘params’],json_path,new_value) if ‘files’ in test_params: for json_path,new_value in test_params[‘files’].items(): api_default_param[‘files’] = update_value_to_json(api_default_param[‘files’],json_path,new_value) test_params = api_default_param # 整合完成測試數(shù)據(jù)和默認(rèn)數(shù)據(jù)之后,將他們分別存儲(chǔ)kwargs中 if ‘json’ in test_params: kwargs[‘json’] = test_params[‘json’] if ‘data’ in test_params: kwargs[‘data’] = test_params[‘data’] if ‘params’ in test_params: kwargs[‘params’] = test_params[‘params’] if ‘files’ in test_params: kwargs[‘files’] = test_params[‘files’] resp = client.send(url=url,method=method,**kwargs) # 發(fā)起請求 expect_status = case_info[6] # 期望的響應(yīng)狀態(tài)碼 assert resp.status_code == expect_status # print(resp.text) extract_resp = case_info[5] # 響應(yīng)提取 if extract_resp != ”: extract_resp = eval(extract_resp) “”” { “token”:”$.Admin-Token” } “”” for key,value in extract_resp.items(): # key就是提取后要保存的變量名稱 # value是你要提取的目標(biāo)字段對應(yīng)的jsonpath表達(dá)式 res = client.extract_resp(value) variables[key] = res expect_resp = case_info[7] # 期望的響應(yīng)信息 if expect_resp != ”: expect_resp = regx_sub_data(expect_resp,variables) expect_resp = eval(expect_resp) “”” [ { “actual”:”$.code”, “expect”:500, }, { “actual”:”$.msg”, “expect”:”產(chǎn)品編號(hào)已存在,請校對后再添加!”, } ] “”” for expect_info in expect_resp: json_path = expect_info[‘actual’] actual_res = client.extract_resp(json_path) expect_res = expect_info[‘expect’] pytest.assume(actual_res==expect_res,f’期望是{expect_res},實(shí)際是{actual_res}’)if __name__ == ‘__main__’: pytest.main() # 該方法會(huì)自動(dòng)掃描當(dāng)前項(xiàng)目中的pytest.ini,根據(jù)其中的配置進(jìn)行執(zhí)行

      7.集成日志收集

      日志收集的目的是在我們用例有失敗時(shí),可以幫助我們?nèi)プ匪輪栴}產(chǎn)生的原因。日志都要收集哪些信息呢?

      主要收集接口發(fā)起以及接口響應(yīng)的各項(xiàng)信息,在什么地方去集成日志可以收集到這些信息?

      • 修改client.py中的代碼如下:
      • # !/usr/bin python3 # encoding: utf-8 -*- # @file : client.py # @author : 沙陌 Matongxue_2# @Time : 2022-05-11 10:01# @Copyright: 北京碼同學(xué)import loggingimport jsonpathimport requestssession = requests.session()class RequestsClient: def __init__(self): self.logger = logging.getLogger(__class__.__name__) def send(self,url,method,**kwargs): self.logger.info(f’接口地址是:{url}’) self.logger.info(f’接口請求方式是:{method}’) for key,value in kwargs.items(): self.logger.info(f’接口的{key}是:{value}’) try: self.resp = session.request(url=url,method=method,**kwargs) self.logger.info(f’接口響應(yīng)狀態(tài)碼是:{self.resp.status_code}’) self.logger.info(f’接口響應(yīng)信息是:{self.resp.text}’) except BaseException as e: self.logger.exception(‘接口發(fā)起異常’) raise BaseException(f’接口發(fā)起異常:{e}’) return self.resp # 針對jsonpath的數(shù)據(jù)提取封裝一個(gè)方法 # 第一個(gè)參數(shù)指的是你要匹配的數(shù)據(jù)的jsonpath表達(dá)式 # 第二個(gè)指的是你想返回匹配到的第幾個(gè),默認(rèn)是0返回第一個(gè) def extract_resp(self,json_path,index=0): # 注意有的接口是沒有返回信息的,返回信息是空的 text = self.resp.text # 獲取返回信息的字符串形式 if text != ”: resp_json = self.resp.json() # 獲取響應(yīng)信息的json格式 # 如果能匹配到值,那么res就是個(gè)列表 # 如果匹配不到res就是個(gè)False res = jsonpath.jsonpath(resp_json,json_path) if res: if index < 0: # 如果index小于0 ,我認(rèn)為你要匹配到的所有結(jié)果 self.logger.info(f'通過{json_path}提取到的結(jié)果是:{res}') return res else: self.logger.info(f'通過{json_path}提取到的結(jié)果是:{res[index]}') return res[index] else: self.logger.warning(f'通過{json_path}沒有提取到結(jié)果') return res else: self.logger.exception('接口返回信息為空,無法提取') raise BaseException('接口返回信息為空,無法提取')if __name__ == '__main__': client = RequestsClient() client.send(url= 'http://82.156.74.26:9099/login', method='post', data={'username':'18866668888','password':'123456'}) print(client.extract_resp('Admin-Token'))
      • 配置pytest.ini文件
      • 在pytest.ini文件中追加如下內(nèi)容:
      • ;critical > error > warning > info > debuglog_cli = truelog_cli_level = INFOlog_format = %(asctime) s [%(filename) s:%(lineno) s] [%(levelname) s] %(message) slog_date_format=%Y-%m-%d %H:%M:%Slog_file = logs/test.log
        • log_cli = true: 表示日志要輸出到控制臺(tái)上
        • log_cli_level=INFO: 表示要收集的日志等級(jí),日志分為critical > error > warning > info > debug
        • log_format = xxx:表示日志的格式
        • log_date_format = xxx: 表示日志中的時(shí)間格式
        • log_file = logs/test.log: 日志收集存儲(chǔ)的文件,要注意他的路徑

      8.allure測試報(bào)告集成

      • 收集pytest執(zhí)行的測試結(jié)果數(shù)據(jù)

      需要用到一個(gè)python的第三方庫,叫做allure-pytest,所以先安裝

      在pytest.ini中追加allure結(jié)果數(shù)據(jù)收集的命令參數(shù)

      addopts = -sv –alluredir ./report/data –clean-alluredir

      –alluredir ./report/data :表示收集到的測試結(jié)果存放在report/data目錄中

      –clean-alluredir :表示每次執(zhí)行收集結(jié)果前都先清除上一次的結(jié)果

      • 生成html報(bào)告

      需要用到allure的命令行工具,命令行工具下載地址:

      https://github.com/allure-framework/allure2/releases

      如果無法訪問,那么就下載我提供的allure-2.11.0.zip

      下載之后解壓即可,解壓以后去配環(huán)境變量path,配如下路徑

      配完以后,在命令行中輸入allure –version能看到版本號(hào),就說明配置好了

      記得重啟pycharm,在pycharm進(jìn)入終端輸入如下命令:

      allure generate ./report/data -o ./report/html

      報(bào)告打開:

      每次命令行輸入命令比較麻煩,可以直接將生成命令集成在代碼中,修改run.py中的main里代碼如下:

      if __name__ == ‘__main__’: pytest.main() # 該方法會(huì)自動(dòng)掃描當(dāng)前項(xiàng)目中的pytest.ini,根據(jù)其中的配置進(jìn)行執(zhí)行 os.system(‘allure generate ./report/data -o ./report/html –clean’)

      • 優(yōu)化allure測試報(bào)告展示

      增加測試用例的層級(jí)劃分

      修改run.py中的代碼如下:

      # !/usr/bin python3 # encoding: utf-8 -*- # @file : run.py # @author : 沙陌 Matongxue_2# @Time : 2022-05-10 11:24# @Copyright: 北京碼同學(xué)import osimport allureimport openpyxlimport pytestfrom common.client import RequestsClientfrom common.testcase_util import get_all_testcases, get_variables, get_api_default_params, regx_sub_data, update_value_to_jsonwb = openpyxl.load_workbook(‘testcases/CRM系統(tǒng)接口測試用例.xlsx’)# 獲取所有的測試用例數(shù)據(jù)test_data = get_all_testcases(wb)variables = get_variables(wb) # 獲取所有的公共變量,也用來存儲(chǔ)測試過程中產(chǎn)生的動(dòng)態(tài)變量api_default_params = get_api_default_params(wb) # 獲取所有接口的默認(rèn)參數(shù)數(shù)據(jù)@pytest.mark.parametrize(‘suite_name,case_name,case_info_list’,test_data)def test_run(suite_name,case_name,case_info_list): # 創(chuàng)建一個(gè)接口調(diào)用的對象 client = RequestsClient() allure.dynamic.feature(suite_name) # 測試報(bào)告上會(huì)高于測試用例的層級(jí)展示 allure.dynamic.title(case_name) # 測試報(bào)告上表示測試用例的名稱 # case_info_list 是多個(gè)接口的數(shù)據(jù),是一個(gè)列表 for case_info in case_info_list: # case_info 其實(shí)也是一個(gè)列表,表示excel某一行的測試數(shù)據(jù),從接口名稱開始往后 # [‘登錄’, ‘${host}/login’, ‘post’, ”, ”, ‘{“token”:”$.Admin-Token”}’, 200, ‘[{“actual”:”$.code”,”expect”:0}]’] kwargs = {‘verify’:False} #verify表示忽略https的證書 api_name = case_info[0] # 接口名稱 url = case_info[1] # 接口名稱 url = regx_sub_data(url,variables) # 處理url中的動(dòng)態(tài)變量及動(dòng)態(tài)函數(shù)調(diào)用 method = case_info[2] # 接口請求方式 headers = case_info[3] # 接口頭信息 if headers!=”: headers = regx_sub_data(headers,variables) headers = eval(headers) # 將json格式的字符串轉(zhuǎn)換成字典 kwargs[‘headers’] = headers # 測試數(shù)據(jù)并不是接口發(fā)起時(shí)真正的全部參數(shù),需要根據(jù)用戶填入的要測試的數(shù)據(jù)和該接口對應(yīng)的默認(rèn)數(shù)據(jù)進(jìn)行替換以及組合來達(dá)到 # 請求數(shù)據(jù) api_default_param = api_default_params[api_name] # 獲取當(dāng)前行的接口對應(yīng)的默認(rèn)數(shù)據(jù) if api_default_param != ”: api_default_param = regx_sub_data(api_default_param,variables) api_default_param = eval(api_default_param) test_params = case_info[4] # 測試數(shù)據(jù) if test_params != ”: test_params = regx_sub_data(test_params,variables) test_params = eval(test_params) # 解析測試數(shù)據(jù),通過jsonpath去替換默認(rèn)參數(shù)中的數(shù)據(jù) # 邏輯是遍歷測試數(shù)據(jù),判斷測試數(shù)據(jù)中是哪種參數(shù)類型(data/params/json/files),根據(jù)參數(shù)類型去替換默認(rèn)數(shù)據(jù)的對應(yīng)的部分 if ‘json’ in test_params: “”” { “$.entity.name”:”聯(lián)系人${{cur_timestamp()}}”, } “”” for json_path,new_value in test_params[‘json’].items(): api_default_param[‘json’] = update_value_to_json(api_default_param[‘json’],json_path,new_value) if ‘data’ in test_params: for json_path,new_value in test_params[‘data’].items(): api_default_param[‘data’] = update_value_to_json(api_default_param[‘data’],json_path,new_value) if ‘params’ in test_params: for json_path,new_value in test_params[‘params’].items(): api_default_param[‘params’] = update_value_to_json(api_default_param[‘params’],json_path,new_value) if ‘files’ in test_params: for json_path,new_value in test_params[‘files’].items(): api_default_param[‘files’] = update_value_to_json(api_default_param[‘files’],json_path,new_value) test_params = api_default_param # 整合完成測試數(shù)據(jù)和默認(rèn)數(shù)據(jù)之后,將他們分別存儲(chǔ)kwargs中 if ‘json’ in test_params: kwargs[‘json’] = test_params[‘json’] if ‘data’ in test_params: kwargs[‘data’] = test_params[‘data’] if ‘params’ in test_params: kwargs[‘params’] = test_params[‘params’] if ‘files’ in test_params: kwargs[‘files’] = test_params[‘files’] resp = client.send(url=url,method=method,**kwargs) # 發(fā)起請求 expect_status = case_info[6] # 期望的響應(yīng)狀態(tài)碼 assert resp.status_code == expect_status # print(resp.text) extract_resp = case_info[5] # 響應(yīng)提取 if extract_resp != ”: extract_resp = eval(extract_resp) “”” { “token”:”$.Admin-Token” } “”” for key,value in extract_resp.items(): # key就是提取后要保存的變量名稱 # value是你要提取的目標(biāo)字段對應(yīng)的jsonpath表達(dá)式 res = client.extract_resp(value) variables[key] = res expect_resp = case_info[7] # 期望的響應(yīng)信息 if expect_resp != ”: expect_resp = regx_sub_data(expect_resp,variables) expect_resp = eval(expect_resp) “”” [ { “actual”:”$.code”, “expect”:500, }, { “actual”:”$.msg”, “expect”:”產(chǎn)品編號(hào)已存在,請校對后再添加!”, } ] “”” for expect_info in expect_resp: json_path = expect_info[‘actual’] actual_res = client.extract_resp(json_path) expect_res = expect_info[‘expect’] pytest.assume(actual_res==expect_res,f’期望是{expect_res},實(shí)際是{actual_res}’)if __name__ == ‘__main__’: pytest.main() # 該方法會(huì)自動(dòng)掃描當(dāng)前項(xiàng)目中的pytest.ini,根據(jù)其中的配置進(jìn)行執(zhí)行 os.system(‘allure generate ./report/data -o ./report/html –clean’)

      免費(fèi)領(lǐng)取碼同學(xué)軟件測試課程筆記+超多學(xué)習(xí)資料+學(xué)習(xí)完整視頻,可以關(guān)注我們公眾號(hào)哦:自動(dòng)化軟件測試

      本文著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年6月19日 06:47
      下一篇 2022年6月19日 06:47

      相關(guān)推薦

      • 科普:蘋果lightning端子針腳功能定義介紹

        前言 2012年9月12日,位于美國舊金山芳草地會(huì)議中心,蘋果發(fā)布全新的Lightning 接口,中文譯為“閃電”接口;相信用過iPhone 4手機(jī)的用戶,對于30針Dock接口印…

        2022年7月3日
      • 電腦性能測試(電腦性能測試軟件有哪些)

        今天小編給各位分享電腦性能測試的知識(shí),其中也會(huì)對電腦性能測試軟件有哪些進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! 怎樣檢測電腦硬件的性能 1.下載安裝好…

        2022年10月31日
      • 第02篇:Mybatis配置文件解析

        本篇主要內(nèi)容如下,由于頭條頁面對Markdown文檔的展示問題,所以排版可能有問題。 一、配置文件分析 文件分析 在上一篇的代碼中,我們看到了一個(gè)非常重要文件,這里我們先來人肉分析…

        2022年7月11日
      • 為什么大家都在選擇做電商呢?

        如果有人問你:當(dāng)下最流行的創(chuàng)業(yè)模式是啥?我想你一定會(huì)脫口而出:是社交電商! 沒錯(cuò)!的確是社交電商!為什么社交電商會(huì)有這么大的影響力呢?具體要怎么去做呢? 首先來說社交為什么這么受歡…

        2022年7月20日
      • 銀保監(jiān)會(huì)回應(yīng)熱點(diǎn):村鎮(zhèn)銀行墊付已超180億,更加有力推進(jìn)保交樓

        村鎮(zhèn)銀行墊付進(jìn)展、中小銀行改革化險(xiǎn)、“保交樓”問題、金融資產(chǎn)管理公司改革方案……8月12日,針對近期的熱點(diǎn)問題,銀保監(jiān)會(huì)有關(guān)部門負(fù)責(zé)人一一進(jìn)行了回應(yīng)。 銀保監(jiān)會(huì)有關(guān)部門負(fù)責(zé)人表示,…

        2022年8月14日
      • 首套房利率下調(diào)已經(jīng)買了的下調(diào)嗎 要具體分析!

        近段時(shí)間,全國有部分地區(qū)宣布首套房利率下調(diào),這對于剛需的購房者來說,是不錯(cuò)的消息,那么首套房利率下調(diào)已經(jīng)買了的下調(diào)嗎?下文就來帶大家了解一下。 1、如果客戶購買的不是首套房,而是二…

        2022年9月5日
      • APP第三方登錄怎么實(shí)現(xiàn)的

        在日常使用各個(gè)APP的時(shí)候,大家應(yīng)該都或多或少接觸過與“授權(quán)”有關(guān)的場景。大家有沒有想過在不需要輸入密碼賬號(hào)的情況下,是怎么實(shí)現(xiàn)第三方登錄的呢?本文作者將結(jié)合自己的項(xiàng)目經(jīng)歷來跟大家…

        2022年6月18日
      • 房貸沒放款利率降了怎么辦 會(huì)跟著降嗎?

        在如今,有的銀行房貸放款時(shí)間是比較長的,有的人等了幾個(gè)月以后,發(fā)現(xiàn)最新的利率已經(jīng)降低了,那么房貸沒放款利率降了怎么辦?下文就來帶大家了解一下。 房貸沒放款利率降了,是不會(huì)跟著降的?!?/p>

        2022年9月21日
      • 面向高端玩家 、可一鍵超頻至6400的技嘉AORUS RGB DDR5 6000內(nèi)存條

        作為臺(tái)式機(jī)、筆記本等設(shè)備的重要組成部分,不同規(guī)格、不同品牌的內(nèi)存對不同玩家的吸引力也各不相同,有人追求顏值,在意內(nèi)存的造型設(shè)計(jì),比如RGB燈光、白色外殼等等;有人追求手動(dòng)超頻的樂趣…

        2022年6月13日
      • 中國從今年年初在“一帶一路”框架下,沒有向俄羅斯投資

        @頭號(hào)周刊 據(jù)復(fù)旦大學(xué)綠色金融研究中心的報(bào)告顯示,今年上半年,沒有和俄羅斯實(shí)體達(dá)成新的“一帶一路”合作協(xié)議。 在2021年,俄中兩國簽署了價(jià)值20億美元的協(xié)議。 2022年的上半年…

        2022年8月4日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息