Example #1
0
 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.apsrm = ApiProjectSystemRelationManager()
Example #2
0
 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.apirm = ApiProjectIntfRelationManager()
     self.aidrm = ApiIntfDefaultRequestManager()
Example #3
0
 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
Example #4
0
 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.atrm = ApiTestcaseRequestManager()
     self.attrm = ApiTestcaseTagRelationManager()
     self.ttm = TestcaseTagManager()
     self.atmm = ApiTestcaseMainManager()
     self.chain_list = []
     self.chain_no = 0
     if self.username:
         self.data["userName"] = self.username
Example #5
0
    def _load_main_testcase(self, testcase_main_id, testset=None, custom_flow_id=None):
        """
        循环加载子用例到testset
        """
        tm_obj = atmm.get_testcase_main(id=testcase_main_id)
        tm_obj.testcase_name = '{0}__{1}'.format(tm_obj.testcase_name, tm_obj.expect_result)
        sub_list = json_loads(tm_obj.sub_list)
        if custom_flow_id:
            # 存在指定自定义链路信息,按照链路切割sub_list
            flow_obj = atmcfm.get_flow(id=custom_flow_id)
            # sub_list = sub_list[flow_obj.start_sub_index:flow_obj.start_sub_index + 1]
            flow_index_list = json_loads(flow_obj.flow_index_list)
            new_sub_list = [sub_list[i] for i in flow_index_list]
            sub_list = new_sub_list

        sub_list.reverse()

        # 新加载方式,耗时减少60%
        union_list = split_list_to_union_list(sub_list)
        # print(union_list)
        sub_objs = []
        for part_list in union_list:
            part_sub_objs = atsm.get_testcase_subs_in_id_list(part_list)
            sorted_part_sub_objs = sort_objs_by_id_list(part_sub_objs, part_list)
            sub_objs.extend(sorted_part_sub_objs)

        intf_id_list = [sub_obj.api_intf_id for sub_obj in sub_objs]
        union_intf_id_list = split_list_to_union_list(intf_id_list)
        intf_objs = []
        for part_list in union_intf_id_list:
            part_intf_objs = aiim.get_intfs_in_id_list(part_list)
            sorted_part_intf_objs = sort_objs_by_id_list(part_intf_objs, part_list)
            intf_objs.extend(sorted_part_intf_objs)

        for i in range(len(sub_objs)):
            sub_obj = sub_objs[i]
            print('sub_id:{}'.format(sub_obj.id))
            ts_obj = sub_obj
            intf_obj = intf_objs[i]
            # print('intf_id:{}'.format(intf_obj.id))

            testset = self._add_to_testset(testset, tc_obj=ts_obj, intf_obj=intf_obj, tm_obj=tm_obj)

        # # 旧加载方式
        # for sub_id in sub_list:
        #     print('sub_id:{}'.format(sub_id))
        #     ts_obj = atsm.get_testcase_sub(id=sub_id)
        #     intf_obj = aiim.get_intf(id=ts_obj.api_intf_id)
        #
        #     testset = self._add_to_testset(testset, tc_obj=ts_obj, intf_obj=intf_obj, tm_obj=tm_obj)

        # 接口用例(case_type==1)可能存在前置全链路用例(目前还没有)
        if tm_obj.case_type == 1:
            setup_flow_list = json_loads(tm_obj.setup_flow_list)
            setup_flow_list.reverse()
            for flow_id in setup_flow_list:
                testset = self._load_main_testcase(flow_id, testset=testset, custom_flow_id=custom_flow_id)

        return testset
Example #6
0
    def _load_api_testcase_itself(self, testcase_id, testset=None):
        """
        加载单个接口用例到testset
        """
        tc_obj = atim.get_testcase(id=testcase_id)
        tc_obj.testcase_name = '{0}__{1}'.format(tc_obj.testcase_name, tc_obj.expect_result)
        intf_obj = aiim.get_intf(id=tc_obj.api_intf_id)

        testset = self._add_to_testset(testset, tc_obj, intf_obj)

        return testset
Example #7
0
    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'))
Example #8
0
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
Example #9
0
    def _load_api_testcase(self, testcase_id, testset=None):
        """
        递归加载接口用例到testset
        """
        tc_obj = atim.get_testcase(id=testcase_id)
        tc_obj.testcase_name = '{0}__{1}'.format(tc_obj.testcase_name, tc_obj.expect_result)
        intf_obj = aiim.get_intf(id=tc_obj.api_intf_id)
        include_list = json_loads(tc_obj.include)
        setup_cases_list = include_list[1]["setup_cases"]

        testset = self._add_to_testset(testset, tc_obj, intf_obj)

        if setup_cases_list:
            """存在前置用例"""
            for setup_case_id in reversed(setup_cases_list):
                """前置用例id不能和自身用例id相同"""
                if str(setup_case_id) != str(testcase_id):
                    """加载前置用例到testset"""
                    testset = self._load_api_testcase(setup_case_id, testset)

        return testset
