之前写过一个 基于HttpRunner,解析swagger数据,快速生成接口测试框架,今天抽时间又优化了下
使用最新的httprunner 2.3.2 版本。默认好像没有生成测试报告,需要简单的修改下源码:
# api.py 217行 添加 report_path = report.gen_html_report(self._summary) # 修改报告的默认命名方式 # report.py 301行-310行 start_at_timestamp = int(summary["time"]["start_at"]) summary["time"]["start_datetime"] = datetime.fromtimestamp(start_at_timestamp).strftime('%Y-%m-%d %H:%M:%S') time_format= datetime.fromtimestamp(start_at_timestamp).strftime('%Y-%m-%d %H-%M-%S') if report_file: report_dir = os.path.dirname(report_file) report_file_name = os.path.basename(report_file) else: report_dir = report_dir or os.path.join(os.getcwd(), "reports") report_file_name = "{}.html".format(time_format) # log,修改api.py 33-36行,默认输出日志文件到框架目录下的logs中 log_path = os.path.join(os.getcwd(), "logs") if not os.path.exists(log_path): os.mkdir(log_path) time_format = datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d') if not os.path.exists(log_file): log_file = os.path.join(log_path, log_file + time_format + ".log") logger.setup_logger(log_level, log_file)
修改了 processingJson.py ,在从swagger拉取接口时,判断,保留已修改的json文件内容<在已运行的json接口文件中加参数 noReset >
import json, os # from httprunner import logger from common.logger import logger def get_json(path, field=''): """ 获取json文件中的值,data.json和res.json可共用 :param path: :param field: :return: """ with open(path, 'r', encoding='utf-8') as f: json_data = json.load(f) if field: data = json_data.get(field) return data else: return json_data def write_data(res, json_path): """ 把处理后的参数写入json文件 :param res: :param json_path: :return: """ if isinstance(res, dict) or isinstance(res, list): with open(json_path, 'w', encoding='utf-8') as f: json.dump(res, f, ensure_ascii=False, sort_keys=True, indent=4) logger.log_info( 'Interface Params Total:{} ,write to json file successfully! {} '.format(len(res), json_path)) else: logger.log_error('{} Params is not dict. '.format(write_data.__name__)) def check_json(res: dict or list, json_path: str, field: str = "noReset"): """ 接口路口已存在的,不重置,只添加删除参数,设置 noReset 参数为 true; :param res: :param json_path: :param field: :return: """ if os.path.exists(json_path): noReset = get_json(json_path, field) if noReset: data = get_json(json_path) res[field] = True not_reset_json(data, res) if "teststeps" in res.keys(): for teststep in res.get("teststeps", []): teststep["validate"] = [] elif "testcases" in res.keys(): res["testcases"] = data.get("testcases", []) else: with open("接口更新记录.txt", "a") as f: f.write("新增 api :{}".format(json_path)) write_data(res, json_path) def not_reset_json(data, res): """ 递归,data 中已存在值,则替换到 res 中 :param data: :param res: :return: """ if isinstance(data, dict): for key, value in data.items(): if isinstance(value, (dict, list)): not_reset_json(value, res[key]) elif isinstance(value, str): res[key] = value elif isinstance(data, list): for i in range(len(data)): if isinstance(data[i], (dict, list)): try: not_reset_json(data[i], res[i]) except IndexError: try: res.update(data[i]) except AttributeError: res.append(data[i]) else: res[i] = data[i] elif isinstance(data, str): logger.log_info("外层判断,data是str :{}".format(data)) def comparison_document(): """ 比较suite/testceae和api文件的差异,发现未运行的接口 :return: """ from common.logger import BASE_DIR if os.path.exists("comparison_document.txt"): os.remove("comparison_document.txt") api_path = os.path.join(BASE_DIR, "api") suite_path = os.path.join(BASE_DIR, "testsuitesdemo_testsuite.json") api_file_list = os.listdir(api_path) suite_data = get_json(suite_path) suite_list = suite_data.get("testcases", []) suite_api_list = [] for api in suite_list: suite_api_list.append(api["name"]) with open("comparison_document.txt", "a", encoding="utf-8") as f: f.write("--------------testsuite未设置接口--------------------------" + " ") for api_name in api_file_list: if api_name not in suite_api_list: with open("comparison_document.txt", "a", encoding="utf-8") as f: f.write(os.path.join(api_path, api_name) + " ") testcase_path = os.path.join(BASE_DIR, "testcases") testcase_file_list = os.listdir(testcase_path) with open("comparison_document.txt", "a", encoding="utf-8") as f: f.write("--------------testcase未设置接口--------------------------" + " ") for file in testcase_file_list: testcase_file_path = os.path.join(testcase_path, file) testcase_data = get_json(testcase_file_path) title = testcase_data.get("config", {}).get("name", "") teststeps_list = testcase_data.get("teststeps", {}) testcase_api_list = [] for api in teststeps_list: if title in api.get("api", ""): testcase_api_list.append(api.get("name", "") + ".json") for api_name in api_file_list: if api_name == title: api_name_list = os.listdir(os.path.join(api_path, api_name)) for api in api_name_list: if api not in testcase_api_list: with open("comparison_document.txt", "a", encoding="utf-8") as f: f.write(os.path.join(os.path.join(api_path, api_name), api) + " ") if __name__ == '__main__': comparison_document()
有新增的接口时,会输出 接口更新记录.txt 文件
comparison_document() 方法,可以避免有遗漏的没有运行的 api
swagger.py 写入json文件的方法,需要更换成 check_json()
so,先这样~~~