【第六章】二次封裝斷言 設計斷言庫
阿新 • • 發佈:2021-12-13
對斷言模組進行二次封裝
- 為什麼要斷言,為什麼要二次封裝
自動化測試框架中,斷言這一部分是必不可少的,使用unittest自帶的斷言功能不太適合框架,且斷言支援不強大(比如json斷言、正則斷言都不支援),所以在框架中把斷言重新設計封裝成check類。
具體設計思想:
- 設計excel用例資訊時,新增期望結果型別(無、json鍵是否存在、正則匹配、json鍵值對)、期望結果兩個欄位
- 通過check類的方法實現斷言後返回一個json資料,裡面包含斷言結果以及相應返回值
- check類返回的結果放入封裝的get和post方法中,然後在多介面執行方法中把結果作為是否繼續執行下一個介面的依據
- 返回最後的結果在unitest中獲取到後,只需要統一使用assertTrue來進行斷言即可
- 小試牛刀
程式碼示例: 對比鍵的單個、多個鍵是否存在
# -*- coding: utf-8 -*- # @Time : 2021/12/13 13:41 # @Author : Limusen # @File : assert_demo_09 """ 斷言demo """ import json # 斷言基礎實現舉例 str1 = '{"access_token":"12312jkssa"}' str2 = '{"access_token":"ACCESS_TOKEN","expires_in":7200}' # 轉成json字典 json_obj = json.loads(str1) json_obj_02 = json.loads(str2) # 判斷字典的鍵中是否跟 access_token 一樣的 # 對比單個值 if "access_token" in json_obj.keys(): print(True) else: print(False) # 對比多個值 check_keys = ["access_token", "expires_in"] result_list = [] for check_key in check_keys: if check_key injson_obj_02.keys(): print("我是正確的") result_list.append(True) else: print("我是錯誤的") result_list.append(False) if False in result_list: print(False) print(result_list)
- 封裝成類方法
- common模組新建check_utils.py
- 示例程式碼
- check_utils.py
# -*- coding: utf-8 -*- # @Time : 2021/12/13 14:07 # @Author : Limusen # @File : check_utils class CheckUtils: def __init__(self, response_data): """ :param response_data: 響應結果 """ self.response_data = response_data self.function = { "json_check": self.json_key_check, } def json_key_check(self, check_data): """ :param check_data: 需要檢查的欄位,注意得是字串才行,因為要分割 :return: True說明斷言成功,False說明斷言失敗 """ # 字串逗號分割 key_list = check_data.split(",") tmp_result = [] # 取出需要斷言的欄位 for check_key in key_list: # 如果 check_key 在json串的鍵當中,則新增True,不是則新增False if check_key in self.response_data.json().keys(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: # 只要有一個不符合 用例全部失敗 return False else: return True if __name__ == '__main__': import requests url = "https://api.weixin.qq.com/cgi-bin/token" get_params = {"grant_type": "client_credential", "appid": "wxb637f1f0d", "secret": "501123d2da9011d0f084"} response = requests.get(url=url, params=get_params) ck = CheckUtils(response) print(ck.json_key_check("access_token,expires_in"))
- 優化check_utils 繼續增加可斷言型別,新增執行斷言方法的總控開關
# -*- coding: utf-8 -*- # @Time : 2021/12/13 14:07 # @Author : Limusen # @File : check_utils class CheckUtils: def __init__(self, response_data): """ :param response_data: 響應結果 """ self.response_data = response_data self.function = { "json_check": self.json_key_check } def json_key_check(self, check_data): """ :param check_data: 需要檢查的欄位,注意得是字串才行,因為要分割 :return: True說明斷言成功,False說明斷言失敗 """ # 字串逗號分割 key_list = check_data.split(",") tmp_result = [] # 取出需要斷言的欄位 for check_key in key_list: # 如果 check_key 在json串的鍵當中,則新增True,不是則新增False if check_key in self.response_data.json().keys(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: # 只要有一個不符合 用例全部失敗 return False else: return True def run_check(self, check_type, except_result): """ :param check_type: 檢查的型別 :param except_result: 檢查的欄位 :return: """ return self.function[check_type](except_result) if __name__ == '__main__': import requests url = "https://api.weixin.qq.com/cgi-bin/token" get_params = {"grant_type": "client_credential", "appid": "wxb637f897f0bf1f0d", "secret": "501123d2d367b109a5cb9a9011d0f084"} response = requests.get(url=url, params=get_params) ck = CheckUtils(response) # print(ck.json_key_check("access_token,expires_in")) print(ck.run_check('json_check', 'access_token,expires_in'))
- 新增其他型別斷言
- assert_demo_10.py
# -*- coding: utf-8 -*- # @Time : 2021/12/13 13:41 # @Author : Limusen # @File : assert_demo_10 """ 斷言demo 對比json資料 """ import json # 單項對比 # key — value 斷言基礎實現舉例 str1 = '{"access_token":"ACCESS_TOKEN","expires_in":7200}' except_str = '{"expires_in": 7200}' json_obj = json.loads(str1) except_obj = json.loads(except_str) # print(json_obj.items()) # print(except_obj.items()) # 示例2: a = [(1, 2)] b = [(2, 3), (1, 2)] e = [] for c in b: if c == a[0]: e.append(True) else: e.append(False) if False in e: print(False) print(list(except_obj.items())[0]) print(json_obj.items()) # 如果expires_in 在 json_obj列表中則輸出ture if list(except_obj.items())[0] in json_obj.items(): print(True) else: print(False) # 多項對比 str1 = '{"access_token":"ACCESS_TOKEN","expires_in":7200}' except_str_02 = '{"expires_in": 7200,"access_token":"ACCESS_TOKEN"}' json_obj_02 = json.loads(str1) except_obj_02 = json.loads(except_str_02) yes_no = [] for except_res in except_obj_02.items(): if except_res in json_obj_02.items(): yes_no.append(True) else: yes_no.append(False) if False in yes_no: print(False)
- 封裝至check_utils.py
- key_value_check
# -*- coding: utf-8 -*- # @Time : 2021/12/13 14:07 # @Author : Limusen # @File : check_utils import json class CheckUtils: def __init__(self, response_data): """ :param response_data: 響應結果 """ self.response_data = response_data self.function = { "json_key": self.key_check, "json_key_value": self.key_value_check } def key_check(self, check_data): """ 檢查鍵是否相同 :param check_data: 需要檢查的欄位,注意得是字串才行,因為要分割 :return: True說明斷言成功,False說明斷言失敗 """ # 字串逗號分割 key_list = check_data.split(",") tmp_result = [] # 取出需要斷言的欄位 for check_key in key_list: # 如果 check_key 在json串的鍵當中,則新增True,不是則新增False if check_key in self.response_data.json().keys(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: # 只要有一個不符合 用例全部失敗 return False else: return True def key_value_check(self, check_data): """ 檢查鍵值對是否一致 :param check_data: :return: """ key_dict = json.loads(check_data) tmp_result = [] for check_key in key_dict.items(): if check_key in self.response_data.json().items(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: return False else: return True def run_check(self, check_type, except_result): """ :param check_type: 檢查的型別 :param except_result: 檢查的欄位 :return: """ return self.function[check_type](except_result) if __name__ == '__main__': import requests url = "https://api.weixin.qq.com/cgi-bin/token" get_params = {"grant_type": "client_credential", "appid": "wxb637f897f0bf1f0d", "secret": "501123d2d367b109a5cb9a9011d0f084"} response = requests.get(url=url, params=get_params) ck = CheckUtils(response) print(ck.run_check('json_key', "access_token,expires_in")) print(ck.run_check('json_key_value', '{"expires_in": 7200}'))
- 全部封裝程式碼
check_utils.py
# -*- coding: utf-8 -*- # @Time : 2021/12/13 14:07 # @Author : Limusen # @File : check_utils import json import re class CheckUtils: def __init__(self, response_data): """ :param response_data: 響應結果 """ self.response_data = response_data self.function = { "none_check": self.none_check(), "json_key": self.key_check, "json_key_value": self.key_value_check, "body_regexp": self.body_regexp_check, "header_key_check": self.header_key_check, "header_key_value_check": self.header_key_value_check, "response_code_check": self.response_code_check } def none_check(self): """ 斷言型別為空的情況 :return: """ return True def key_check(self, check_data): """ 檢查鍵是否相同 :param check_data: 需要檢查的欄位,注意得是字串才行,因為要分割 :return: True說明斷言成功,False說明斷言失敗 """ # 字串逗號分割 key_list = check_data.split(",") tmp_result = [] # 取出需要斷言的欄位 for check_key in key_list: # 如果 check_key 在json串的鍵當中,則新增True,不是則新增False if check_key in self.response_data.json().keys(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: # 只要有一個不符合 用例全部失敗 return False else: return True def key_value_check(self, check_data): """ 檢查鍵值對是否一致 :param check_data: :return: """ key_dict = json.loads(check_data) tmp_result = [] for check_key in key_dict.items(): if check_key in self.response_data.json().items(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: return False else: return True def body_regexp_check(self, check_data): """ 根據正則表示式斷言 :param check_data: :return: """ if re.findall(check_data, self.response_data.text): # 能找到check_data的值則算通過 return True else: return False def header_key_check(self, check_data): """ 檢查頭部資訊是否包含某個值 可以參照key_check() :param check_data: :return: """ # 字串逗號分割 key_list = check_data.split(",") tmp_result = [] # 取出需要斷言的欄位 for check_key in key_list: # 如果 check_key 在json串的鍵當中,則新增True,不是則新增False if check_key in self.response_data.headers.keys(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: # 只要有一個不符合 用例全部失敗 return False else: return True def header_key_value_check(self, check_data): """ 檢查頭部鍵值對是否一致 參照key_value_check() :param check_data: :return: """ key_dict = json.loads(check_data) tmp_result = [] for check_key in key_dict.items(): if check_key in self.response_data.headers.items(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: return False else: return True def response_code_check(self, check_data): """ 檢查返回狀態碼 :param check_data: :return: """ if self.response_data.status_code == int(check_data): return True else: return False def run_check(self, check_type, except_result): """ :param check_type: 檢查的型別 :param except_result: 檢查的欄位 :return: """ return self.function[check_type](except_result) if __name__ == '__main__': import requests url = "https://api.weixin.qq.com/cgi-bin/token" get_params = {"grant_type": "client_credential", "appid": "wxb637f897f0bf1f0d", "secret": "501123d2d367b109a5cb9a9011d0f084"} response = requests.get(url=url, params=get_params) # print(response.headers) ck = CheckUtils(response) print(ck.none_check()) print(ck.run_check('json_key', "access_token,expires_in")) print(ck.run_check('json_key_value', '{"expires_in": 7200}')) print(ck.run_check("body_regexp", '"access_token":"(.+?)"')) print(ck.run_check("header_key_check", "Connection")) print(ck.run_check("header_key_value_check", '{"Connection": "keep-alive"}')) print(ck.run_check("response_code_check", "200"))
- 這裡呼叫ck.run_check('none_check'),會報錯 ,優化一下程式碼
def run_check(self, check_type, except_result): """ :param check_type: 檢查的型別 :param except_result: 檢查的欄位 :return: """ if check_type == "none" or except_result == "": return self.function["none"]() else: return self.function[check_type](except_result)
- 整體程式碼
# -*- coding: utf-8 -*- # @Time : 2021/12/13 14:07 # @Author : Limusen # @File : check_utils import json import re class CheckUtils: def __init__(self, response_data): """ :param response_data: 響應結果 """ self.response_data = response_data self.function = { "none": self.none_check(), "json_key": self.key_check, "json_key_value": self.key_value_check, "body_regexp": self.body_regexp_check, "header_key_check": self.header_key_check, "header_key_value_check": self.header_key_value_check, "response_code_check": self.response_code_check } def none_check(self): """ 斷言型別為空的情況 :return: """ return True def key_check(self, check_data): """ 檢查鍵是否相同 :param check_data: 需要檢查的欄位,注意得是字串才行,因為要分割 :return: True說明斷言成功,False說明斷言失敗 """ # 字串逗號分割 key_list = check_data.split(",") tmp_result = [] # 取出需要斷言的欄位 for check_key in key_list: # 如果 check_key 在json串的鍵當中,則新增True,不是則新增False if check_key in self.response_data.json().keys(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: # 只要有一個不符合 用例全部失敗 return False else: return True def key_value_check(self, check_data): """ 檢查鍵值對是否一致 :param check_data: :return: """ key_dict = json.loads(check_data) tmp_result = [] for check_key in key_dict.items(): if check_key in self.response_data.json().items(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: return False else: return True def body_regexp_check(self, check_data): """ 根據正則表示式斷言 :param check_data: :return: """ if re.findall(check_data, self.response_data.text): # 能找到check_data的值則算通過 return True else: return False def header_key_check(self, check_data): """ 檢查頭部資訊是否包含某個值 可以參照key_check() :param check_data: :return: """ # 字串逗號分割 key_list = check_data.split(",") tmp_result = [] # 取出需要斷言的欄位 for check_key in key_list: # 如果 check_key 在json串的鍵當中,則新增True,不是則新增False if check_key in self.response_data.headers.keys(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: # 只要有一個不符合 用例全部失敗 return False else: return True def header_key_value_check(self, check_data): """ 檢查頭部鍵值對是否一致 參照key_value_check() :param check_data: :return: """ key_dict = json.loads(check_data) tmp_result = [] for check_key in key_dict.items(): if check_key in self.response_data.headers.items(): tmp_result.append(True) else: tmp_result.append(False) if False in tmp_result: return False else: return True def response_code_check(self, check_data): """ 檢查返回狀態碼 :param check_data: :return: """ if self.response_data.status_code == int(check_data): return True else: return False def run_check(self, check_type, except_result): """ :param check_type: 檢查的型別 :param except_result: 檢查的欄位 :return: """ if check_type == "none" or except_result == "": return self.function["none"]() else: return self.function[check_type](except_result) if __name__ == '__main__': import requests url = "https://api.weixin.qq.com/cgi-bin/token" get_params = {"grant_type": "client_credential", "appid": "wxb637f897f0bf1f0d", "secret": "501123d2d367b109a5cb9a9011d0f084"} response = requests.get(url=url, params=get_params) # print(response.headers) ck = CheckUtils(response) print(ck.none_check()) print(ck.run_check('json_key', "access_token,expires_in")) print(ck.run_check('json_key_value', '{"expires_in": 7200}')) print(ck.run_check("body_regexp", '"access_token":"(.+?)"')) print(ck.run_check("header_key_check", "Connection")) print(ck.run_check("header_key_value_check", '{"Connection": "keep-alive"}')) print(ck.run_check("response_code_check", "200"))
這一章將的是斷言庫的封裝,下一章將講解將斷言庫整合到request中