def __init__(self): self.data = get_request_json() self.username = redis.get_username(request.headers.get('X-Token')) # self.acim = ApiCompanyInfoManager() # self.asim = ApiSystemInfoManager() # self.aiim = ApiIntfInfoManager() # self.atim = ApiTestcaseInfoManager() self.aplm = ApiProductLineManager() self.atmm = ApiTestcaseMainManager()
def __init__(self): self.data = get_request_json() self.username = redis.get_username(request.headers.get('X-Token')) self.atmtrm = ApiTestcaseMainTagRelationManager() self.aplm = ApiProductLineManager() self.atmm = ApiTestcaseMainManager() self.aiim = ApiIntfInfoManager() self.atsm = ApiTestcaseSubManager() self.atrqm = ApiTestcaseRequestQllManager() self.ttm = TestcaseTagManager() if self.username: self.data["userName"] = self.username
def query_related_cases_by_sub_id(self): try: sub_id = self.data.pop("subId") except KeyError: return make_response({"code": "100", "desc": "入参校验错误"}) sub_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id) if not sub_obj or not sub_obj.main_list or not json_loads( sub_obj.main_list): return make_response({"code": "101", "desc": "没有关联的用例信息"}) main_id_list = json_loads(sub_obj.main_list) main_objs = ApiTestcaseMainManager.get_testcases_in_id_list( main_id_list) data_list = [] for main_obj in main_objs: p_obj = ApiProductLineManager.get_product_line( id=main_obj.api_product_line_id) data_dic = { "testcaseId": main_obj.id, "testcaseName": main_obj.testcase_name, "productLineDesc": get_full_product_line_name(p_obj) } data_list.append(data_dic) return make_response({"code": "000", "data": data_list})
def get_full_product_line_name(p_obj, tail_name=''): """获取全链路用例完整节点信息""" full_product_line_name = '{0} -> {1}'.format(p_obj.product_line_name, tail_name) if not p_obj.parent_id: return full_product_line_name.strip(' ->') else: parent_p_obj = ApiProductLineManager.get_product_line(id=p_obj.parent_id) return get_full_product_line_name(parent_p_obj, tail_name=full_product_line_name)
def add_memo(summary): """增加一些备注,并且记录生成的公共变量""" details = summary['details'] for detail_dic in details: # 每条用例 in_out = detail_dic.pop('in_out', None) # 全链路用例增加信息 if detail_dic['is_main']: case_id = 'M' + str(detail_dic['case_id']) if 'testcase_main_id' not in summary: # summary['testcase_main_id'] = detail_dic['case_id'] testcase_main_obj = ApiTestcaseMainManager.get_testcase_main(id=detail_dic['case_id']) # summary['testcase_main_name'] = testcase_main_obj.testcase_name p_obj = ApiProductLineManager.get_product_line(id=testcase_main_obj.api_product_line_id) summary['product_line_id'] = p_obj.id summary['product_line_name'] = get_full_product_line_name(p_obj) # 接口用例增加信息 else: case_id = str(detail_dic['case_id']) if 'intf_id' not in summary: summary['intf_id'] = detail_dic['intf_id'] intf_obj = ApiIntfInfoManager.get_intf(id=detail_dic['intf_id']) summary['intf_name'] = '{0}-{1}'.format(intf_obj.intf_desc, intf_obj.intf_name) system_obj = ApiSystemInfoManager.get_system(id=intf_obj.api_system_id) summary['system_id'] = system_obj.id summary['system_name'] = system_obj.system_name # 记录随机生成的数据,方便追溯和定时清理数据 if in_out: record_keys = ['MOBILE_NO', 'ID_NO', 'BANK_CARD_NO_CREDIT', 'BANK_CARD_NO_DEBIT'] mobile_no, id_no, bank_card_no_credit, bank_card_no_debit = '', '', '', '' is_found = False for var, var_value in in_out['in'].items(): for key in record_keys: if key == var: is_found = True if var == 'MOBILE_NO': mobile_no = var_value elif var == 'ID_NO': id_no = var_value elif var == 'BANK_CARD_NO_CREDIT': bank_card_no_credit = var_value elif var == 'BANK_CARD_NO_DEBIT': bank_card_no_debit = var_value break if is_found: GenerateDataRecordManager.insert_record( case_id=case_id, mobile_no=mobile_no, id_no=id_no, bank_card_no_credit=bank_card_no_credit, bank_card_no_debit=bank_card_no_debit) return summary
def product_line_subtree(self): """根据公司id查询配置在该公司下的产品线-目录-目录-...-全链路用例""" try: company_id = self.data.pop('companyId') with_sub = self.data.pop('withSub', None) tag_id_list = self.data.pop('tagIdList', None) without_testcase = self.data.pop('withoutTestcase', None) except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) if not (isinstance(tag_id_list, list) and len(tag_id_list) in [1, 2]): tag_id_list = None self.all_sub_objs = ApiTestcaseSubManager.get_testcase_subs() subtree = [] index = 0 pl_objs = ApiProductLineManager.get_product_lines( api_company_id=company_id) for pl_obj in pl_objs: index += 1 top_tree = { 'id': index, 'label': pl_obj.product_line_name, 'productLineId': pl_obj.id, 'children': [] } index = get_under_node(pl_obj.id, top_tree['children'], index, with_sub, tag_id_list, without_testcase, self.all_sub_objs) subtree.append(top_tree) if tag_id_list: # 过滤去除没有用例的节点 remove_no_case_node(subtree) return make_response({"code": "000", "data": subtree})
class ApiTestcaseMain(Resource): def __init__(self): self.data = get_request_json() self.username = redis.get_username(request.headers.get('X-Token')) self.atmtrm = ApiTestcaseMainTagRelationManager() self.aplm = ApiProductLineManager() self.atmm = ApiTestcaseMainManager() self.aiim = ApiIntfInfoManager() self.atsm = ApiTestcaseSubManager() self.atrqm = ApiTestcaseRequestQllManager() self.ttm = TestcaseTagManager() if self.username: self.data["userName"] = self.username @timer def post(self, action): if action == 'add': return self.add_testcase_main(action) elif action == 'edit': return self.edit_testcase_main(action) elif action == 'delete': return self.delete_testcase_main() elif action == 'queryByProductLine': return self.query_by_product_line() elif action == 'queryByIntfId': return self.query_by_intf_id() elif action == 'detail': return self.testcase_detail() elif action == 'changeStatus': return self.change_status() elif action == 'copy': return self.copy_testcase() elif action == 'setTag': return self.set_tag() elif action == 'changeParent': return self.change_parent() elif action == 'queryRelatedCasesBySubId': return self.query_related_cases_by_sub_id() elif action == 'getCustomFlows': return self.get_custom_flows() elif action == 'saveCustomFlows': return self.save_custom_flows() else: return make_response({ "code": "100", "desc": "url错误,不存在的接口动作<{action}>".format(action=action) }) @developer_check def add_testcase_main(self, action): try: handle_api_testcase_main(action, **self.data) except LoadCaseError: return make_response({"code": "201", "desc": "新增用例时出错"}) return make_response({"code": "000", "desc": "用例新增成功"}) @developer_with_limit_check def edit_testcase_main(self, action): try: handle_api_testcase_main(action, **self.data) except LoadCaseError: return make_response({"code": "201", "desc": "保存用例时出错"}) return make_response({"code": "000", "desc": "用例保存成功"}) @developer_with_limit_check def delete_testcase_main(self): try: testcase_id = int(self.data.pop('testcaseId')) except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) tm_obj = self.atmm.get_testcase_main(id=testcase_id) if not tm_obj: return make_response({ "code": "200", "desc": "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id) }) sub_list = json_loads(tm_obj.sub_list) if tm_obj.case_type == 2: for sub_id in sub_list: sub_obj = self.atsm.get_testcase_sub(id=sub_id) main_list = json_loads( sub_obj.main_list) if sub_obj.main_list else [] if testcase_id in main_list: main_list.remove(testcase_id) self.atsm.update_testcase_sub( sub_id, main_list=json_dumps(main_list)) # self.atsm.delete_testcase_sub(sub_id) else: for sub_id in sub_list: sub_obj = self.atsm.get_testcase_sub(id=sub_id) if sub_obj.api_intf_id == tm_obj.api_intf_id: main_list = json_loads( sub_obj.main_list) if sub_obj.main_list else [] if testcase_id in main_list: main_list.remove(testcase_id) self.atsm.update_testcase_sub( sub_id, main_list=json_dumps(main_list)) # self.atsm.delete_testcase_sub(sub_id) self.atmm.delete_testcase_main(testcase_id) # 删除tag关系 relation_objs = self.atmtrm.get_relations(api_testcase_id=testcase_id) for relation_obj in relation_objs: self.atmtrm.delete_relation(relation_obj.id) return make_response({"code": "000", "desc": "测试用例删除成功"}) @login_check def query_by_product_line(self): """ 根据product_line查找该套件下的所有测试用例: 分页展示,支持用例名称搜索 """ try: product_line_id = self.data.pop('productLineId') page_no = int(self.data.pop('pageNo')) page_size = int(self.data.pop('pageSize')) testcase_name = self.data.pop('testcaseName', None) except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) if not self.aplm.get_product_line(id=product_line_id): return make_response({ "code": "201", "desc": "产品线id\"{}\"不存在, 请刷新后重试".format(product_line_id) }) # 查询所有标签{类别-场景}MAP tag_base_map = self.get_tag_base_map() case_obj = self.atmm.paging_query_testcase_by_product_line_id( product_line_id, page_no, page_size, testcase_name=testcase_name) desc_list = [] for i in case_obj.items: case_status = map_number_to_case_status(i.case_status) last_run = map_number_to_last_run(i.last_run) tag_relations = self.atmtrm.get_relations(api_testcase_id=i.id) tag_map = {} for base_category in tag_base_map: tag_map[base_category] = [] for relation in tag_relations: for category, tag_list in tag_base_map.items(): for tag_dic in tag_list: if tag_dic['tagId'] == relation.tag_id: tag_map[category].append(tag_dic) testcases_dict = { "id": i.id, "testcase_name": "{0}__{1}".format(i.testcase_name, i.expect_result), "testcase_desc": i.simple_desc, "expectResult": i.expect_result, "status": case_status, "creator": username_to_nickname(i.creator), "last_modifier": username_to_nickname(i.last_modifier), "last_run": last_run, "tags": tag_map, "createTime": format(i.create_time) if i.create_time else '', "updateTime": format(i.update_time) if i.update_time else '', "lastRunTime": format(i.last_run_time) if i.last_run_time else '', } desc_list.append(testcases_dict) return make_response({ "code": "000", "desc": desc_list, "totalNum": case_obj.total }) @login_check def query_by_intf_id(self): """ 根据intf_id查找该套件下的所有测试用例: 分页展示,支持用例名称搜索 """ try: intf_id = self.data.pop('intfId') page_no = int(self.data.pop('pageNo')) page_size = int(self.data.pop('pageSize')) testcase_name = self.data.pop('testcaseName', None) except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) if not self.aiim.get_intf(id=intf_id): return make_response({ "code": "201", "desc": "接口id\"{}\"不存在, 请刷新后重试".format(intf_id) }) # 查询所有标签{类别-场景}MAP tag_base_map = self.get_tag_base_map() case_obj = self.atmm.paging_query_testcase_by_intf_id( intf_id, page_no, page_size, testcase_name=testcase_name) desc_list = [] for i in case_obj.items: case_status = map_number_to_case_status(i.case_status) last_run = map_number_to_last_run(i.last_run) tag_relations = self.atmtrm.get_relations(api_testcase_id=i.id) tag_map = {} for base_category in tag_base_map: tag_map[base_category] = [] for relation in tag_relations: for category, tag_list in tag_base_map.items(): for tag_dic in tag_list: if tag_dic['tagId'] == relation.tag_id: tag_map[category].append(tag_dic) testcases_dict = { "id": i.id, "testcase_name": i.testcase_name, "testcase_desc": i.simple_desc, "expectResult": i.expect_result, "status": case_status, "creator": username_to_nickname(i.creator), "last_modifier": username_to_nickname(i.last_modifier), "last_run": last_run, "tags": tag_map, "createTime": format(i.create_time) if i.create_time else '', "updateTime": format(i.update_time) if i.update_time else '', "lastRunTime": format(i.last_run_time) if i.last_run_time else '', } desc_list.append(testcases_dict) return make_response({ "code": "000", "desc": desc_list, "totalNum": case_obj.total }) @developer_check def testcase_detail(self): try: testcase_id = self.data.pop("testcaseId") except KeyError: return make_response({"code": "100", "desc": "入参校验错误"}) tm_obj = self.atmm.get_testcase_main(id=testcase_id) if not tm_obj: return make_response({ "code": "101", "desc": "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id) }) testcase_detail = get_api_testcase_main_detail(tm_obj) return make_response({"code": "000", "data": testcase_detail}) @developer_check def change_status(self): try: testcase_id = self.data.pop("id") except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) obj = self.atmm.get_testcase_main(id=testcase_id) case_status = 1 if obj.case_status == 0 else 0 self.atmm.update_testcase_main(id_=testcase_id, case_status=case_status) return make_response({"code": "000", "desc": "操作成功"}) @developer_check def copy_testcase(self): try: testcase_id = self.data.pop('id') copy_num = int(self.data.pop('copyNum')) copy_type = int(self.data.pop('copyType', 1)) # 1:复制主用例,引用子用例 2:复制主用例和子用例 except (KeyError, ValueError): return make_response({"code": "100", "desc": "入参校验失败"}) tm_obj = self.atmm.get_testcase_main(id=testcase_id) if tm_obj.case_type == 2: product_line_id = tm_obj.api_product_line_id pre_obj = self.atmm.get_last_obj_by_product_line(product_line_id) else: intf_id = tm_obj.api_intf_id pre_obj = self.atmm.get_last_obj_by_intf(intf_id) index = pre_obj.index + 1 if pre_obj else 0 table_last_obj = self.atmm.get_last_obj() insert_id = table_last_obj.id + 1 if table_last_obj else 1 if copy_type == 2: from_sub_list = json_loads(tm_obj.sub_list) sub_info_list = [] for from_sub_id in from_sub_list: t_sub_obj = self.atsm.get_testcase_sub(id=from_sub_id) tr_obj = self.atrqm.get_request(api_testcase_id=from_sub_id) sub_info_list.append({ 'request': tr_obj.request, 'sub_name': t_sub_obj.sub_name, 'request_type': t_sub_obj.request_type, 'include': t_sub_obj.include, 'simple_desc': t_sub_obj.simple_desc, 'case_type': t_sub_obj.case_type, 'api_intf_id': t_sub_obj.api_intf_id, 'creator': self.username, 'expect_result': t_sub_obj.expect_result, }) testcase_insert_list = [] testcase_id_list = [] for i in range(copy_num): update_list = copy.deepcopy(sub_info_list) to_sub_list = ApiTestcaseSubManager.batch_update_testcase_sub( update_list) case_name = tm_obj.testcase_name + '_copy_{0}_{1}'.format( testcase_id, i + 1) testcase_insert_list.append({ 'id': insert_id + i, 'testcase_name': case_name, 'simple_desc': tm_obj.simple_desc, 'case_type': tm_obj.case_type, 'case_status': tm_obj.case_status, 'api_intf_id': tm_obj.api_intf_id, 'api_product_line_id': tm_obj.api_product_line_id, 'sub_list': json_dumps(to_sub_list), 'creator': self.username, 'expect_result': tm_obj.expect_result, 'index': index + i, 'setup_flow_list': tm_obj.setup_flow_list, 'main_teardown_hooks': tm_obj.main_teardown_hooks, }) testcase_id_list.append(insert_id + i) self.atmm.batch_insert_testcase_main(testcase_insert_list) # 复制tag tag_relation_objs = self.atmtrm.get_relations( api_testcase_id=testcase_id) tag_id_list = [str(obj.tag_id) for obj in tag_relation_objs] tag_relation_insert_list = [] for i in range(copy_num): for tag_id in tag_id_list: tag_relation_insert_list.append({ 'api_testcase_id': testcase_id_list[i], 'tag_id': tag_id }) self.atmtrm.batch_insert_relation(tag_relation_insert_list) elif copy_type == 1: to_sub_list = json_loads(tm_obj.sub_list) testcase_insert_list = [] testcase_id_list = [] for i in range(copy_num): case_name = tm_obj.testcase_name + '_copy_{0}_{1}'.format( testcase_id, i + 1) testcase_insert_list.append({ 'id': insert_id + i, 'testcase_name': case_name, 'simple_desc': tm_obj.simple_desc, 'case_type': tm_obj.case_type, 'case_status': tm_obj.case_status, 'api_intf_id': tm_obj.api_intf_id, 'api_product_line_id': tm_obj.api_product_line_id, 'sub_list': json_dumps(to_sub_list), 'creator': self.username, 'expect_result': tm_obj.expect_result, 'index': index + i, 'setup_flow_list': tm_obj.setup_flow_list, 'main_teardown_hooks': tm_obj.main_teardown_hooks, }) testcase_id_list.append(insert_id + i) self.atmm.batch_insert_testcase_main(testcase_insert_list) # 复制tag tag_relation_objs = self.atmtrm.get_relations( api_testcase_id=testcase_id) tag_id_list = [str(obj.tag_id) for obj in tag_relation_objs] tag_relation_insert_list = [] for i in range(copy_num): for tag_id in tag_id_list: tag_relation_insert_list.append({ 'api_testcase_id': testcase_id_list[i], 'tag_id': tag_id }) self.atmtrm.batch_insert_relation(tag_relation_insert_list) else: return make_response({ "code": "101", "desc": "错误的copy_type:{0}".format(copy_type) }) return make_response({ "code": "000", "desc": "用例{0}复制成功, 数量{1}".format(testcase_id, copy_num) }) @developer_with_limit_check def set_tag(self): try: testcase_id = self.data.pop("testcaseId") tag_id_list = self.data.pop("tagIdList") except KeyError: return make_response({"code": "100", "desc": "入参校验错误"}) for tag_id in tag_id_list: if not self.ttm.get_testcase_tag(tag_id): return make_response({ "code": "200", "desc": "标签id\"{}\"不存在, 请刷新后重试".format(tag_id) }) set_testcase_tag(testcase_id, tag_id_list, is_main=True) return make_response({"code": "000", "desc": "设置标签成功"}) @login_check def query_related_cases_by_sub_id(self): try: sub_id = self.data.pop("subId") except KeyError: return make_response({"code": "100", "desc": "入参校验错误"}) sub_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id) if not sub_obj or not sub_obj.main_list or not json_loads( sub_obj.main_list): return make_response({"code": "101", "desc": "没有关联的用例信息"}) main_id_list = json_loads(sub_obj.main_list) main_objs = ApiTestcaseMainManager.get_testcases_in_id_list( main_id_list) data_list = [] for main_obj in main_objs: p_obj = ApiProductLineManager.get_product_line( id=main_obj.api_product_line_id) data_dic = { "testcaseId": main_obj.id, "testcaseName": main_obj.testcase_name, "productLineDesc": get_full_product_line_name(p_obj) } data_list.append(data_dic) return make_response({"code": "000", "data": data_list}) @login_check def get_custom_flows(self): try: testcase_id = self.data.pop('testcaseId') except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) flow_objs = ApiTestcaseMainCustomFlowManager.get_flows( testcase_id=testcase_id) data_list = [{ 'flowId': obj.id, 'flowName': obj.flow_name, 'flowIndexList': json_loads(obj.flow_index_list) } for obj in flow_objs] return make_response({"code": "000", "flowList": data_list}) @developer_check def save_custom_flows(self): try: testcase_id = self.data.pop('testcaseId') flow_list = self.data.pop('flowList') except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) save_flow(testcase_id, flow_list) return make_response({"code": "000", "desc": "保存成功"}) @developer_check def change_parent(self): try: testcase_id = self.data.pop('testcaseId') parent_id = self.data.pop('newParentId') except KeyError: return make_response({"code": "100", "desc": CODE_DESC_MAP["100"]}) tm_obj = self.atmm.get_testcase_main(id=testcase_id) if tm_obj.case_type == 2: pl_obj = self.aplm.get_product_line(id=parent_id) if not pl_obj: return make_response({ "code": "202", "desc": "不存在的目录id, 请刷新后重试" }) sub_obj = self.aplm.get_product_line(parent_id=pl_obj.id) if sub_obj: return make_response({ "code": "500", "desc": "移动失败,新目录下包含其他目录,请移动到最后一层目录中" }) pre_tm_obj = self.atmm.get_last_obj_by_product_line(parent_id) else: intf_obj = self.aiim.get_intf(id=parent_id) if not intf_obj: return make_response({ "code": "201", "desc": "不存在的接口id, 请刷新后重试" }) pre_tm_obj = self.atmm.get_last_obj_by_intf(parent_id) # 更新原产品线/原接口其他用例的index self.atmm.index_update_while_remove_testcase(id_=testcase_id) # 获取新产品线/新接口的用例index index = pre_tm_obj.index + 1 if pre_tm_obj else 0 # 更新 if tm_obj.case_type == 2: self.atmm.update_testcase_main(id_=testcase_id, api_product_line_id=parent_id, index=index) else: self.atmm.update_testcase_main(id_=testcase_id, api_intf_id=parent_id, index=index) return make_response({"code": "000", "desc": "移动成功"}) def get_tag_base_map(self): # 查询所有标签{类别-场景}MAP tag_objs = self.ttm.query_testcase_tag() tag_base_map = {} for tag_obj in tag_objs: if tag_obj.tag_category not in tag_base_map: tag_base_map[tag_obj.tag_category] = [{ "tagId": tag_obj.id, "tagName": tag_obj.tag_name }] else: tag_base_map[tag_obj.tag_category].append({ "tagId": tag_obj.id, "tagName": tag_obj.tag_name }) return tag_base_map
def get_under_node(parent_id, tree_list, index, with_sub, tag_id_list, without_testcase, all_sub_objs): pl_objs = ApiProductLineManager.get_product_lines(parent_id=parent_id) for pl_obj in pl_objs: index += 1 tree = { 'id': index, 'label': pl_obj.product_line_name, 'productLineId': pl_obj.id, 'children': [] } index = get_under_node(pl_obj.id, tree['children'], index, with_sub, tag_id_list, without_testcase, all_sub_objs) tree_list.append(tree) if without_testcase: return index # tm_objs = ApiTestcaseMainManager.get_testcase_mains(api_product_line_id=parent_id) res = ApiTestcaseMainManager.get_testcase_mains_in_tag( api_product_line_id=parent_id, tag_id_list=tag_id_list) for row in res: index += 1 tree = { 'id': index, 'label': str(row[0]) + '_' + row[1], 'testcaseId': row[0], 'children': [] } # 是否需要添加到子用例层 if with_sub: sub_list = json.loads(row[2]) # sub_objs = ApiTestcaseSubManager.get_testcase_subs_in_id_list(sub_list) # for sub_obj in sub_objs: # sub_tree = { # 'id': index, # 'label': sub_obj.sub_name, # 'subId': sub_obj.id, # } # tree['children'].append(sub_tree) # for sub_id in sub_list: # sub_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id) # sub_tree = { # 'id': index, # 'label': sub_obj.sub_name, # 'subId': sub_id, # 'children': [] # } # tree['children'].append(sub_tree) for sub_id in sub_list: for sub_obj in all_sub_objs: if sub_id == sub_obj.id: sub_tree = { 'id': index, 'label': sub_obj.sub_name, 'subId': sub_obj.id, } tree['children'].append(sub_tree) break tree_list.append(tree) return index
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
class ApiProductLine(Resource): def __init__(self): self.data = get_request_json() self.username = redis.get_username(request.headers.get('X-Token')) # self.acim = ApiCompanyInfoManager() # self.asim = ApiSystemInfoManager() # self.aiim = ApiIntfInfoManager() # self.atim = ApiTestcaseInfoManager() self.aplm = ApiProductLineManager() self.atmm = ApiTestcaseMainManager() @timer def post(self, action): if action == 'add': return self.add_product_line() elif action == 'edit': return self.edit_product_line() elif action == 'delete': return self.delete_product_line() elif action == 'changeParent': return self.change_folder_parent() else: return make_response({ "code": "100", "desc": "url错误,不存在的接口动作<{action}>".format(action=action) }) @developer_check def add_product_line(self): try: product_line_name = self.data.pop('productLineName') company_id = self.data.pop('companyId', None) parent_id = self.data.pop('parentId', None) if not company_id and not parent_id: raise KeyError except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) product_line_name = str(product_line_name).strip() if company_id: # 判断产品线是否已存在,存在无法添加 if self.aplm.get_product_line(product_line_name=product_line_name, api_company_id=company_id): return make_response({ "code": "201", "desc": "产品线\"{}\"已存在".format(product_line_name) }) self.aplm.insert_product_line(product_line_name=product_line_name, api_company_id=company_id, creator=self.username) return make_response({ "code": "000", "desc": "产品线\"{}\"增加成功".format(product_line_name) }) else: # 判断目录是否已存在,存在无法添加 if self.aplm.get_product_line(product_line_name=product_line_name, parent_id=parent_id): return make_response({ "code": "201", "desc": "目录\"{}\"已存在".format(product_line_name) }) self.aplm.insert_folder(product_line_name=product_line_name, parent_id=parent_id, creator=self.username) return make_response({ "code": "000", "desc": "目录\"{}\"增加成功".format(product_line_name) }) @developer_check def edit_product_line(self): try: product_line_id = self.data.pop('productLineId') product_line_name = self.data.pop('productLineName') except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) pl_obj = self.aplm.get_product_line(id=product_line_id) if pl_obj.api_company_id: if not pl_obj: return make_response({ "code": "202", "desc": "产品线id\"{}\"不存在, 请刷新后重试".format(product_line_id) }) elif self.aplm.get_product_line( product_line_name=product_line_name, api_company_id=pl_obj.api_company_id): return make_response({ "code": "201", "desc": "产品线\"{}\"已存在, 无法修改".format(product_line_name) }) self.aplm.update_product_line(product_line_id, product_line_name=product_line_name, last_modifier=self.username) return make_response({ "code": "000", "desc": "产品线\"{}\"修改成功".format(product_line_name) }) else: if not pl_obj: return make_response({ "code": "202", "desc": "目录id\"{}\"不存在, 请刷新后重试".format(product_line_id) }) elif self.aplm.get_product_line( product_line_name=product_line_name, parent_id=pl_obj.parent_id): return make_response({ "code": "201", "desc": "目录\"{}\"已存在, 无法修改".format(product_line_name) }) self.aplm.update_product_line(product_line_id, product_line_name=product_line_name, last_modifier=self.username) return make_response({ "code": "000", "desc": "目录\"{}\"修改成功".format(product_line_name) }) @developer_check def delete_product_line(self): try: product_line_id = self.data.pop('productLineId') except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) pl_obj = self.aplm.get_product_line(id=product_line_id) if pl_obj.api_company_id: if not pl_obj: return make_response({ "code": "202", "desc": "产品线id\"{}\"不存在, 请刷新后重试".format(product_line_id) }) sub_folder_objs = self.aplm.get_product_lines( parent_id=product_line_id) if sub_folder_objs: return make_response({ "code": "300", "desc": "产品线下已配置{}个目录,无法直接删除".format(len(sub_folder_objs)) }) tm_objs = self.atmm.get_testcase_mains( api_product_line_id=product_line_id) if tm_objs: return make_response({ "code": "300", "desc": "产品线下已配置{}个全链路用例,无法直接删除".format(len(tm_objs)) }) self.aplm.delete_product_line(product_line_id) return make_response({"code": "000", "desc": "产品线删除成功"}) else: if not pl_obj: return make_response({ "code": "202", "desc": "目录id\"{}\"不存在, 请刷新后重试".format(product_line_id) }) sub_folder_objs = self.aplm.get_product_lines( parent_id=product_line_id) if sub_folder_objs: return make_response({ "code": "300", "desc": "节点下已配置{}个目录,无法直接删除".format(len(sub_folder_objs)) }) tm_objs = self.atmm.get_testcase_mains( api_product_line_id=product_line_id) if tm_objs: return make_response({ "code": "300", "desc": "节点下已配置{}个全链路用例,无法直接删除".format(len(tm_objs)) }) self.aplm.delete_folder(product_line_id) return make_response({"code": "000", "desc": "目录删除成功"}) @developer_check def change_folder_parent(self): try: folder_id = self.data.pop('productLineId') new_parent_id = self.data.pop('newParentId') except KeyError: return make_response({"code": "100", "desc": "入参校验失败"}) folder_obj = self.aplm.get_product_line(id=folder_id) if not folder_obj: return make_response({ "code": "202", "desc": "目录id\"{}\"不存在, 请刷新后重试".format(folder_id) }) parent_obj = self.aplm.get_product_line(id=new_parent_id) if not parent_obj: return make_response({ "code": "203", "desc": "目录id\"{}\"不存在, 请刷新后重试".format(new_parent_id) }) kwargs = { 'id': folder_obj.id, 'product_line_name': folder_obj.product_line_name, 'simple_desc': folder_obj.simple_desc, # 'api_company_id': folder_obj.api_company_id, 'creator': folder_obj.creator, 'last_modifier': self.username, 'parent_id': new_parent_id, } self.aplm.delete_folder(folder_id) self.aplm.insert_folder(**kwargs) return make_response({"code": "000", "desc": "成功"})