def __init__(self): self.apv = ApiPublicVariableInfoManager() self.atim = ApiTestcaseInfoManager() self.asim = ApiSystemInfoManager() self.apim = ApiProjectInfoManager() self.acim = ApiCompanyInfoManager() self.aiim = ApiIntfInfoManager() self.atmm = ApiTestcaseMainManager() self.atsm = ApiTestcaseSubManager() self.custom = read_custom() self.data = get_request_json() self.username = redis.get_username(request.headers.get('X-Token'))
def get_public_v_names(tc_obj, v_names=None): """ 根据tc_obj获取用例中公共变量的名称 Args: tc_obj: v_names: Returns: "$serialNo, $MOBILE_NO, $DEVICE_ID, $current_timestamp" """ if not v_names: v_names = '' include_list = json.loads(tc_obj.include) public_variables_list = [] for include in include_list: if 'public_variables' in include: public_variables_list = include['public_variables'] for public_variable_id in public_variables_list: public_v_obj = ApiPublicVariableInfoManager.get_variable( id=public_variable_id) if public_v_obj: if v_names: v_names += ', $' + public_v_obj.variable_name else: v_names = '$' + public_v_obj.variable_name return v_names
def repair_sub_case_public_var_error(): import re variable_regexp = r"\$([\w_]+)" sub_objs = ApiTestcaseSubManager.get_testcase_subs() repair_count = 0 for sub_obj in sub_objs: if not sub_obj.include or sub_obj.include in ['[]', '[{"public_variables": []}]']: continue include_list = json_loads(sub_obj.include) pv_id_list = include_list[0]['public_variables'] pv_dic = {} for public_v_id in pv_id_list: pv_obj = ApiPublicVariableInfoManager.get_variable(id=public_v_id) pv_dic[public_v_id] = pv_obj.variable_name request_obj = ApiTestcaseRequestQllManager.get_request(api_testcase_id=sub_obj.id) new_pv_id_list = [] if request_obj and request_obj.request: variables = re.findall(variable_regexp, str(request_obj.request)) variables = list(set(variables)) for variable_name in variables: for pv_id, pv_name in pv_dic.items(): if pv_name == variable_name: new_pv_id_list.append(pv_id) break if set(pv_id_list) != set(new_pv_id_list): new_pv_id_list.append(137) if set(pv_id_list) != set(new_pv_id_list): if 137 not in pv_id_list: new_pv_id_list.remove(137) print('sub_obj.id:{2}, old:{0}, new:{1}'.format(pv_id_list, new_pv_id_list, sub_obj.id)) new_include = [{"public_variables": new_pv_id_list}] include_str = json_dumps(new_include) print(include_str) ApiTestcaseSubManager.update_testcase_sub(id_=sub_obj.id, include=include_str) repair_count += 1 print(repair_count)
def get_api_testcase_main_detail(tm_obj): """ 新版-获取主测试用例详情 :param tm_obj: :return: """ custom = read_custom() pvim = ApiPublicVariableInfoManager() public_v_objs = pvim.get_variables() case_type = tm_obj.case_type main_teardown_info = [] if tm_obj.main_teardown_hooks: main_teardown_hooks = json.loads(tm_obj.main_teardown_hooks) for teardown in main_teardown_hooks: teardown = teardown.replace("||$DB_CONNECT", "", 1).replace("||$DISCONF_HOST", "", 1) teardown_func_name = teardown.split("${")[1].split("(")[0] teardown_func_args = teardown[:-2].split("(", 1)[-1] for teardown_hook in custom["teardown-hooks"]: if teardown_hook["name"] == teardown_func_name: args_dict = {} for a, p in zip(teardown_func_args.split('||'), teardown_hook["parameters"]): args_dict[p] = a main_teardown_info.append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": args_dict }) # # 返回自定义flow信息 # custom_flow_objs = ApiTestcaseMainCustomFlowManager.get_flows(testcase_id=tm_obj.id) # custom_flow_list = [ # { # "flowId": obj.id, # "flowName": obj.flow_name, # "startEnd": [obj.start_sub_index, obj.end_sub_index] # } # for obj in custom_flow_objs # ] response = { "base": { "testcaseName": tm_obj.testcase_name, "testcaseDesc": tm_obj.simple_desc if tm_obj.simple_desc else '', "creator": tm_obj.creator, "last_modifier": tm_obj.last_modifier, "expectResult": tm_obj.expect_result if tm_obj.expect_result else '', "mainTeardownInfo": main_teardown_info, }, "steps": [], } _all_main_case_objs = None if case_type == 1: response["base"].update({ "caseType": case_type, "intfId": tm_obj.api_intf_id, }) response["setupFlow"] = [] setup_flow_id_list = json.loads(tm_obj.setup_flow_list) for setup_flow_id in setup_flow_id_list: flow_obj = ApiTestcaseMainManager.get_testcase_main( id=setup_flow_id) pl_obj = ApiProductLineManager.get_product_line( id=flow_obj.api_product_line_id) product_line_name = pl_obj.product_line_name if pl_obj else "" response["setupFlow"].append({ "flowCaseId": setup_flow_id, "flowName": flow_obj.testcase_name, "productLineName": product_line_name, "productLineId": flow_obj.api_product_line_id, }) _all_main_case_objs = ApiTestcaseMainManager.get_testcase_mains() sub_id_list = json.loads(tm_obj.sub_list) ts_objs = ApiTestcaseSubManager.get_testcase_subs_in_id_list(sub_id_list) tr_objs = ApiTestcaseRequestQllManager.get_requests_in_case_id_list( sub_id_list) intf_id_list = [ts_obj.api_intf_id for ts_obj in ts_objs] intf_objs = ApiIntfInfoManager.get_intfs_in_id_list(intf_id_list) for sub_id in sub_id_list: sub_dic = { "base": {}, "setupInfo": [], "teardownInfo": [], "requestTeardownInfo": [], "requestInfo": {}, "validateInfo": [], "extractInfo": [], "variableInfo": [] } # ts_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id) # tr_obj = ApiTestcaseRequestQllManager.get_request(api_testcase_id=sub_id) # intf_obj = ApiIntfInfoManager.get_intf(id=ts_obj.api_intf_id) ts_obj = None tr_obj = None intf_obj = None for obj in ts_objs: if obj.id == sub_id: ts_obj = obj break for obj in tr_objs: if obj.api_testcase_id == sub_id: tr_obj = obj break if not ts_obj or not tr_obj: continue for obj in intf_objs: if obj.id == ts_obj.api_intf_id: intf_obj = obj break request = tr_obj.request include = ts_obj.include request_type = ts_obj.request_type # 返回base sub_dic["base"]["intfId"] = ts_obj.api_intf_id sub_dic["base"]["intfName"] = intf_obj.intf_name sub_dic["base"][ "intfNameInChinese"] = intf_obj.intf_desc if intf_obj.intf_desc else '' sub_dic["base"]["subId"] = sub_id sub_dic["base"]["subName"] = ts_obj.sub_name sub_dic["base"][ "subDesc"] = ts_obj.simple_desc if ts_obj.simple_desc else '' sub_dic["base"][ "subExpectResult"] = ts_obj.expect_result if ts_obj.expect_result else '' sub_dic["base"][ "isMultiQuote"] = True if ts_obj.main_list and json.loads( ts_obj.main_list) and len(json.loads( ts_obj.main_list)) > 1 else False sub_dic["base"]["requestType"] = map_number_to_testcase_type( request_type) if case_type == 1: sub_dic["base"][ "isSelf"] = True if ts_obj.api_intf_id == tm_obj.api_intf_id else False # testcase_request = json.loads(request.replace("'", "\"")) testcase_request = json.loads(request) last_teststeps = len(testcase_request["teststeps"]) - 1 # 返回variableInfo for variable in testcase_request["teststeps"][last_teststeps][ "variables"]: for variable_key, variable_value in variable.items(): if 1 == 0: pass else: variable_dict = {} # variable_value = str(variable_value) save_as_type = get_save_as_type(variable_value) variable_value = str(variable_value) # 自定义变量-db if variable_value.startswith("${variable_db_operation("): variable_dict["name"] = variable_key variable_dict["type"] = "db" variable_dict["value"] = variable_value.replace( "${variable_db_operation(", "", 1).replace("||$DB_CONNECT)}", "", 1) # 变量类型-function elif variable_value.startswith( '${') and variable_value.endswith('}'): func_name = variable_value.split('${')[-1].split( '(')[0] if 'variable_db_operation' == func_name: continue args_list = variable_value[:-2].split( '(', 1)[-1].split('||') args_dict = {} for func in custom["functions"]: if func["name"] == func_name: for a, p in zip(args_list, func["parameters"]): args_dict[p] = a break variable_dict["name"] = variable_key variable_dict["type"] = "function" variable_dict["value"] = func_name variable_dict["args"] = args_dict # 变量类型-constant else: variable_dict["saveAs"] = save_as_type variable_dict["name"] = variable_key variable_dict["type"] = "constant" variable_dict["value"] = variable_value sub_dic["variableInfo"].append(variable_dict) # 返回setupInfo testcase_setup_hooks = testcase_request["teststeps"][last_teststeps][ "setup_hooks"] for setup in testcase_setup_hooks: setup_func_name = setup.split("${")[1].split("(")[0] setup_func_args = setup[:-2].split("(", 1)[-1] # setup_func_args = re.findall(r'[^()]+', setup.split("{")[-1].split('}')[0])[1] # setup_func_args = re.findall(r'[(](.*?)[)]', setup,re.S)[0] '''判断request字段里面的setup_hooks里面是否有前置操作,有则返回至detail的setupInfo''' for setup_hook in custom["setup-hooks"]: if setup_hook["name"] == setup_func_name: if setup_func_name == "setup_db_operation": sub_dic["setupInfo"].append({ "name": setup_func_name, "desc": setup_hook["description"], "args": { "sql": setup_func_args.replace( "||$DB_CONNECT", "", 1) } }) elif setup_func_name == "setup_wait_until_db_result_succeed": args_dict = {} for a, p in zip(setup_func_args.split('||'), setup_hook["parameters"]): if p == "sql": args_dict[p] = a.replace( "||$DB_CONNECT", "", 1) else: args_dict[p] = a sub_dic["setupInfo"].append({ "name": setup_func_name, "desc": setup_hook["description"], "args": args_dict }) else: ''' # { # "name": "execution_testcase", # "args": { # "用例编号": "4173", # "请求参数": "{\"phone\":\"18260037329\"}" # } # } # ''' args_dict = {} for a, p in zip(setup_func_args.split('||'), setup_hook["parameters"]): args_dict[p] = a sub_dic["setupInfo"].append({ "name": setup_func_name, "desc": setup_hook["description"], "args": args_dict }) '''判断request字段里面的setup_hooks里面是否有加签函数,有则返回至detail的requestInfo''' for setup_hook in custom["sign"]: if setup_hook["name"] == setup_func_name: if "sign" in setup_func_name: '''setup_hooks中是否有加签函数''' sub_dic["requestInfo"]["sign"] = { "name": setup_func_name, "desc": setup_hook["description"] } # 返回teardownInfo testcase_teardown_hooks = testcase_request["teststeps"][ last_teststeps]["teardown_hooks"] for teardown in testcase_teardown_hooks: teardown_func_name = teardown.split("${")[1].split("(")[0] teardown_func_args = teardown[:-2].split("(", 1)[-1] for teardown_hook in custom["teardown-hooks"]: if teardown_hook["name"] == teardown_func_name: if teardown_func_name == "teardown_db_operation": sub_dic["teardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": { "sql": teardown_func_args.replace( "||$DB_CONNECT", "", 1) } }) elif teardown_func_name == "teardown_wait_until_db_result_succeed": args_dict = {} for a, p in zip(teardown_func_args.split('||'), teardown_hook["parameters"]): if p == "sql": args_dict[p] = a.replace( "||$DB_CONNECT", "", 1) else: args_dict[p] = a sub_dic["teardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": args_dict }) else: """如果args是列表,返回args列表""" args_dict = {} for a, p in zip(teardown_func_args.split('||'), teardown_hook["parameters"]): args_dict[p] = a sub_dic["teardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": args_dict }) # 返回requestTeardownInfo request_teardown_hooks = testcase_request["teststeps"][ last_teststeps].get("request_teardown_hooks", []) for teardown in request_teardown_hooks: teardown_func_name = teardown.split("${")[1].split("(")[0] teardown_func_args = teardown[:-2].split("(", 1)[-1] for teardown_hook in custom["teardown-hooks"]: if teardown_hook["name"] == teardown_func_name: """如果args是列表,返回args列表""" args_dict = {} for a, p in zip(teardown_func_args.split('||'), teardown_hook["parameters"]): args_dict[p] = a sub_dic["requestTeardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": args_dict }) # 返回requestInfo[json] requests_dict = testcase_request["teststeps"][last_teststeps][ "request"] is_merge = requests_dict.pop("isMerge", True) if request_type == 1: for json_value in requests_dict.values(): sub_dic["requestInfo"]["json"] = json_value # 增加入参校验 include_li = json.loads(include) if len(include_li) >= 3: param_check_dic = include_li[2]["param_check"] for item, p_list in param_check_dic.items(): if item == 'empty': sub_dic["requestInfo"]["emptyCheckParamList"] = p_list elif request_type == 2: for args_value in requests_dict.values(): sub_dic["requestInfo"] = args_value elif request_type == 3: for msg_value in requests_dict.values(): sub_dic["requestInfo"] = msg_value sub_dic["requestInfo"]["isMerge"] = is_merge sub_dic["requestInfo"]["type"] = request_type # 返回extractInfo for extract in testcase_request["teststeps"][last_teststeps][ "extract"]: for extract_key, extract_value in extract.items(): sub_dic["extractInfo"].append({ "saveAs": extract_key, "check": extract_value }) # 返回validateInfo for validate in testcase_request["teststeps"][last_teststeps][ "validate"]: for comparator, veirfy in validate.items(): if comparator == 'db_validate' and veirfy[0].endswith( '$DB_CONNECT'): veirfy[0] = veirfy[0].split("$DB_")[0] sub_dic["validateInfo"].append({ "comparator": comparator, "desc": comparator, "check": veirfy[0], "expect": veirfy[1], "comment": veirfy[2] if len(veirfy) >= 3 else '', }) # 返回include if not (include is None or len(include) < 3): testcase_include = json.loads(include) include_list = [{"public_variables": []}] for pv_id in testcase_include[0]["public_variables"]: # obj = pvim.get_variable(id=pv_id) obj = None for public_v_obj in public_v_objs: if public_v_obj.id == pv_id: obj = public_v_obj break if not obj: continue id_, name, type_name, desc = obj.id, obj.variable_name, obj.type, obj.simple_desc value = [v.strip() for v in obj.value.strip('##').split('##')][0] include_list[0]["public_variables"].append({ "id": id_, "name": name, "value": value, "type": type_name, "desc": desc }) sub_dic["include"] = include_list # 返回relatedMainCases if case_type == 1: sub_dic.update({"relatedCases": []}) for main_case_obj in _all_main_case_objs: if main_case_obj.case_type == 2: continue other_case_sub_list = json.loads(main_case_obj.sub_list) if sub_id in other_case_sub_list: sub_dic["relatedCases"].append({ "testcaseId": main_case_obj.id, "testcaseName": main_case_obj.testcase_name }) response["steps"].append(sub_dic) return response
def get_api_testcase_detail(tc_obj, without_setup_cases=False): """ 新版-获取测试用例详情 :param tc_obj: :param without_setup_cases: :return: """ custom = read_custom() pvim = ApiPublicVariableInfoManager() response = { "base": { "testcaseId": tc_obj.id, "testcaseName": tc_obj.testcase_name, "testcaseDesc": tc_obj.simple_desc if tc_obj.simple_desc else '', "creator": tc_obj.creator, "last_modifier": tc_obj.last_modifier, "expectResult": tc_obj.expect_result if tc_obj.expect_result else '', }, "steps": [{ "setupInfo": [], "teardownInfo": [], "requestTeardownInfo": [], "requestInfo": { "type": tc_obj.type }, "validateInfo": [], "extractInfo": [], "variableInfo": [] }], } tcr_obj = ApiTestcaseRequestManager.get_request(api_testcase_id=tc_obj.id) request = tcr_obj.request if tcr_obj else None include = tc_obj.include request_type = tc_obj.type setup_case_list = json.loads( tc_obj.setup_case_list) if tc_obj.setup_case_list else [] # 返回setupCases if not without_setup_cases: response['setupCases'] = [] for setup_case_str in setup_case_list: setup_case_type, setup_case_id, option = parse_setup_case_str( setup_case_str) kwargs = { 'with_intf_system_name': True, 'with_extract': False, 'only_first': True } if setup_case_type == 1: if option == 'self': kwargs['childless'] = True elif setup_case_type == 2: kwargs['main_case_flow_id'] = option setup_chain_list = get_testcase_chain(setup_case_id, setup_case_type, **kwargs) setup_case_dic = setup_chain_list.pop() setup_case_dic['children'] = setup_chain_list response['setupCases'].append(setup_case_dic) if request: # testcase_request = json.loads(request.replace("'", "\"")) testcase_request = json.loads(request) last_teststeps = len(testcase_request["teststeps"]) - 1 # 返回variableInfo for variable in testcase_request["teststeps"][last_teststeps][ "variables"]: for variable_key, variable_value in variable.items(): if 1 == 0: pass else: variable_dict = {} # variable_value = str(variable_value) save_as_type = get_save_as_type(variable_value) variable_value = str(variable_value) # 自定义变量-db if variable_value.startswith("${variable_db_operation("): variable_dict["name"] = variable_key variable_dict["type"] = "db" variable_dict["value"] = variable_value.replace( "${variable_db_operation(", "", 1).replace("||$DB_CONNECT)}", "", 1) # 变量类型-function elif variable_value.startswith( '${') and variable_value.endswith('}'): func_name = variable_value.split('${')[-1].split( '(')[0] if 'variable_db_operation' == func_name: continue # args_list = variable_value.split('(')[-1].split(')')[0].split(',') args_list = variable_value[:-2].split( '(', 1)[-1].split('||') args_dict = {} for func in custom["functions"]: if func["name"] == func_name: for a, p in zip(args_list, func["parameters"]): args_dict[p] = a break variable_dict["name"] = variable_key variable_dict["type"] = "function" variable_dict["value"] = func_name variable_dict["args"] = args_dict # 变量类型-constant else: variable_dict["saveAs"] = save_as_type variable_dict["name"] = variable_key variable_dict["type"] = "constant" variable_dict["value"] = variable_value response["steps"][0]["variableInfo"].append(variable_dict) # 返回setupInfo testcase_setup_hooks = testcase_request["teststeps"][last_teststeps][ "setup_hooks"] for setup in testcase_setup_hooks: setup_func_name = setup.split("${")[1].split("(")[0] setup_func_args = setup[:-2].split("(", 1)[-1] '''判断request字段里面的setup_hooks里面是否有前置操作,有则返回至detail的setupInfo''' for setup_hook in custom["setup-hooks"]: if setup_hook["name"] == setup_func_name: if setup_func_name == "setup_db_operation": response["steps"][0]["setupInfo"].append({ "name": setup_func_name, "desc": setup_hook["description"], "args": { "sql": setup_func_args.replace( "||$DB_CONNECT", "", 1) } }) elif setup_func_name == "setup_wait_until_db_result_succeed": args_dict = {} for a, p in zip(setup_func_args.split('||'), setup_hook["parameters"]): if p == "sql": args_dict[p] = a.replace( "||$DB_CONNECT", "", 1) else: args_dict[p] = a response["steps"][0]["setupInfo"].append({ "name": setup_func_name, "desc": setup_hook["description"], "args": args_dict }) else: ''' # { # "name": "execution_testcase", # "args": { # "用例编号": "4173", # "请求参数": "{\"phone\":\"18260037329\"}" # } # } # ''' args_dict = {} for a, p in zip(setup_func_args.split('||'), setup_hook["parameters"]): args_dict[p] = a response["steps"][0]["setupInfo"].append({ "name": setup_func_name, "desc": setup_hook["description"], "args": args_dict }) '''判断request字段里面的setup_hooks里面是否有加签函数,有则返回至detail的requestInfo''' for setup_hook in custom["sign"]: if setup_hook["name"] == setup_func_name: if "sign" in setup_func_name: '''setup_hooks中是否有加签函数''' response["steps"][0]["requestInfo"]["sign"] = { "name": setup_func_name, "desc": setup_hook["description"] } # 返回teardownInfo testcase_teardown_hooks = testcase_request["teststeps"][ last_teststeps]["teardown_hooks"] for teardown in testcase_teardown_hooks: teardown_func_name = teardown.split("${")[1].split("(")[0] teardown_func_args = teardown[:-2].split("(", 1)[-1] for teardown_hook in custom["teardown-hooks"]: if teardown_hook["name"] == teardown_func_name: if teardown_func_name == "teardown_db_operation": response["steps"][0]["teardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": { "sql": teardown_func_args.replace( "||$DB_CONNECT", "", 1) } }) elif teardown_func_name == "teardown_wait_until_db_result_succeed": args_dict = {} for a, p in zip(teardown_func_args.split('||'), teardown_hook["parameters"]): if p == "sql": args_dict[p] = a.replace( "||$DB_CONNECT", "", 1) else: args_dict[p] = a response["steps"][0]["teardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": args_dict }) else: """如果args是列表,返回args列表""" args_dict = OrderedDict() for a, p in zip(teardown_func_args.split('||'), teardown_hook["parameters"]): args_dict[p] = a response["steps"][0]["teardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": args_dict }) # 返回requestTeardownInfo request_teardown_hooks = testcase_request["teststeps"][ last_teststeps].get("request_teardown_hooks", []) for teardown in request_teardown_hooks: teardown_func_name = teardown.split("${")[1].split("(")[0] teardown_func_args = teardown[:-2].split("(", 1)[-1] for teardown_hook in custom["teardown-hooks"]: if teardown_hook["name"] == teardown_func_name: """如果args是列表,返回args列表""" args_dict = OrderedDict() for a, p in zip(teardown_func_args.split('||'), teardown_hook["parameters"]): args_dict[p] = a response["steps"][0]["requestTeardownInfo"].append({ "name": teardown_func_name, "desc": teardown_hook["description"], "args": args_dict }) # 返回requestInfo[json] requests_dict = testcase_request["teststeps"][last_teststeps][ "request"] is_merge = requests_dict.pop("isMerge", True) if request_type == 1: for json_value in requests_dict.values(): response["steps"][0]["requestInfo"]["json"] = json_value # 增加入参校验 include_li = json.loads(include) if len(include_li) >= 3: param_check_dic = include_li[2]["param_check"] for item, p_list in param_check_dic.items(): if item == 'empty': response["steps"][0]["requestInfo"][ "emptyCheckParamList"] = p_list elif request_type == 2: for args_value in requests_dict.values(): response["steps"][0]["requestInfo"] = args_value elif request_type == 3: for msg_value in requests_dict.values(): response["steps"][0]["requestInfo"] = msg_value response["steps"][0]["requestInfo"]["isMerge"] = is_merge response["steps"][0]["requestInfo"]["type"] = request_type # 返回extractInfo for extract in testcase_request["teststeps"][last_teststeps][ "extract"]: for extract_key, extract_value in extract.items(): response["steps"][0]["extractInfo"].append({ "saveAs": extract_key, "check": extract_value }) # 返回validateInfo for validate in testcase_request["teststeps"][last_teststeps][ "validate"]: for comparator, veirfy in validate.items(): if comparator == 'db_validate' and veirfy[0].endswith( '$DB_CONNECT'): veirfy[0] = veirfy[0].split("$DB_")[0] response["steps"][0]["validateInfo"].append({ "comparator": comparator, "desc": comparator, "check": veirfy[0], "expect": veirfy[1], "comment": veirfy[2] if len(veirfy) >= 3 else '', }) # 返回include if not (include is None or len(include) < 3): testcase_include = json.loads(include) include_list = [{"public_variables": []}] for pv_id in testcase_include[0]["public_variables"]: obj = pvim.get_variable(id=pv_id) if not obj: continue id_, name, type_name, desc = obj.id, obj.variable_name, obj.type, obj.simple_desc value = [v.strip() for v in obj.value.strip('##').split('##')][0] include_list[0]["public_variables"].append({ "id": id_, "name": name, "value": value, "type": type_name, "desc": desc }) response["include"] = include_list return response
def get_all_pv_id_list(self, target_pv_id_list, testcase_id_list=None, testcase_main_id_list=None): if testcase_id_list: for testcase_id in testcase_id_list: obj = self.atim.get_testcase(id=testcase_id) include_list = json_loads(obj.include) public_variables_list = [] for include in include_list: if 'public_variables' in include: public_variables_list = include['public_variables'] # public_variables_list = include_list[0]['public_variables'] # setup_cases_list = include_list[1]['setup_cases'] for public_variable_id in public_variables_list: if public_variable_id not in target_pv_id_list: target_pv_id_list.append(public_variable_id) if obj.setup_case_list: setup_case_list = json_loads(obj.setup_case_list) for setup_case_str in setup_case_list: case_type, case_id, case_flow_id = parse_setup_case_str( setup_case_str) if case_type == 1: testcase_id_list = [case_id] target_pv_id_list = self.get_all_pv_id_list( target_pv_id_list, testcase_id_list=testcase_id_list) elif case_type == 2: testcase_main_id_list = [case_id] target_pv_id_list = self.get_all_pv_id_list( target_pv_id_list, testcase_main_id_list=testcase_main_id_list) elif testcase_main_id_list: exist_main_teardown_var_name = set() # 已加载的全链路独立后置中的公共变量名称集合 for testcase_id in testcase_main_id_list: tm_obj = self.atmm.get_testcase_main(id=testcase_id) sub_list = json_loads(tm_obj.sub_list) for sub_id in sub_list: ts_obj = self.atsm.get_testcase_sub(id=sub_id) include_list = json_loads(ts_obj.include) public_variables_list = include_list[0]['public_variables'] for public_variable_id in public_variables_list: if public_variable_id not in target_pv_id_list: target_pv_id_list.append(public_variable_id) # 处理全链路用例独立后置步骤中的公共变量 if tm_obj.main_teardown_hooks: variable_regexp = r"\$([\w_]+)" main_teardown_variables = re.findall( variable_regexp, str(tm_obj.main_teardown_hooks)) for target in main_teardown_variables: if target in exist_main_teardown_var_name: continue intf_id = ts_obj.api_intf_id intf_obj = ApiIntfInfoManager.get_intf(id=intf_id) system_id = intf_obj.api_system_id s_var_obj = ApiPublicVariableInfoManager.get_variable( variable_name=target, api_system_id=system_id) if s_var_obj: target_pv_id_list.append(s_var_obj.id) else: company_id = ApiSystemInfoManager.get_system( id=system_id).api_company_id c_var_obj = ApiPublicVariableInfoManager.get_variable( variable_name=target, api_company_id=company_id) if c_var_obj: target_pv_id_list.append(c_var_obj.id) exist_main_teardown_var_name.add(target) return target_pv_id_list
class ApiPublicVariable(Resource): def __init__(self): self.apv = ApiPublicVariableInfoManager() self.atim = ApiTestcaseInfoManager() self.asim = ApiSystemInfoManager() self.apim = ApiProjectInfoManager() self.acim = ApiCompanyInfoManager() self.aiim = ApiIntfInfoManager() self.atmm = ApiTestcaseMainManager() self.atsm = ApiTestcaseSubManager() self.custom = read_custom() self.data = get_request_json() self.username = redis.get_username(request.headers.get('X-Token')) @timer @login_check def get(self, action): if action == 'list': page = request.args.get('page', 1, type=int) num = request.args.get('num', 10, type=int) keywords = request.args.get('keywords', None, type=str) variable_objs = self.apv.public_variable_paginate( page, num, keywords=keywords) total = variable_objs.total data = [] for variable in variable_objs.items: if variable.api_system_id: system_obj = self.asim.get_system( id=variable.api_system_id) company_obj = self.acim.get_company( id=system_obj.api_company_id) company_id = system_obj.api_company_id system_id = variable.api_system_id company_name = company_obj.company_name system_name = system_obj.system_name elif variable.api_company_id: company_obj = self.acim.get_company( id=variable.api_company_id) company_id = variable.api_company_id company_name = company_obj.company_name system_id = None system_name = None else: company_id = None system_id = None company_name = None system_name = None variable_dict = {} variable_value = variable.value # 变量类型-files if variable.type == 'files': if isinstance(variable_value, str): '''windows下文件路径 C:\\users: \\json解析报错,先替换成\\\\''' try: variable_value = json.loads( variable_value.replace('\\', '\\\\')) variable_value = json.loads( json.dumps(variable_value).replace( '\\\\', '\\')) except TypeError: variable_value = json.loads(variable_value) variable_dict["name"] = variable.variable_name variable_dict["type"] = "files" variable_dict["type_desc"] = "文件" variable_dict["value"] = variable_value # 自定义变量-db elif variable_value.startswith("${variable_db_operation("): variable_dict["name"] = variable.variable_name variable_dict["type"] = "db" variable_dict["type_desc"] = "数据库操作" variable_dict["value"] = variable_value.replace( "${variable_db_operation(", "", 1).replace("||$DB_CONNECT)}", "", 1) # 变量类型-function elif variable_value.startswith( '${') and variable_value.endswith('}'): func_name = variable_value.split('${')[-1].split('(')[0] if 'variable_db_operation' == func_name: continue # args_list = variable_value.split('(')[-1].split(')')[0].split(',') args_list = variable_value[:-2].split('(', 1)[-1].split('||') args_dict = {} for func in self.custom["functions"]: if func["name"] == func_name: for a, p in zip(args_list, func["parameters"]): args_dict[p] = a break variable_dict["name"] = variable.variable_name variable_dict["type"] = "function" variable_dict["type_desc"] = "特定函数生成" variable_dict["value"] = func_name variable_dict["args"] = args_dict # 变量类型-constant else: variable_dict["name"] = variable.variable_name variable_dict["type"] = "constant" variable_dict["type_desc"] = "key-value" variable_dict["value"] = variable_value variable_dict[ "saveAs"] = variable.save_as if variable.save_as else 'str' variable_dict.update({ "variable_id": variable.id, "simple_Desc": variable.simple_desc, "creator": username_to_nickname(variable.creator), "system_id": system_id, "company_id": company_id, "company_name": company_name, "system_name": system_name }) data.append(variable_dict) return make_response({"code": "000", "total": total, "desc": data}) @timer def post(self, action): if action == 'addVariable': return self.add_variable() elif action == "delete": return self.delete_variable() elif action == "edit": return self.edit_variable() elif action == "detail": return self.detail() elif action == "querySupportPubVariables": return self.query_support_pub_variables() elif action == "queryPubVariablesByTestcaseList": return self.query_pub_variables_by_testcase_list() else: return make_response({ "code": "100", "desc": "url错误,不存在的接口动作<{action}>".format(action=action) }) @developer_check def add_variable(self): """ input: { "variableName":1, "type":"function", "value":"123", "simpleDesc":"s", "systemId":"1", "companyId":"1", "saveAs": "str", } """ try: system_id = self.data.pop("systemId", None) company_id = self.data.pop("companyId", None) variable_name = self.data.pop("variableName") variable_type = self.data.pop("variableType") value = self.data.pop("value") args = self.data.pop("args", None) simple_desc = self.data.pop("simpleDesc", None) save_as = self.data.pop("saveAs", "str") except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) if system_id: if self.apv.get_variable(variable_name=variable_name, api_system_id=system_id): return make_response({ "code": "201", "desc": "变量名{}已经存在,请重新添加".format(variable_name) }) elif company_id: if self.apv.get_variable(variable_name=variable_name, api_company_id=company_id): return make_response({ "code": "202", "desc": "变量名{}已经存在,请重新添加".format(variable_name) }) else: return make_response({ "code": "300", "desc": "systemId/companyId二选一必填" }) if variable_type == 'files' and isinstance(value, list): value_str = json.dumps(value) elif variable_type == 'function': value_str = transfer_function_variable_to_expression(value, args) else: value_str = value self.apv.insert_variable(api_company_id=company_id, api_system_id=system_id, variable_name=variable_name, type=variable_type, value=value_str, simple_desc=simple_desc, creator=self.username, save_as=save_as) return make_response({ "code": "000", "desc": "变量{}新增成功".format(variable_name) }) @developer_check def delete_variable(self): """根据变量名称(唯一)删除变量 input: { "variable_name":"test", "systemId":"1" } """ try: variable_id = int(self.data.pop("variableId")) # id_=data.pop("id") except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) pv_obj = self.apv.get_variable(id=variable_id) if not pv_obj: return make_response({ "code": "000", "desc": "变量id{}不存在,请刷新后重试".format(variable_id) }) include_list = self.atim.query_all_testcases_include() for row in include_list: if not row[0]: continue include = json_loads(row[0]) if 'public_variables' in include[0]: if variable_id in include[0]['public_variables']: return make_response({ "code": "200", "desc": "存在用例引用公共变量,无法直接删除" }) self.apv.delete_variable(pv_obj.id) return make_response({"code": "000", "desc": "变量删除成功"}) @developer_check def edit_variable(self): """ 根据变量id或者变量名称编辑变量 input: { "variable_name:" } """ try: id_ = self.data.pop('id') variable_name = self.data.pop("variableName") value = self.data.pop("value", None) variable_type = self.data.pop("variableType", None) simple_desc = self.data.pop("simpleDesc", None) system_id = self.data.pop("systemId", None) company_id = self.data.pop("companyId", None) args = self.data.pop("args", None) save_as = self.data.pop("saveAs", "str") except KeyError: return make_response({"code": "100", "desc": "传参错误"}) # 变量名称唯一:如果想修改的变量名称,在作用域内被其它变量已使用,不能修改 if system_id: if not self.asim.get_system(id=system_id): return make_response({"code": "101", "desc": "systemId不存在"}) if self.apv.whether_variable_name_canbeupdated( variable_name, id_, system_id): return make_response({ "code": "102", "desc": "变量名{}已存在,请重新修改".format(variable_name) }) elif company_id: if not self.acim.get_company(id=company_id): return make_response({"code": "101", "desc": "companyId不存在"}) if self.apv.whether_variable_name_canbeupdated_in_company_id( variable_name, id_, company_id): return make_response({ "code": "102", "desc": "变量名{}已存在,请重新修改".format(variable_name) }) else: return make_response({ "code": "201", "desc": "systemId/companyId二选一必填" }) if variable_type == 'files' and isinstance(value, list): value_str = json.dumps(value) elif variable_type == 'function': value_str = transfer_function_variable_to_expression(value, args) else: value_str = value self.apv.update_variable(id_, variable_name=variable_name, value=value_str, type=variable_type, simple_desc=simple_desc, api_system_id=system_id, api_company_id=company_id, save_as=save_as) return make_response({ "code": "000", "desc": "变量{}已修改".format(variable_name) }) @login_check def detail(self): """根据变量名称,获取变量详情 ----未找到使用场景""" try: system_id = self.data.pop("systemId") variable_name = self.data.pop("variableName") except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) variable = self.apv.get_variable(api_system_id=system_id, variable_name=variable_name) if not variable: return make_response({ "code": "200", "desc": "该系统下的变量名{}不存在".format(variable_name) }) id_ = variable.id variable_name = variable.variable_name value = variable.value simple_desc = variable.simple_desc variable_type = variable.type if variable.system_id: system_obj = self.asim.get_system(id=variable.system_id) company_obj = self.acim.get_company(id=system_obj.api_company_id) company_name = company_obj.company_name system_name = system_obj.system_name else: company_name = None system_name = None return make_response({ "code": "000", "data": { "id": id_, "company_name": company_name, "system_name": system_name, "variable_name": variable_name, "value": value, "type": variable_type, "simpleDesc": simple_desc } }) @login_check def query_support_pub_variables(self): """获取某一类型下的变量列表 input: {variable_type:"constant"} output:{ "code": "000", "desc": { "constant": [ { "id": 7, "simpleDesc": "ssd", "value": "dfssfds", "variable_name": "hejianhao05" }, { "id": 11, "simpleDesc": "gdfg", "value": "dfgdf", "variable_name": "dgfdfgfdg" }, { "id": 16, "simpleDesc": null, "value": "select * from fromfrormrmf", "variable_name": "hjhdf" } ] } }""" objs = self.apv.get_variables() desc_dic = {"constant": [], "db": [], "function": [], "files": []} for obj in objs: for desc_key in desc_dic.keys(): if obj.type == desc_key: desc_dic[desc_key].append({ "id": obj.id, "variable_name": obj.variable_name, "value": obj.value, "simpleDesc": obj.simple_desc }) break return make_response({"code": "000", "desc": desc_dic}) @login_check def query_pub_variables_by_testcase_list(self): """ 根据testcase_id_list查询当前用例以及所有前置用例引用的公共变量信息 url:/atp/apiPublicVariable/queryPubVariablesByTestcaseList input:{"testcaseList":["666", "999"]} output:{ "code": "000", "pubVariablesList": [ { "id": "", "name": "", "value": "", "type": "", "optionValues": ["" , ""] }, { "id": "", "name": "", "value": "", "type": "", "optionValues": [] } ] } """ try: testcase_id_list = self.data.pop("testcaseList", None) testcase_main_id_list = self.data.pop("testcaseMainList", None) except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) if not testcase_id_list and not testcase_main_id_list: return make_response({"code": "100", "desc": "入参校验失败"}) target_pv_id_list = self.get_all_pv_id_list( [], testcase_id_list=testcase_id_list, testcase_main_id_list=testcase_main_id_list) print(target_pv_id_list) pv_objs = self.apv.get_variables_in_id_list(target_pv_id_list) data_list = [] for pv_obj in pv_objs: """ from pv_obj.value : "12|| wudi || sad2s||" to pv_value_list : ['12', 'wudi', 'sad2s'] """ '''如果是文件类型的变量,暂不支持可选值''' if pv_obj.type == 'files': continue elif pv_obj.type == 'function': pv_value_list = [] default_value = str(pv_obj.value).strip() else: pv_value_list = [ v.strip() for v in str(pv_obj.value).strip('##').split('##') ] default_value = pv_value_list.pop(0) tmp_dic = { "id": pv_obj.id, "name": pv_obj.variable_name, "value": default_value, "type": pv_obj.type, "optionValues": pv_value_list } data_list.append(tmp_dic) return make_response({"code": "000", "pubVariablesList": data_list}) def get_all_pv_id_list(self, target_pv_id_list, testcase_id_list=None, testcase_main_id_list=None): if testcase_id_list: for testcase_id in testcase_id_list: obj = self.atim.get_testcase(id=testcase_id) include_list = json_loads(obj.include) public_variables_list = [] for include in include_list: if 'public_variables' in include: public_variables_list = include['public_variables'] # public_variables_list = include_list[0]['public_variables'] # setup_cases_list = include_list[1]['setup_cases'] for public_variable_id in public_variables_list: if public_variable_id not in target_pv_id_list: target_pv_id_list.append(public_variable_id) if obj.setup_case_list: setup_case_list = json_loads(obj.setup_case_list) for setup_case_str in setup_case_list: case_type, case_id, case_flow_id = parse_setup_case_str( setup_case_str) if case_type == 1: testcase_id_list = [case_id] target_pv_id_list = self.get_all_pv_id_list( target_pv_id_list, testcase_id_list=testcase_id_list) elif case_type == 2: testcase_main_id_list = [case_id] target_pv_id_list = self.get_all_pv_id_list( target_pv_id_list, testcase_main_id_list=testcase_main_id_list) elif testcase_main_id_list: exist_main_teardown_var_name = set() # 已加载的全链路独立后置中的公共变量名称集合 for testcase_id in testcase_main_id_list: tm_obj = self.atmm.get_testcase_main(id=testcase_id) sub_list = json_loads(tm_obj.sub_list) for sub_id in sub_list: ts_obj = self.atsm.get_testcase_sub(id=sub_id) include_list = json_loads(ts_obj.include) public_variables_list = include_list[0]['public_variables'] for public_variable_id in public_variables_list: if public_variable_id not in target_pv_id_list: target_pv_id_list.append(public_variable_id) # 处理全链路用例独立后置步骤中的公共变量 if tm_obj.main_teardown_hooks: variable_regexp = r"\$([\w_]+)" main_teardown_variables = re.findall( variable_regexp, str(tm_obj.main_teardown_hooks)) for target in main_teardown_variables: if target in exist_main_teardown_var_name: continue intf_id = ts_obj.api_intf_id intf_obj = ApiIntfInfoManager.get_intf(id=intf_id) system_id = intf_obj.api_system_id s_var_obj = ApiPublicVariableInfoManager.get_variable( variable_name=target, api_system_id=system_id) if s_var_obj: target_pv_id_list.append(s_var_obj.id) else: company_id = ApiSystemInfoManager.get_system( id=system_id).api_company_id c_var_obj = ApiPublicVariableInfoManager.get_variable( variable_name=target, api_company_id=company_id) if c_var_obj: target_pv_id_list.append(c_var_obj.id) exist_main_teardown_var_name.add(target) return target_pv_id_list
def _add_pv(self, testset, tc_obj, intf_obj, tm_obj=None): """ 添加公共变量到config """ # testset增加主用例用例独立后置中的公共变量 if not self.has_extract_variable_in_main_teardown and tm_obj and tm_obj.main_teardown_hooks: variable_regexp = r"\$([\w_]+)" # main_teardown_hooks = json_loads(tm_obj.main_teardown_hooks) main_teardown_variables = re.findall(variable_regexp, str(tm_obj.main_teardown_hooks)) for target in main_teardown_variables: system_id = intf_obj.api_system_id s_var_obj = ApiPublicVariableInfoManager.get_variable(variable_name=target, api_system_id=system_id) if s_var_obj: testset["config"]["variables"].append({ target: s_var_obj.value.split('##')[0] }) else: company_id = ApiSystemInfoManager.get_system(id=system_id).api_company_id c_var_obj = ApiPublicVariableInfoManager.get_variable( variable_name=target, api_company_id=company_id) if c_var_obj: testset["config"]["variables"].append({ target: c_var_obj.value.split('##')[0] }) self.has_extract_variable_in_main_teardown = True teststep = testset["teststeps"][0] include_list = json_loads(tc_obj.include) pv_list = None for include in include_list: if "public_variables" in include: pv_list = include["public_variables"] break """用例存在引用公共变量""" if pv_list: """存在公共变量临时修改""" if self.confirmed_pv_changes: for pv_change_dic in self.confirmed_pv_changes: if pv_change_dic['changedValue']: if pv_change_dic['type'] == 'files': continue # 暂不支持文件类型公共变量临时修改 elif pv_change_dic['type'] in ['constant', 'function', 'db']: if int(pv_change_dic['pvId']) in pv_list: pv_list.remove(int(pv_change_dic['pvId'])) testset["config"]["variables"].append({ pv_change_dic['name']: pv_change_dic['changedValue'] }) # if int(pv_change_dic['pvId']) in pv_list: # if pv_change_dic['type'] == 'files': # continue # 暂不支持文件类型公共变量临时修改 # pv_list.remove(int(pv_change_dic['pvId'])) # testset["config"]["variables"].append({ # pv_change_dic['name']: pv_change_dic['changedValue'] # }) pv_objs = avim.get_variables_in_id_list(pv_list) for obj in pv_objs: if obj.type == 'files': """特殊处理files类型的公共变量""" file_variable_name = obj.variable_name try: file_path_list = eval(obj.value) except (SyntaxError, NameError): file_path_list = None if not isinstance(file_path_list, list): continue target_key = None for key in teststep['request']['json']: if teststep['request']['json'][key] == '$' + file_variable_name: teststep['request']['files'] = [] for i in range(len(file_path_list)): if 'f_name' in teststep['request']['json']: file_name = teststep['request']['json']['f_name'][i] else: file_name = str(file_path_list[i]).split('/')[-1] try: teststep['request']['files'].append( (key, (file_name, open(file_path_list[i], "rb"), "multipart/form-data")) ) except FileNotFoundError: # 公共变量指定的文件不存在 pass target_key = key break if target_key: teststep['request']['json'].pop('f_name', 0) teststep['request']['json'].pop(target_key) teststep['request']['data'] = teststep['request']['json'] teststep['request'].pop('json') elif obj.type == 'function': """处理自定义方法类型的公共变量""" is_exist = False for exist_pv_dic in testset["config"]["variables"]: for key in exist_pv_dic: if key == obj.variable_name: is_exist = True if is_exist: break if not is_exist: variable_string = variable_string_add_param(str(obj.value)) testset["config"]["variables"].append({ obj.variable_name: variable_string }) elif obj.type == 'db': """处理db类型的公共变量""" is_exist = False for exist_pv_dic in testset["config"]["variables"]: for key in exist_pv_dic: if key == obj.variable_name: is_exist = True if is_exist: break if not is_exist: testset["config"]["variables"].append({ obj.variable_name: [v.strip() for v in str(obj.value).strip('##').split('##')][0] }) else: """处理key-value类型的公共变量""" is_exist = False for exist_pv_dic in testset["config"]["variables"]: for key in exist_pv_dic: if key == obj.variable_name: is_exist = True if is_exist: break if not is_exist: var_value = [v.strip() for v in str(obj.value).strip('##').split('##')][0] save_as = obj.save_as if obj.save_as else 'str' if save_as in ['num', 'bool', 'list', 'dict']: try: var_value = eval(var_value) except SyntaxError: var_value = var_value testset["config"]["variables"].append({ obj.variable_name: var_value }) return testset
def edit_intf(self): try: intf_id = self.data.pop('intfId') intf_desc = self.data.pop('intfNameInChinese') intf_type = self.data.pop('type') intf_info = self.data.pop('info') request_dic = self.data.pop('request', {}) request_detail_dic = self.data.pop('requestDetail', []) intf_relation = self.data.pop('intfRelation') except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) intf_obj = self.aiim.get_intf(id=intf_id) if not intf_obj: return make_response({"code": "202", "desc": "接口id\"{}\"不存在, 请刷新后重试".format(intf_id)}) if intf_type != 'MQ': header_variables = [] if intf_type == 'HTTP': intf_info['apiUrl'] = intf_info['apiUrl'].strip() intf_name = intf_info['apiUrl'] header = intf_info['headers'] variable_regexp = r"\$([\w_]+)" header_variables = re.findall(variable_regexp, header) elif intf_type == 'DUBBO': intf_info['dubboService'] = intf_info['dubboService'].strip() intf_info['dubboMethod'] = intf_info['dubboMethod'].strip() intf_name = '{0}.{1}'.format(intf_info['dubboService'], intf_info['dubboMethod']) company_id = self.asim.get_system(id=intf_obj.api_system_id).api_company_id system_id_list = [row.id for row in self.asim.get_systems(api_company_id=company_id)] for obj in self.aiim.get_intfs_in_system_id_list(system_id_list): if obj.intf_name == intf_name and int(obj.id) != int(intf_id): company_name = self.acim.get_company(id=company_id).company_name return make_response({"code": "201", "desc": "\"{0}\"公司下存在相同接口\"{1}\", 无法将当前接口修改为\"{1}\"".format( company_name, intf_name)}) else: intf_info['topic'] = intf_info['topic'].strip() intf_info['tag'] = intf_info['tag'].strip() intf_name = '{0}.{1}'.format(intf_info['topic'], intf_info['tag']) obj = self.aiim.get_intf(intf_name=intf_name, api_system_id=intf_obj.api_system_id) if obj and obj.id != intf_id: return make_response({"code": "201", "desc": "工程下存在相同MQ接口\"{}\", 请使用已存在的MQ接口".format(intf_name)}) if intf_relation: intf_relation = [i[1] for i in intf_relation] self.aiim.update_intf(intf_id, intf_name=intf_name, intf_desc=intf_desc, intf_type=intf_type, intf_info=json_dumps(intf_info), last_modifier=self.username, intf_relation=json_dumps(intf_relation)) else: self.aiim.update_intf(intf_id, intf_name=intf_name, intf_desc=intf_desc, intf_type=intf_type, intf_info=json_dumps(intf_info), last_modifier=self.username) self.aidrm.update_request_by_intf_id(intf_id, request=json_dumps(request_dic), request_detail=json_dumps(request_detail_dic)) # 保存接口headers中的公共变量到接口下的所有用例 if intf_type == 'HTTP' and header_variables: to_add_pv_id_list = [] pv_objs = ApiPublicVariableInfoManager.get_variables(api_company_id=company_id) for pv_obj in pv_objs: for header_variable in header_variables: if header_variable == pv_obj.variable_name: to_add_pv_id_list.append(pv_obj.id) break # 如果存在需添加的公共变量id if to_add_pv_id_list: tc_objs = ApiTestcaseInfoManager.get_testcases(api_intf_id=intf_id) for tc_obj in tc_objs: try: pv_id_list = json_loads(tc_obj.include)[0]['public_variables'] except (json.decoder.JSONDecodeError, IndexError, KeyError): pv_id_list = [] merge_pv_id_list = pv_id_list + to_add_pv_id_list merge_pv_id_list = list(set(merge_pv_id_list)) if set(merge_pv_id_list) != set(pv_id_list): include = json_dumps([{"public_variables": merge_pv_id_list}]) ApiTestcaseInfoManager.update_testcase(id_=tc_obj.id, include=include) ts_objs = ApiTestcaseSubManager.get_testcase_subs(api_intf_id=intf_id) for ts_obj in ts_objs: try: pv_id_list = json_loads(ts_obj.include)[0]['public_variables'] except (json.decoder.JSONDecodeError, IndexError, KeyError): pv_id_list = [] merge_pv_id_list = pv_id_list + to_add_pv_id_list merge_pv_id_list = list(set(merge_pv_id_list)) if set(merge_pv_id_list) != set(pv_id_list): include = json_dumps([{"public_variables": merge_pv_id_list}]) ApiTestcaseSubManager.update_testcase_sub(id_=ts_obj.id, include=include) return make_response({"code": "000", "desc": "接口\"{}\"修改成功".format(intf_name)})