Example #10
0
class ApiIntf(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.apirm = ApiProjectIntfRelationManager()
        self.aidrm = ApiIntfDefaultRequestManager()

    @timer
    def post(self, action):
        if action == 'add':
            return self.add_intf()

        elif action == 'edit':
            return self.edit_intf()

        elif action == 'delete':
            return self.delete_intf()

        elif action == 'detail':
            return self.intf_detail()

        elif action == 'queryBySystemId':
            return self.query_by_system_id()

        else:
            return make_response({"code": "100", "desc": "url错误,不存在的接口动作<{action}>".format(action=action)})

    @developer_check
    def add_intf(self):
        try:
            system_id = self.data.pop('systemId')
            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_desc = str(intf_desc).strip()

        if not self.asim.get_system(id=system_id):
            return make_response({"code": "201", "desc": "工程id\"{}\"不存在".format(system_id)})

        if intf_type != 'MQ':
            if intf_type == 'HTTP':
                intf_info['apiUrl'] = intf_info['apiUrl'].strip()
                intf_name = intf_info['apiUrl']
            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=system_id).api_company_id
            system_id_list = [row.id for row in self.asim.get_systems(api_company_id=company_id)]
            intf_name_list = [row.intf_name for row in self.aiim.get_intfs_in_system_id_list(system_id_list)]
            if intf_name in intf_name_list:
                company_name = self.acim.get_company(id=company_id).company_name
                return make_response({"code": "201", "desc": "\"{0}\"公司下存在相同接口\"{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=system_id)
            if obj:
                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.insert_intf(intf_name=intf_name, intf_desc=intf_desc, api_system_id=system_id,
                                  intf_type=intf_type, intf_info=json_dumps(intf_info), creator=self.username,
                                  intf_relation=json_dumps(intf_relation))
        else:
            self.aiim.insert_intf(intf_name=intf_name, intf_desc=intf_desc, api_system_id=system_id,
                                  intf_type=intf_type, intf_info=json_dumps(intf_info), creator=self.username)
        intf_obj = self.aiim.get_intf(intf_name=intf_name, intf_desc=intf_desc, api_system_id=system_id,
                                      intf_type=intf_type, intf_info=json_dumps(intf_info), creator=self.username)
        self.aidrm.insert_request(api_intf_id=intf_obj.id, request=json_dumps(request_dic),
                                  request_detail=json_dumps(request_detail_dic))
        return make_response({"code": "000", "desc": "接口\"{}\"增加成功".format(intf_name)})

    @developer_with_limit_check
    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)})

    @developer_with_limit_check
    def delete_intf(self):
        try:
            intf_id = self.data.pop('intfId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        if not self.aiim.get_intf(id=intf_id):
            return make_response({"code": "202", "desc": "接口id\"{}\"不存在, 请刷新后重试".format(intf_id)})

        testcase_objs = self.atim.get_testcases(api_intf_id=intf_id)
        if testcase_objs:
            return make_response({"code": "300", "desc": "接口下已编写{}个用例,无法直接删除".format(len(testcase_objs))})

        self.aiim.delete_intf(intf_id)
        self.aidrm.delete_request_by_intf_id(intf_id)
        relation_objs = self.apirm.get_relations(api_intf_id=intf_id)
        for relation_obj in relation_objs:
            self.apirm.delete_relation(relation_obj.id)
        return make_response({"code": "000", "desc": "接口删除成功"})

    @login_check
    def intf_detail(self):
        try:
            intf_id = self.data.pop('intfId')
        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)})

        try:
            info = json.loads(intf_obj.intf_info)
        except json.decoder.JSONDecodeError:
            return make_response({"code": "301", "desc": "intf_info字段解析异常"})

        intf_r_obj = self.aidrm.get_request(api_intf_id=intf_id)
        if intf_r_obj:
            request_dic = json.loads(intf_r_obj.request)
            request_detail_dic = json.loads(intf_r_obj.request_detail)
        else:
            request_dic = {}
            request_detail_dic = []

        # 处理依赖列表数据
        if intf_obj.intf_relation:
            relation_intf_objs = self.aiim.get_intfs_in_id_list(json.loads(intf_obj.intf_relation))
            intf_relation = [[i.api_system_id, i.id] for i in relation_intf_objs]
        else:
            intf_relation = []
        data = {
            'intfChineseName': intf_obj.intf_desc,
            'type': intf_obj.intf_type,
            'systemId': intf_obj.api_system_id,
            'info': info,
            'request': request_dic,
            'requestDetail': request_detail_dic,
            'intfRelation': intf_relation
        }
        return make_response({"code": "000", "data": data})

    @login_check
    def query_by_system_id(self):
        try:
            system_id = self.data.pop('systemId')
            project_id = self.data.pop('projectId', None)
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        all_intf_objs = self.aiim.get_intfs(api_system_id=system_id)
        # print(len(all_intf_objs))
        all_intf_list = []
        for obj in all_intf_objs:
            all_intf_list.append(
                {
                    'intfId': obj.id,
                    'label': obj.intf_name,
                }
            )

        include_intf_list = []
        intf_list = []
        if project_id:
            relation_objs = self.apirm.get_relations(api_project_id=project_id)
            for intf_dic in all_intf_list:
                is_include = False
                for relation_obj in relation_objs:
                    if relation_obj.api_intf_id == intf_dic['intfId']:
                        include_intf_list.append(
                            {
                                'intfId': intf_dic['intfId'],
                                'label': intf_dic['label'],
                            }
                        )
                        is_include = True
                        break
                if not is_include:
                    intf_list.append(
                        {
                            'intfId': intf_dic['intfId'],
                            'label': intf_dic['label'],
                        }
                    )
            return make_response({"code": "000", "intfList": intf_list, "includeIntfList": include_intf_list})
        else:
            return make_response({"code": "000", "intfList": all_intf_list, "includeIntfList": include_intf_list})
Example #11
0
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
Example #12
0
class ApiSystem(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.apsrm = ApiProjectSystemRelationManager()

    @timer
    def post(self, action):
        if action == 'add':
            return self.add_system()

        elif action == 'edit':
            return self.edit_system()

        elif action == 'delete':
            return self.delete_system()

        elif action == 'queryByCompanyId':
            return self.query_by_company_id()

        elif action == 'getGitBranchNamesBySystemId':
            return self.get_git_branch_names_by_system_id()

        else:
            return make_response({
                "code":
                "100",
                "desc":
                "url错误,不存在的接口动作<{action}>".format(action=action)
            })

    @master_check
    def add_system(self):
        try:
            company_id = self.data.pop('companyId')
            system_name = self.data.pop('systemName')
            git_ssh_url = self.data.pop('gitSshURL')
            simple_desc = self.data.pop('simpleDesc', None)
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        system_name = str(system_name).strip()
        git_ssh_url = str(git_ssh_url).strip()

        if not self.acim.get_company(id=company_id):
            return make_response({
                "code": "201",
                "desc": "公司id\"{}\"不存在".format(company_id)
            })

        if self.asim.get_system(system_name=system_name,
                                api_company_id=company_id):
            return make_response({
                "code":
                "201",
                "desc":
                "公司下存在相同工程名称\"{}\", 无法新增".format(system_name)
            })

        self.asim.insert_system(system_name=system_name,
                                simple_desc=simple_desc,
                                api_company_id=company_id,
                                git_url=git_ssh_url,
                                creator=self.username)
        return make_response({
            "code": "000",
            "desc": "工程\"{}\"增加成功".format(system_name)
        })

    @master_check
    def edit_system(self):
        try:
            system_id = self.data.pop('systemId')
            system_name = self.data.pop('systemName')
            git_ssh_url = self.data.pop('gitSshURL')
            simple_desc = self.data.pop('simpleDesc', None)
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        system_obj = self.asim.get_system(id=system_id)
        if not system_obj:
            return make_response({
                "code":
                "202",
                "desc":
                "工程id\"{}\"不存在, 请刷新后重试".format(system_id)
            })

        exist_system_obj = self.asim.get_system(
            system_name=system_name, api_company_id=system_obj.api_company_id)
        if exist_system_obj and exist_system_obj.id != int(system_id):
            return make_response({
                "code":
                "201",
                "desc":
                "公司下存在相同工程名称\"{}\", 无法修改".format(system_name)
            })

        self.asim.update_system(system_id,
                                system_name=system_name,
                                git_url=git_ssh_url,
                                simple_desc=simple_desc,
                                last_modifier=self.username)
        return make_response({
            "code": "000",
            "desc": "工程\"{}\"修改成功".format(system_name)
        })

    @master_check
    def delete_system(self):
        try:
            system_id = self.data.pop('systemId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        if not self.asim.get_system(id=system_id):
            return make_response({
                "code":
                "202",
                "desc":
                "工程id\"{}\"不存在, 请刷新后重试".format(system_id)
            })

        intf_objs = self.aiim.get_intfs(api_system_id=system_id)
        if intf_objs:
            return make_response({
                "code":
                "300",
                "desc":
                "工程下已配置{}个接口,无法直接删除".format(len(intf_objs))
            })

        self.asim.delete_system(system_id)
        return make_response({"code": "000", "desc": "工程删除成功"})

    # @login_check
    def query_by_company_id(self):
        try:
            company_id = self.data.pop('companyId')
            project_id = self.data.pop('projectId', None)
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        all_system_objs = self.asim.get_systems(api_company_id=company_id)
        all_system_list = []
        for obj in all_system_objs:
            all_system_list.append({
                'systemId': obj.id,
                'label': obj.system_name,
                'gitUrl': obj.git_url
            })

        include_system_list = []
        system_list = []
        if project_id:
            relation_objs = self.apsrm.get_relations(api_project_id=project_id)
            for system_dic in all_system_list:
                is_include = False
                for relation_obj in relation_objs:
                    if relation_obj.api_system_id == system_dic['systemId']:
                        include_system_list.append({
                            'systemId':
                            system_dic['systemId'],
                            'label':
                            system_dic['label'],
                        })
                        is_include = True
                        break
                if not is_include:
                    system_list.append({
                        'systemId': system_dic['systemId'],
                        'label': system_dic['label'],
                    })
            return make_response({
                "code": "000",
                "systemList": system_list,
                "includeSystemList": include_system_list
            })
        else:
            return make_response({
                "code": "000",
                "allSystemList": all_system_list
            })

    def get_git_branch_names_by_system_id(self):
        try:
            git_url = self.data.pop('gitUrl')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        git_userspace_name = git_url.split(":")[1].strip('.git')

        try:
            git = GitlabAPI()
            git_branches_list = git.get_project_branches(git_userspace_name)
            return make_response({
                "code": "000",
                "data": {
                    "gitUrl": git_url,
                    "gitBranchList": git_branches_list
                }
            })
        except:
            return make_response({"code": "999", "desc": "系统内部错误"})
Example #13
0
def get_testcase_chain(testcase_id,
                       case_type,
                       chain_list=None,
                       with_intf_system_name=None,
                       with_extract=None,
                       only_first=False,
                       main_case_flow_id=None,
                       childless=False):
    """
    根据testcase_id获取调用链, 包含接口用例和全链路用例
    return example:
    [
        {
            "preCaseId": 1,
            "preCaseName": "指定手机获取验证码",
            "preCaseType": "接口用例",
            "preIntfName": "接口描述-/url/api"
        },
        {
            "preCaseId": 27,
            "preCaseName": "新户申请钱包",
            "preCaseType": "全链路用例"
        },
        {
            "preCaseId": 2,
            "preCaseName": "登录",
            "preCaseType": "接口用例"
        }
    ]
    """
    if not chain_list:
        chain_list = []

    # 调用链最大长度保护
    if len(chain_list) >= 100:
        return chain_list

    if case_type == 1:
        tc_obj = ApiTestcaseInfoManager.get_testcase(id=testcase_id)
        if tc_obj:
            if with_intf_system_name:
                intf_obj = ApiIntfInfoManager.get_intf(id=tc_obj.api_intf_id)
                system_obj = ApiSystemInfoManager.get_system(
                    id=intf_obj.api_system_id)
                chain_row_dic = {
                    "preCaseName":
                    '{0}__{1}'.format(tc_obj.testcase_name,
                                      tc_obj.expect_result),
                    "preCaseId":
                    tc_obj.id,
                    "preCaseType":
                    get_desc_by_case_type(case_type),
                    "preIntfName":
                    '{0}-{1}'.format(intf_obj.intf_desc, intf_obj.intf_name),
                    "preSystemName":
                    system_obj.system_name
                }
                if with_extract:
                    # 解析出用例中提取变量
                    extract_v_names = get_extract_v_names(testcase_id)
                    public_v_names = get_public_v_names(tc_obj)
                    chain_row_dic.update({
                        "extract_v_names": extract_v_names,
                        "public_v_names": public_v_names
                    })
                chain_list.insert(0, chain_row_dic)
            else:
                chain_row_dic = {
                    "preCaseName":
                    '{0}__{1}'.format(tc_obj.testcase_name,
                                      tc_obj.expect_result),
                    "preCaseId":
                    tc_obj.id,
                    "preCaseType":
                    get_desc_by_case_type(case_type),
                }
                if with_extract:
                    # 解析出用例中提取变量
                    extract_v_names = get_extract_v_names(testcase_id)
                    public_v_names = get_public_v_names(tc_obj)
                    chain_row_dic.update({
                        "extract_v_names": extract_v_names,
                        "public_v_names": public_v_names
                    })
                chain_list.insert(0, chain_row_dic)
            if childless:
                chain_list[0]['hasChildren'] = False
                return chain_list
            setup_case_list = json.loads(
                tc_obj.setup_case_list) if tc_obj.setup_case_list else []
            setup_case_list.reverse()
            if setup_case_list:
                if only_first:
                    chain_list[0]['hasChildren'] = True
                    return chain_list
                else:
                    # 继续递归查询前置
                    for setup_case_str in setup_case_list:
                        setup_case_type, setup_case_id, option = parse_setup_case_str(
                            setup_case_str)
                        kwargs = {
                            'chain_list': chain_list,
                            'with_intf_system_name': with_intf_system_name,
                            'with_extract': with_extract
                        }
                        if setup_case_type == 1:
                            if option == 'self':
                                kwargs['childless'] = True
                        elif setup_case_type == 2:
                            kwargs['main_case_flow_id'] = option
                        chain_list = get_testcase_chain(
                            setup_case_id, setup_case_type, **kwargs)
                        # setup_case_type, setup_case_id, setup_case_flow_id = parse_setup_case_str(setup_case_str)
                        # chain_list = get_testcase_chain(
                        #     setup_case_id, setup_case_type, chain_list=chain_list,
                        #     with_intf_system_name=with_intf_system_name, with_extract=with_extract,
                        #     main_case_flow_id=setup_case_flow_id
                        # )
            else:
                if only_first:
                    chain_list[0]['hasChildren'] = False
                    return chain_list
        return chain_list

    elif case_type == 2:
        tm_obj = ApiTestcaseMainManager.get_testcase_main(id=testcase_id)
        if tm_obj:
            chain_list.insert(
                0, {
                    "preCaseName":
                    '{0}__{1}'.format(tm_obj.testcase_name,
                                      tm_obj.expect_result),
                    "preCaseId":
                    tm_obj.id,
                    "preCaseType":
                    get_desc_by_case_type(case_type),
                    "preIntfName":
                    '',
                    "preSystemName":
                    '',
                    "customFlowId":
                    None,
                    "customFlowName":
                    ''
                })
            if only_first:
                chain_list[0]['hasChildren'] = False
            if main_case_flow_id:
                flow_obj = ApiTestcaseMainCustomFlowManager.get_flow(
                    id=main_case_flow_id)
                if flow_obj:
                    chain_list[0]['customFlowName'] = flow_obj.flow_name
                    chain_list[0]['customFlowId'] = flow_obj.id
        return chain_list
Example #14
0
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
Example #15
0
class ApiTestcase(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.atrm = ApiTestcaseRequestManager()
        self.attrm = ApiTestcaseTagRelationManager()
        self.ttm = TestcaseTagManager()
        self.atmm = ApiTestcaseMainManager()
        self.chain_list = []
        self.chain_no = 0
        if self.username:
            self.data["userName"] = self.username

        # self.USERNAME_NICKNAME_DIC = {row[0]: row[1] for row in UserManager.get_all_username_nickname()}

    @staticmethod
    def username2nickname_fast(username):
        if not username:
            return username

        cache = CacheData()
        if username in cache.USERNAME_NICKNAME_DIC:
            return cache.USERNAME_NICKNAME_DIC[username]
        else:
            return username

    @timer
    def post(self, action):
        if action == 'add':
            return self.add_testcase(action)

        elif action == 'edit':
            return self.edit_testcase(action)

        elif action == 'delete':
            return self.delete_testcase()

        # elif action == 'detailOld':
        #     return self.testcase_detail_old()

        elif action == 'detail':
            return self.testcase_detail()

        elif action == 'queryByIntfId':
            return self.query_by_intf_id()

        elif action == 'changeStatus':
            return self.change_status()

        elif action == 'copy':
            return self.copy_testcase()

        elif action == 'copyBytestcaseData':
            return self.copy_testcase_data()

        elif action == 'queryByCallchain':
            return self.query_callchain()

        elif action == 'setTag':
            return self.set_tag()

        elif action == 'changeParent':
            return self.change_parent()

        elif action == 'detailWithSetup':
            return self.testcase_detail_with_setup()

        elif action == 'queryListBySetupCase':
            return self.query_list_by_setup_case()

        else:
            return make_response({
                "code":
                "100",
                "desc":
                "url错误,不存在的接口动作<{action}>".format(action=action)
            })

    @developer_check
    def add_testcase(self, action):
        try:
            handle_api_testcase(action, **self.data)
        except LoadCaseError:
            return make_response({"code": "200", "desc": "新增用例时出错"})
        return make_response({"code": "000", "desc": "用例新增成功"})

    @developer_with_limit_check
    def edit_testcase(self, action):
        try:
            handle_api_testcase(action, **self.data)
        except LoadCaseError:
            return make_response({"code": "200", "desc": "编辑用例时出错"})
        return make_response({"code": "000", "desc": "用例修改成功"})

    @developer_with_limit_check
    def delete_testcase(self):
        try:
            testcase_id = self.data.pop('testcaseId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})
        if not self.atim.get_testcase(id=testcase_id):
            return make_response({
                "code":
                "200",
                "desc":
                "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id)
            })

        # 检查当前用例是否被其他用例作为前置,如果是无法删除
        setup_case_lists = self.atim.get_id_and_setup_case_list()

        is_setupped = False
        for setup_case_list in setup_case_lists:
            if is_setupped:
                break
            if setup_case_list[1]:
                setup_cases = eval(setup_case_list[1])
                for setup_case_id in setup_cases:
                    if int(setup_case_id.split('-')[1]) == testcase_id:
                        is_setupped = True
                        break

        if is_setupped:
            return make_response({
                "code": "300",
                "desc": "当前用例被其他用例引用为前置,无法直接删除"
            })

        self.atim.delete_testcase(testcase_id)
        r_obj = self.atrm.get_request(api_testcase_id=testcase_id)
        if r_obj:
            self.atrm.delete_request(r_obj.id)

        # 删除tag关系
        relation_objs = ApiTestcaseTagRelationManager.get_relations(
            api_testcase_id=testcase_id)
        for relation_obj in relation_objs:
            ApiTestcaseTagRelationManager.delete_relation(relation_obj.id)

        return make_response({"code": "000", "desc": "测试用例删除成功"})

    @developer_check
    def testcase_detail(self):
        try:
            testcase_id = self.data.pop("testcaseId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        tc_obj = self.atim.get_testcase(id=testcase_id)

        if not tc_obj:
            return make_response({
                "code":
                "101",
                "desc":
                "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id)
            })

        testcase_detail = get_api_testcase_detail(tc_obj)
        return make_response({"code": "000", "data": testcase_detail})

    @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": "入参校验失败"})

        if not self.aiim.get_intf(id=intf_id):
            return make_response({
                "code":
                "201",
                "desc":
                "接口id\"{}\"不存在, 请刷新后重试".format(intf_id)
            })

        # 查询所有标签{类别-场景}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
                })

        case_obj = self.atim.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_desc = get_desc_by_case_status(i.case_status)
            last_run_desc = get_desc_by_last_run(i.last_run)

            tag_relations = self.attrm.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)

            # tag_objs = self.attrm.query_tag_info_by_testcase(i.id)
            #
            # tag_id_list = [t_obj[0] for t_obj in tag_objs] if tag_objs else []
            # tag_name_list = [t_obj[1] for t_obj in tag_objs] if tag_objs else []

            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_desc,
                "creator":
                self.username2nickname_fast(i.creator),
                "last_modifier":
                self.username2nickname_fast(i.last_modifier),
                "last_run":
                last_run_desc,
                # "tags_id": tag_id_list,
                # "tags_name": tag_name_list,
                "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 change_status(self):
        try:
            testcase_id = self.data.pop("id")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        obj = self.atim.get_testcase(id=testcase_id)

        if obj.case_status == 0:
            case_status = 1
        else:
            case_status = 0

        self.atim.update_testcase(id_=testcase_id, case_status=case_status)
        return make_response({"code": "000", "desc": "操作成功"})

    @developer_check
    def query_callchain_old(self):
        """
        查询当前用例的调用链
        :return:
        """
        try:
            testcase_id = self.data.pop("testcaseId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})
        if not self.atim.get_testcase(id=testcase_id):
            return make_response({
                "code":
                "200",
                "desc":
                "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id)
            })
        res = self.traverse_setup_cases(testcase_id)
        res[-1]["chain_no"] += " 当前用例"
        return res

    def traverse_setup_cases(self, testcase_id):
        """
        遍历所有前置testcase_id
        :param testcase_id:
        :return:
        """
        row = self.atim.query_testcase_belong(testcase_id)
        if row[0]:
            setup_cases = eval(row[0])[1]['setup_cases']
        else:
            setup_cases = []
        for setup_case_id in setup_cases:
            if str(testcase_id) != str(setup_case_id):
                self.traverse_setup_cases(setup_case_id)

        extract_v_names = ''
        if row[4]:
            testset = json.loads(row[4])
            for extract_dic in testset['teststeps'][0]['extract']:
                for v_name in extract_dic:
                    extract_v_names += ', $' + v_name

        self.chain_no += 1
        self.chain_list.append({
            "chain_no": str(self.chain_no),
            "testcase_id": testcase_id,
            "testcase_name": row[1],
            "system_name": row[2],
            "intf_name": row[3],
            "extract_v_names": extract_v_names.strip(', ')
        })
        return self.chain_list

    @developer_check
    def query_callchain(self):
        """
        查询当前用例的调用链
        :return:
        """
        try:
            testcase_id = self.data.pop("testcaseId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})
        tc_obj = self.atim.get_testcase(id=testcase_id)
        if not tc_obj:
            return make_response({
                "code":
                "200",
                "desc":
                "用例id\"{}\"不存在, 请刷新后重试".format(testcase_id)
            })
        res_list = get_testcase_chain(testcase_id,
                                      case_type=1,
                                      with_intf_system_name=True,
                                      with_extract=True)
        # res_list.reverse()
        return make_response({"code": "000", "data": res_list})

    @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)

        # objs = self.attrm.get_relations(api_testcase_id=testcase_id)
        # to_delete_id_list = [str(obj.id) for obj in objs]
        #
        # for tag_id in tag_id_list:
        #     obj = self.attrm.get_relation(api_testcase_id=testcase_id, tag_id=tag_id)
        #     if obj and str(obj.id) in to_delete_id_list:
        #         to_delete_id_list.remove(str(obj.id))
        #     else:
        #         self.attrm.insert_relation(api_testcase_id=testcase_id, tag_id=tag_id)
        #
        # for id_ in to_delete_id_list:
        #     self.attrm.delete_relation(id_)

        return make_response({"code": "000", "desc": "设置标签成功"})

    @developer_check
    def copy_testcase(self):
        try:
            testcase_id = self.data.pop('id')
            count = int(self.data.pop('copyNum'))
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        obj = self.atim.get_testcase(id=testcase_id)
        intf_id = obj.api_intf_id
        pre_obj = self.atim.get_last_obj_by_intf(intf_id)
        index = pre_obj.index + 1 if pre_obj else 0
        table_last_obj = self.atim.get_last_obj()
        insert_id = table_last_obj.id + 1 if table_last_obj else 1

        testcase_insert_list = []
        testcase_id_list = []
        for i in range(count):
            case_name = obj.testcase_name + '_copy_{0}_{1}'.format(
                testcase_id, i + 1)
            testcase_insert_list.append({
                'id': insert_id + i,
                'testcase_name': case_name,
                'type': obj.type,
                'include': obj.include,
                'simple_desc': obj.simple_desc,
                'case_status': obj.case_status,
                'api_intf_id': obj.api_intf_id,
                'creator': self.username,
                'expect_result': obj.expect_result,
                'index': index + i,
                'setup_case_list': obj.setup_case_list,
            })
            testcase_id_list.append(insert_id + i)

        self.atim.batch_insert_testcase(testcase_insert_list)

        request_obj = self.atrm.get_request(api_testcase_id=testcase_id)

        request_insert_list = []
        for i in range(count):
            request_insert_list.append({
                'api_testcase_id': testcase_id_list[i],
                'request': request_obj.request
            })
        self.atrm.batch_insert_request(request_insert_list)

        # 复制tag
        tag_relation_objs = ApiTestcaseTagRelationManager.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(count):
            for tag_id in tag_id_list:
                tag_relation_insert_list.append({
                    'api_testcase_id':
                    testcase_id_list[i],
                    'tag_id':
                    tag_id
                })
        self.attrm.batch_insert_relation(tag_relation_insert_list)

        return make_response({
            "code":
            "000",
            "desc":
            "用例{0}复制成功, 数量{1}".format(testcase_id, count)
        })

    @developer_check
    def copy_testcase_data(self):
        """
        复制用例数据结构
        :return:
        """
        try:
            to_testcase_id_list = self.data.pop("copyIdList")
            from_testcase_id = self.data.pop("copiedId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        from_obj = self.atim.get_testcase(id=from_testcase_id)
        from_request_obj = self.atrm.get_request(
            api_testcase_id=from_testcase_id)

        # 检查是否允许复制
        for testcase_id in to_testcase_id_list:
            to_obj = self.atim.get_testcase(id=testcase_id)
            if to_obj.api_intf_id != from_obj.api_intf_id:
                return make_response({
                    "code":
                    "201",
                    "desc":
                    "用例{}与被复制用例不属于同一接口,无法复制".format(testcase_id)
                })

        tag_relation_objs = ApiTestcaseTagRelationManager.get_relations(
            api_testcase_id=from_testcase_id)
        from_tag_id_list = [str(obj.tag_id) for obj in tag_relation_objs]

        for testcase_id in to_testcase_id_list:
            self.atim.update_testcase(testcase_id,
                                      include=from_obj.include,
                                      last_modifier=self.username,
                                      setup_case_list=from_obj.setup_case_list)
            self.atrm.update_request_by_testcase_id(
                testcase_id, request=from_request_obj.request)
            # 复制标签
            tag_relation_insert_list = []
            for tag_id in from_tag_id_list:
                tag_relation_insert_list.append({
                    'testcase_id': testcase_id,
                    'tag_id': tag_id
                })
            self.attrm.batch_insert_relation(tag_relation_insert_list)
        return make_response({
            "code": "000",
            "desc": "复制{}数据成功".format(from_testcase_id)
        })

    @developer_check
    def change_parent(self):
        try:
            id_ = self.data.pop('testcaseId')
            parent_id = self.data.pop('newParentId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        intf_obj = self.aiim.get_intf(id=parent_id)
        if not intf_obj:
            return make_response({"code": "200", "desc": "不存在的接口id, 请刷新后重试"})

        # 更新原用例集其他用例的index
        self.atim.index_update_while_remove_testcase(id_=id_)
        # 获取新用例集的index
        pre_obj = self.atim.get_last_obj_by_intf(parent_id)
        index = pre_obj.index + 1 if pre_obj else 0

        self.atim.update_testcase(id_=id_, api_intf_id=parent_id, index=index)
        return make_response({"code": "000", "desc": "ok"})

    @developer_check
    def testcase_detail_with_setup(self):
        """全链路引入接口用例时使用"""
        try:
            testcase_id = self.data.pop("testcaseId")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        detail_list = []

        chain_objs = get_testcase_chain_objs(testcase_id, case_type=1)
        for obj_info in chain_objs:
            if obj_info["case_type"] == 1:
                tc_obj = obj_info["obj"]
                detail_dic = get_api_testcase_detail(tc_obj=tc_obj,
                                                     without_setup_cases=True)
                detail_dic.pop("include")
                detail_dic.pop("base")
                step = detail_dic.pop("steps")[0]
                intf_obj = self.aiim.get_intf(id=tc_obj.api_intf_id)
                step.update({
                    "base": {
                        "intfId":
                        tc_obj.api_intf_id,
                        "intfName":
                        intf_obj.intf_name,
                        "intfNameInChinese":
                        intf_obj.intf_desc,
                        "requestType":
                        intf_obj.intf_type,
                        "subName":
                        tc_obj.testcase_name,
                        "subDesc":
                        tc_obj.simple_desc if tc_obj.simple_desc else '',
                        "subExpectResult":
                        tc_obj.expect_result if tc_obj.expect_result else ''
                    }
                })
                detail_dic.update(step)
                detail_list.append(detail_dic)
            elif obj_info["case_type"] == 2:
                tm_obj = obj_info["obj"]
                detail_dic = get_api_testcase_main_detail(tm_obj=tm_obj)
                detail_dic.pop("base")
                steps_list = detail_dic.pop("steps")
                for step in steps_list:
                    step["base"].pop("subId", None)
                    detail_list.append(step)

        return make_response({"code": "000", "dataList": detail_list})

    @login_check
    def query_list_by_setup_case(self):
        try:
            testcase_id = self.data.pop("testcaseId", 0)
            testcase_main_id = self.data.pop("testcaseMainId", 0)
            if testcase_id:
                testcase_id = int(testcase_id)
            elif testcase_main_id:
                testcase_main_id = int(testcase_main_id)
            else:
                raise KeyError
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验错误"})

        if testcase_id:
            setupped_case_id_list = get_setupped_case_id_list(testcase_id, 1)
        else:
            setupped_case_id_list = get_setupped_case_id_list(
                testcase_main_id, 2)

        # 获取{用例id:tag_map}
        cache = CacheData()
        tag_base_map = cache.get_tag_base_map()
        tag_relations = self.attrm.get_relations_in_case_ids(
            setupped_case_id_list)
        case_id_tag_map_tmp_dic = {}
        for case_id in setupped_case_id_list:
            tag_map = {base_category: [] for base_category in tag_base_map}
            for relation in tag_relations:
                if relation.api_testcase_id == case_id:
                    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)
            case_id_tag_map_tmp_dic[case_id] = tag_map

        data_list = []
        res = ApiTestcaseInfoManager.get_intf_and_case_info_in_case_ids(
            setupped_case_id_list)
        for row in res:
            data_list.append({
                'intfId':
                row[0],
                'intfName':
                row[1],
                'intfNameInChinese':
                row[2],
                'intfType':
                row[3],
                'id':
                row[4],
                'testcaseName':
                row[5],
                'testcaseCreator':
                self.username2nickname_fast(row[6]),
                'testcaseLasModifier':
                self.username2nickname_fast(row[7]),
                'status':
                get_desc_by_case_status(row[8]),
                'testcaseLastRun':
                get_desc_by_last_run(row[9]),
                'testcaseCreateTime':
                format(row[10]) if row[10] else '',
                'testcaseUpdateTime':
                format(row[11]) if row[11] else '',
                'testcaseLastRunTime':
                format(row[12]) if row[12] else '',
                'tags':
                case_id_tag_map_tmp_dic[row[4]]
            })
        return make_response({'code': '000', 'dataList': data_list})
Example #16
0
    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
Example #17
0
class ApiProject(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.apim = ApiProjectInfoManager()
        self.apsrm = ApiProjectSystemRelationManager()
        self.apirm = ApiProjectIntfRelationManager()

    @timer
    def post(self, action):
        if action == 'add':
            return self.add_project()

        elif action == 'edit':
            return self.edit_project()

        elif action == 'delete':
            return self.delete_project()

        elif action == 'list':
            return self.project_list_by_company_id()

        elif action == 'includeSystem':
            return self.include_system()

        elif action == 'includeIntf':
            return self.include_intf()

        elif action == 'excludeSystem':
            return self.exclude_system()

        elif action == 'excludeIntf':
            return self.exclude_intf()

        elif action == 'getIncludeIntfList':
            return self.get_include_intf_list()

        elif action == 'subtree':
            return self.subtree()

        else:
            return make_response({
                "code":
                "100",
                "desc":
                "url错误,不存在的接口动作<{action}>".format(action=action)
            })

    @developer_check
    def add_project(self):
        try:
            company_id = self.data.pop('companyId')
            project_name = self.data.pop('projectName')
            simple_desc = self.data.pop('simpleDesc', None)
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        project_name = str(project_name).strip()

        if self.apim.get_project(project_name=project_name,
                                 api_company_id=company_id):
            return make_response({
                "code":
                "201",
                "desc":
                "公司下存在相同项目名称\"{}\", 无法新增".format(project_name)
            })

        self.apim.insert_project(project_name=project_name,
                                 simple_desc=simple_desc,
                                 api_company_id=company_id,
                                 creator=self.username)
        return make_response({
            "code": "000",
            "desc": "项目\"{}\"增加成功".format(project_name)
        })

    @developer_check
    def edit_project(self):
        try:
            project_id = self.data.pop('projectId')
            project_name = self.data.pop('projectName')
            simple_desc = self.data.pop('simpleDesc', None)
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        project_obj = self.apim.get_project(id=project_id)
        if not project_obj:
            return make_response({
                "code":
                "202",
                "desc":
                "项目id\"{}\"不存在, 请刷新后重试".format(project_id)
            })

        exist_project_obj = self.apim.get_project(
            project_name=project_name,
            api_company_id=project_obj.api_company_id)
        if exist_project_obj and exist_project_obj.id != int(project_id):
            return make_response({
                "code":
                "201",
                "desc":
                "公司下存在相同工项目\"{}\", 无法修改".format(project_name)
            })

        self.apim.update_project(project_id,
                                 project_name=project_name,
                                 simple_desc=simple_desc,
                                 last_modifier=self.username)
        return make_response({
            "code": "000",
            "desc": "公司\"{}\"修改成功".format(project_name)
        })

    @developer_check
    def delete_project(self):
        try:
            project_id = self.data.pop('projectId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        if not self.apim.get_project(id=project_id):
            return make_response({
                "code":
                "202",
                "desc":
                "项目id\"{}\"不存在, 请刷新后重试".format(project_id)
            })

        relation_objs = self.apirm.get_relations(api_project_id=project_id)
        if relation_objs:
            return make_response({
                "code":
                "300",
                "desc":
                "项目下已引入{}个接口,无法直接删除".format(len(relation_objs))
            })

        self.apim.delete_project(project_id)
        return make_response({"code": "000", "desc": "项目删除成功"})

    @login_check
    def project_list_by_company_id(self):
        try:
            company_id = int(self.data.pop('companyId', 0))
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})
        if company_id:
            p_objs = self.apim.get_projects_reverse(api_company_id=company_id)
        else:
            p_objs = self.apim.get_projects()

        # 根据项目分组查询项目中的用例总数
        count_res = self.apim.count_api_project_subtree_group_by_project_id(
            company_id)

        res_list = []
        for p_obj in p_objs:
            testcase_num = [row[1] for row in count_res
                            if row[0] == p_obj.id][0]
            if testcase_num:
                has_children = True
            else:
                r_obj = ApiProjectSystemRelationManager.get_relation(
                    api_project_id=p_obj.id)
                has_children = True if r_obj else False
            res_list.append({
                'projectId': p_obj.id,
                'projectName': p_obj.project_name,
                'simpleDesc': p_obj.simple_desc,
                'creator': p_obj.creator,
                'last_modifier': p_obj.last_modifier,
                'hasChildren': has_children,
                'testcaseNum': testcase_num,
            })
        return make_response({"code": "000", "projectList": res_list})

    @developer_check
    def include_system(self):
        try:
            project_id = self.data.pop('projectId')
            system_id_list = self.data.pop('systemIdList')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        if not system_id_list:
            return make_response({"code": "200", "desc": "未选择工程,无法引入"})

        if len(system_id_list) != len(set(system_id_list)):
            return make_response({
                "code": "101",
                "desc": "入参校验失败, systemIdList包含重复元素"
            })

        exist_relation_objs = self.apsrm.get_relations(
            api_project_id=project_id)
        for exist_relation_obj in exist_relation_objs:
            if exist_relation_obj.api_system_id in system_id_list:
                system_id_list.remove(exist_relation_obj.api_system_id)

        insert_list = []
        for system_id in system_id_list:
            insert_list.append({
                'api_project_id': project_id,
                'api_system_id': system_id
            })
        self.apsrm.batch_insert_relation(insert_list)
        return make_response({
            "code": "000",
            "desc": "{}个工程引入成功".format(len(system_id_list))
        })

    @developer_check
    def include_intf(self):
        try:
            project_id = self.data.pop('projectId')
            intf_id_list = self.data.pop('intfIdList')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        if not intf_id_list:
            return make_response({"code": "200", "desc": "未选择接口,无法引入"})

        if len(intf_id_list) != len(set(intf_id_list)):
            return make_response({
                "code": "101",
                "desc": "入参校验失败, intf_id_list包含重复元素"
            })

        exist_relation_objs = self.apirm.get_relations(
            api_project_id=project_id)
        for exist_relation_obj in exist_relation_objs:
            if exist_relation_obj.api_intf_id in intf_id_list:
                intf_id_list.remove(exist_relation_obj.api_intf_id)

        insert_list = []
        for intf_id in intf_id_list:
            insert_list.append({
                'api_project_id': project_id,
                'api_intf_id': intf_id
            })
        self.apirm.batch_insert_relation(insert_list)
        return make_response({
            "code": "000",
            "desc": "{}个接口引入成功".format(len(intf_id_list))
        })

    @developer_check
    def exclude_system(self):
        try:
            project_id = self.data.pop('projectId')
            system_id = self.data.pop('systemId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        obj = self.apsrm.get_relation(api_project_id=project_id,
                                      api_system_id=system_id)
        if not obj:
            return make_response({"code": "200", "desc": "此工程未被引入,请刷新后重试"})

        p_i_relation_objs = self.apirm.get_relations(api_project_id=project_id)
        intf_id_list = [
            p_i_relation_obj.api_intf_id
            for p_i_relation_obj in p_i_relation_objs
        ]

        intf_objs = self.aiim.get_intfs_in_id_list(intf_id_list)
        for intf_obj in intf_objs:
            if intf_obj.api_system_id == int(system_id):
                return make_response({
                    "code": "300",
                    "desc": "此工程下已引入接口,无法直接去除"
                })

        self.apsrm.delete_relation(id_=obj.id)
        return make_response({"code": "000", "desc": "工程去除成功"})

    @developer_check
    def exclude_intf(self):
        try:
            project_id = self.data.pop('projectId')
            intf_id = self.data.pop('intfId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        obj = self.apirm.get_relation(api_project_id=project_id,
                                      api_intf_id=intf_id)
        if not obj:
            return make_response({"code": "200", "desc": "此接口未被引入,请刷新后重试"})

        self.apirm.delete_relation(id_=obj.id)
        return make_response({"code": "000", "desc": "接口去除成功"})

    @developer_check
    def get_include_intf_list(self):
        """
            Input:
            {"projectId":"7"}
            Return:
            {
                "code": "000",
                "includeIntfList": [
                    441,
                    457,
                    653,
                    658,
                    679,
                    737,
                    680,
                    765
                ]
            }
        """
        try:
            project_id = self.data.pop('projectId')
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        objs = self.apirm.get_relations(api_project_id=project_id)
        intf_id_list = [obj.api_intf_id for obj in objs]
        return make_response({"code": "000", "includeIntfList": intf_id_list})

    def subtree(self):
        try:
            project_id = int(self.data.pop('projectId'))
        except (KeyError, ValueError):
            return make_response({"code": "100", "desc": "入参校验失败"})

        subtree = []
        index_id = 0

        result_list = self.apim.query_api_project_subtree(project_id)
        patch_result_list = self.apim.query_api_project_subtree_patch(
            project_id)

        result_dic = db_result_to_map(result_list, patch_result_list)
        for p_k, p_dic in result_dic.items():
            p_name = p_dic.pop('name')
            index_id += 1
            p_tree = {
                'id': index_id,
                'label': p_name,
                'projectId': p_k,
                'children': []
            }
            for s_k, s_dic in p_dic.items():
                s_name = s_dic.pop('name')
                index_id += 1
                s_tree = {
                    'id': index_id,
                    'label': s_name,
                    'systemId': s_k,
                    'children': []
                }
                for i_k, i_dic in s_dic.items():
                    i_name = i_dic.pop('name')
                    index_id += 1
                    i_tree = {
                        'id': index_id,
                        'label': i_name,
                        'intfId': i_k,
                        'children': []
                    }
                    for t_k, t_dic in i_dic.items():
                        index_id += 1
                        t_tree = {
                            'id': index_id,
                            'label': '{0}_{1}'.format(t_k, t_dic['name']),
                            'testcaseId': t_k,
                        }
                        i_tree['children'].append(t_tree)
                    s_tree['children'].append(i_tree)
                p_tree['children'].append(s_tree)
            subtree.append(p_tree)

        return make_response({"code": "000", "data": subtree[0]['children']})
Example #18
0
 def __init__(self):
     self.data = get_request_json()
     self.gdvm = GitDiffVersionManager()
     self.aiif = ApiIntfInfoManager()
     self.atim = ApiTaskInfoManager()
     self.atcm = ApiTestcaseInfoManager()
Example #19
0
class CallBack(Resource):
    def __init__(self):
        self.data = get_request_json()
        self.gdvm = GitDiffVersionManager()
        self.aiif = ApiIntfInfoManager()
        self.atim = ApiTaskInfoManager()
        self.atcm = ApiTestcaseInfoManager()

    @timer
    def post(self, action):
        if action == 'getChangesBySeqNo':
            return self.get_changes_by_seq_no()

        else:
            return make_response({"code": "100", "desc": "url错误,不存在的接口动作<{action}>".format(action=action)})

    def get_changes_by_seq_no(self):
        """
        根据流水号获取变更内容
        :return:
        """
        try:
            seq_no = self.data.pop('seq_no')
            application = self.data.pop('application')
        except KeyError:
            return make_response({"code": "100", "mes": CODE_DESC_MAP["100"]})

        git_diffs = self.gdvm.get_git_diff_versions(seq_no=seq_no)
        if not git_diffs:
            return make_response({"code": "100", "desc": "seq_no不存在"})
        elif len(git_diffs) > 1:
            return make_response({"code": "100", "desc": "seq_no不唯一"})
        else:
            changes = application['changes']
            api_task_id = git_diffs[0].api_task_id
            self.gdvm.update_git_diff_version_by_seq_no(seq_no_=seq_no, detail=json_dumps(changes))
            self.update_task_info(api_task_id, changes, seq_no)

            return make_response({"code": "0000", "msg": "成功"})

    def update_task_info(self, api_task_id, changes, seq_no):
        """
        解析回调接口返回的变更内容
        :param api_task_id:
        :param changes:
        :param seq_no:
        :return:
        """
        affect_http = set()
        affect_dubbo = set()
        affect_mq = set()
        affect_elasticJob = set()
        for affects in [change['affects'] for change in changes]:
            for methods in [affect['methods'] for affect in affects]:
                for method in methods:
                    if method.get('http'):
                        method_http = method.get('http').get('url')
                        affect_http.add(method_http)
                    if method.get('dubbo'):
                        role = method.get('dubbo').get('role')
                        method_dubbo = method.get('dubbo').get('service').get('interface') + '.' + method.get('method') \
                            if role == 'service' else method.get('dubbo').get('reference').get(
                            'interface') + '.' + method.get('method')
                        affect_dubbo.add(method_dubbo)
                    if method.get('mq'):
                        role = method.get('mq').get('role')
                        method_mq = method.get('mq').get('producer').get('topic') \
                            if role == 'producer' else method.get('mq').get('consumer').get(
                            'topic') + '.' + method.get('mq').get('consumer').get(
                            'tag')
                        affect_mq.add(method_mq)
                    if method.get('elasticJob'):
                        method_elasticJob = method.get('elasticJob').get('class') + '.' + method.get('method')
                        affect_elasticJob.add(method_elasticJob)
        affects = {
            "http": list(affect_http), "dubbo": list(affect_dubbo), "mq": list(affect_mq),
            "elasticJob": list(affect_elasticJob)}

        # 查询atp平台是否存在对应接口,如有则将接口id填入effect_intf_id_list,如无则将接口数据填入uncovered_info
        task_info = self.atim.get_task(id=api_task_id)
        effect_intf_id_list = set(json_loads(task_info.effect_intf_id_list)) if task_info.effect_intf_id_list else set()
        uncovered_info = json_loads(task_info.uncovered_info) if task_info.uncovered_info else {}
        uncovered_info_http = set(uncovered_info.get('http')) if uncovered_info.get('http') else set()
        uncovered_info_dubbo = set(uncovered_info.get('dubbo')) if uncovered_info.get('dubbo') else set()
        uncovered_info_mq = set(uncovered_info.get('mq')) if uncovered_info.get('mq') else set()
        uncovered_info_elasticJob = set(uncovered_info.get('elasticJob')) if uncovered_info.get('elasticJob') else set()
        for intf_name in affects['http']:
            if intf_name:
                intf_info = self.aiif.get_intf(intf_name=intf_name)
                if intf_info:
                    testcase_info = self.atcm.get_testcase(api_intf_id=intf_info.id)
                    if testcase_info:
                        affects['http'] = affects['http'].remove(intf_name)
                        effect_intf_id_list.add(intf_info.id)
                    else:
                        uncovered_info_http.add(intf_name)
                else:
                    uncovered_info_http.add(intf_name)

        for intf_name in affects['dubbo']:
            if intf_name:
                intf_info = self.aiif.get_intf(intf_name=intf_name)
                if intf_info:
                    testcase_info = self.atcm.get_testcase(api_intf_id=intf_info.id)
                    if testcase_info:
                        affects['dubbo'] = affects['dubbo'].remove(intf_name)
                        effect_intf_id_list.add(intf_info.id)
                    else:
                        uncovered_info_dubbo.add(intf_name)
                else:
                    uncovered_info_dubbo.add(intf_name)

        for intf_name in affects['mq']:
            if intf_name:
                intf_info = self.aiif.get_intf(intf_name=intf_name)
                if intf_info:
                    testcase_info = self.atcm.get_testcase(api_intf_id=intf_info.id)
                    if testcase_info:
                        affects['mq'] = affects['mq'].remove(intf_name)
                        effect_intf_id_list.add(intf_info.id)
                    else:
                        uncovered_info_mq.add(intf_name)
                else:
                    uncovered_info_mq.add(intf_name)

        for intf_name in affects['elasticJob']:
            if intf_name:
                intf_info = self.aiif.get_intf(intf_name=intf_name)
                if intf_info:
                    testcase_info = self.atcm.get_testcase(api_intf_id=intf_info.id)
                    if testcase_info:
                        affects['elasticJob'] = affects['elasticJob'].remove(intf_name)
                        effect_intf_id_list.add(intf_info.id)
                    else:
                        uncovered_info_elasticJob.add(intf_name)
                else:
                    uncovered_info_elasticJob.add(intf_name)

        effect_intf_id_list = list(effect_intf_id_list)
        uncovered_info['http'] = list(uncovered_info_http)
        uncovered_info['dubbo'] = list(uncovered_info_dubbo)
        uncovered_info['mq'] = list(uncovered_info_mq)
        uncovered_info['elasticJob'] = list(uncovered_info_elasticJob)

        # 判断当前是否是同一个api_task下的最后一个回调,如果是则更新api_task_info表里面对应记录的task_status为1(启动)
        git_diffs = self.gdvm.get_git_diff_versions_special(seq_no, api_task_id)
        if not git_diffs:
            self.atim.update_task(api_task_id, effect_intf_id_list=json_dumps(effect_intf_id_list),
                                  uncovered_info=json_dumps(uncovered_info),
                                  task_status=1)
        else:
            flag = 0
            for row in git_diffs:
                if not row.detail:
                    flag = 1
                    break
            if flag == 1:
                self.atim.update_task(api_task_id, effect_intf_id_list=json_dumps(effect_intf_id_list),
                                      uncovered_info=json_dumps(uncovered_info))
            if flag == 0:
                self.atim.update_task(api_task_id, effect_intf_id_list=json_dumps(effect_intf_id_list),
                                      uncovered_info=json_dumps(uncovered_info),
                                      task_status=1)
Example #20
0
def init_table_api_intf_default_request():
    """初始化api_intf_default_request表"""
    intf_objs = aiim.get_intfs()
    # tc_objs = atim.get_testcases()
    process_len = len(intf_objs)
    process_id = 0
    for intf_obj in intf_objs:
        print('intf_id: {}'.format(intf_obj.id))
        t1 = time.time()

        process_id += 1
        print('{:.1f}%'.format(process_id*100.0/process_len))

        if aidrm.get_request(api_intf_id=intf_obj.id):
            continue

        tc_objs = atim.get_testcases(api_intf_id=intf_obj.id)

        final_body = None
        for tc_obj in tc_objs:
            tc_request_obj = atrm.get_request(api_testcase_id=tc_obj.id)
            if not tc_request_obj or not tc_request_obj.request:
                continue

            request_dic = json_loads(tc_request_obj.request)
            try:
                if tc_obj.type == 1:
                    body = request_dic['teststeps'][0]['request']['json']
                    if not final_body:
                        final_body = body
                    else:
                        final_body = merge_request_body(final_body, body)
                elif tc_obj.type == 2:
                    body = request_dic['teststeps'][0]['request']['json']['args']
                    if not final_body:
                        final_body = body
                    else:
                        final_body = merge_request_body(final_body, body, is_list=True)
                elif tc_obj.type == 3:
                    body_str = request_dic['teststeps'][0]['request']['json']['msg']
                    body = json_loads(body_str)
                    if not final_body:
                        final_body = body
                    else:
                        final_body = merge_request_body(final_body, body)
                else:
                    continue
            except KeyError:
                print('Error!!')
                continue

        t3 = time.time()
        d_time = t3 - t1
        print("==== Finish t3, run {:.3}s ====\n".format(d_time))

        if final_body is not None:
            body = remove_var_mark(final_body)
            p = ParseBodyToDetail(body)
            p.parse_main()
            detail_str = json_dumps(p.detail)
            body_str = json_dumps(body)

            aidrm.insert_request(api_intf_id=intf_obj.id, request=body_str, request_detail=detail_str)