Ejemplo n.º 1
0
def init_column_main_list_for_table_api_testcase_sub():
    """初始化api_testcase_sub.main_list, 可重复执行"""
    main_objs = ApiTestcaseMainManager.get_testcase_mains()
    len_main_objs = len(main_objs)
    print('总计:{}'.format(len_main_objs))
    index = 0
    for main_obj in main_objs:
        index += 1
        process = index * 100.0 / len_main_objs
        print('进度:{:.2f}%'.format(process))
        sub_list = json_loads(main_obj.sub_list)
        for sub_id in sub_list:
            sub_obj = ApiTestcaseSubManager.get_testcase_sub(id=sub_id)
            if not sub_obj:
                print('sub_obj not found, main_obj.id:{0}, sub_id:{1}'.format(main_obj.id, sub_id))
                break
            old_main_list_str = sub_obj.main_list
            if old_main_list_str:
                old_main_list = json_loads(old_main_list_str)
                if old_main_list:
                    if main_obj.id not in old_main_list:
                        old_main_list.append(main_obj.id)
                        main_list_str = json_dumps(old_main_list)
                    else:
                        continue
                else:
                    main_list_str = '[{}]'.format(main_obj.id)
            else:
                main_list_str = '[{}]'.format(main_obj.id)
            print(main_list_str)
            ApiTestcaseSubManager.update_testcase_sub(sub_id, main_list=main_list_str)
Ejemplo n.º 2
0
    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})
Ejemplo n.º 3
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
Ejemplo n.º 4
0
def init_column_for_table_api_testcase_info():
    """初始化api_testcase_info表的setup_case_list列数据"""
    to_update_rows = []
    objs = atim.get_testcases()
    for obj in objs:
        if obj.setup_case_list:
            continue
        include_str = obj.include
        if include_str:
            include_list = json_loads(include_str)
            for include in include_list:
                if 'setup_cases' in include and include['setup_cases'] and isinstance(include['setup_cases'], list):
                    setup_case_list = []
                    for case_id_str in include['setup_cases']:
                        setup_case_list.append('1-' + case_id_str)
                    to_update_rows.append(
                        {
                            'id': obj.id,
                            'setup_case_list': json_dumps(setup_case_list)
                        }
                    )
    print(json_dumps(to_update_rows))
    print(len(to_update_rows))
    x_len = len(to_update_rows)
    index = 0
    for row in to_update_rows:
        atim.update_testcase(id_=row['id'], setup_case_list=row['setup_case_list'])
        index += 1
        print(index*100.0/x_len)
Ejemplo n.º 5
0
    def delete_variable(self):
        """根据变量名称(唯一)删除变量
            input:
            {
              "variable_name":"test",
              "systemId":"1"
            }
        """
        try:
            variable_id = int(self.data.pop("variableId"))
            # id_=data.pop("id")
        except KeyError:
            return make_response({"code": "100", "desc": "入参校验失败"})

        pv_obj = self.apv.get_variable(id=variable_id)
        if not pv_obj:
            return make_response({
                "code": "000",
                "desc": "变量id{}不存在,请刷新后重试".format(variable_id)
            })

        include_list = self.atim.query_all_testcases_include()
        for row in include_list:
            if not row[0]:
                continue
            include = json_loads(row[0])
            if 'public_variables' in include[0]:
                if variable_id in include[0]['public_variables']:
                    return make_response({
                        "code": "200",
                        "desc": "存在用例引用公共变量,无法直接删除"
                    })

        self.apv.delete_variable(pv_obj.id)
        return make_response({"code": "000", "desc": "变量删除成功"})
Ejemplo n.º 6
0
    def _init_testset(self, tc_obj, intf_obj, tm_obj=None):
        """
        初始化testset
        """

        testset = self._get_testset_from_obj(tc_obj, intf_obj, tm_obj=tm_obj)
        testset = self._add_public_env_to_config(testset)
        testset = self._param_check_update(testset, tc_obj)

        # 主用例
        if tm_obj:
            main_case_id = tm_obj.id
            main_name = tm_obj.testcase_name
            testset['config']['is_main'] = True
            # testset增加主用例用例后置信息
            if tm_obj.main_teardown_hooks:
                main_teardown_hooks = json_loads(tm_obj.main_teardown_hooks)
                if main_teardown_hooks:
                    parsed_teardown_hooks = []
                    for teardown_hook_str in main_teardown_hooks:
                        parsed_teardown_hook_str = setup_or_teardown_string_add_param(teardown_hook_str, is_setup=False)
                        parsed_teardown_hooks.append(parsed_teardown_hook_str)
                    testset['config']['teardown_hooks'] = parsed_teardown_hooks
        # 接口用例
        else:
            main_case_id = tc_obj.id
            main_name = tc_obj.testcase_name
            testset['config']['is_main'] = False

        testset['name'] = main_name
        testset['config']['case_id'] = main_case_id
        # 给testset增加name信息
        testset['config']['name'] = testset['name']

        return testset
Ejemplo n.º 7
0
def setup_qa_create_accounting_overdue(loan_id, overdue_days, env_name):
    """ 其他-根据偏移天数更新贷款数据 : 贷款编号, 偏移天数
    :param loan_id: 贷款编号:贷款编号loan_id
    :param overdue_days: 偏移天数:正整数-期望逾期的天数;负数-期望往前偏移的天数
    :param env_name: 环境名称
    :return:
    """
    if not isinstance(overdue_days, int):
        raise Exception('偏移天数输入有误,只支持数字')
    if overdue_days < 0:
        dt = datetime.datetime.now() + relativedelta(days=overdue_days)
    else:
        dt = datetime.datetime.now() + relativedelta(days=-overdue_days) + relativedelta(months=-1)
    loan_timestamp = int(time.mktime(dt.timetuple()))

    data = {"env": env_name, "loanDate": loan_timestamp, "loanId": loan_id}
    url = "http://****/atp/qa/createAccountingOverdue"
    header_info = {"Content-Type": "application/json"}
    hc = HttpClient()
    try:
        r = hc.http_post(url, header_info, data)
        r_dic = json_loads(r.text)
    except Exception as err:
        raise Exception('出现未知错误:{0}'.format(repr(err)))
    if r_dic['code'] == '000':
        return True
    else:
        raise Exception(r_dic['desc'])
Ejemplo n.º 8
0
    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": "测试用例删除成功"})
Ejemplo n.º 9
0
def migrate_base(step):
    """
    迁移基线用例数据
    前置条件:先把 base_testcase_info, base_module_info表数据分别导出到相应备份表,并清空 base_module_info表
    注意按顺序执行,中途报错不可继续
    """
    if step == 1:
        # migrate testcase
        bt_objs = btm.get_all_testcase()
        process_len = len(bt_objs)
        process_id = 0
        for bt_obj in bt_objs:
            process_id += 1
            print('{:.1f}%'.format(process_id * 100.0 / process_len))

            id_ = bt_obj.id
            print(id_)
            try:
                detail_dic = json_loads(bt_obj.detail)
            except Exception:
                detail_dic = {}

            if isinstance(detail_dic, list):
                continue

            new_detail_dic = _change_base_detail(detail_dic)
            btm.update_base_testcase(id_, detail=json_dumps(new_detail_dic))

    if step == 2:
        # migrate module
        bm_bak_objs = bmm_bak.get_modules()
        process_len = len(bm_bak_objs)
        process_id = 0
        for bm_bak_obj in bm_bak_objs:
            process_id += 1
            print('{:.1f}%'.format(process_id * 100.0 / process_len))

            if bm_bak_obj.system_id:
                bmm.insert_base_module(id=bm_bak_obj.id, module_name=bm_bak_obj.module_name, system_id=bm_bak_obj.system_id)
                second_bm_objs = bmm_bak.get_modules(parent_module_id=bm_bak_obj.id)
                if not second_bm_objs:
                    new_module_name = bm_bak_obj.module_name
                    bt_objs = btm.get_all_testcase(module_id=bm_bak_obj.id)
                    if bt_objs:
                        bmm.insert_base_module(module_name=new_module_name, parent_module_id=bm_bak_obj.id)
                        second_bm_obj = bmm.get_module(module_name=new_module_name, parent_module_id=bm_bak_obj.id)
                        new_module_id = second_bm_obj.id

                        for bt_obj in bt_objs:
                            btm.update_base_testcase(bt_obj.id, module_id=new_module_id)

            else:
                sub_bm_bak_objs = bmm_bak.get_modules(parent_module_id=bm_bak_obj.id)
                if sub_bm_bak_objs:
                    continue
                else:
                    new_module_name, new_parent_id = _change_name_and_parent_id(bm_bak_obj.id)
                    bmm.insert_base_module(id=bm_bak_obj.id, module_name=new_module_name, parent_module_id=new_parent_id)
Ejemplo n.º 10
0
def field_check_not_in_list(check_value, expect_value):
    """ 接口响应-字段为list类型且不包含期望值 : 校验, 预期结果
    :desc: 说明: 验证返回报文中的某个字段的值的类型是list,并且不包含期望值
    :param check_value:待校验内容: 指定返回报文中的某个字段,支持多层级,例如 content.demoList
    :param expect_value: 期望值: 期望不被包含的值
    :return:
    """
    # 返回true和false,关联测试报告success和fail
    try:
        if isinstance(check_value, list):
            if expect_value not in check_value:
                # json like
                if (expect_value.startswith('[') and expect_value.endswith(']')) or (expect_value.startswith('{') and expect_value.endswith('}')):
                    try:
                        expect_value = json_loads(expect_value)
                    except json.decoder.JSONDecodeError:
                        return True
                    if expect_value not in check_value:
                        return True
                    else:
                        return False, '待校验的字段值是{0}, 包含了期望值{1}'.format(check_value, expect_value)
                # num like
                elif expect_value.isdigit():
                    try:
                        expect_value = int(expect_value)
                    except ValueError:
                        return True
                    if expect_value not in check_value:
                        return True
                    else:
                        return False, '待校验的字段值是{0}, 包含了期望值{1}'.format(check_value, expect_value)
                # True/False like
                elif 'rue' in expect_value or 'alse' in expect_value:
                    if expect_value == 'true' or expect_value == 'True':
                        expect_value = True
                        if expect_value not in check_value:
                            return True
                        else:
                            return False, '待校验的字段值是{0}, 包含了期望值{1}'.format(check_value, expect_value)
                    elif expect_value == 'false' or expect_value == 'False':
                        expect_value = False
                        if expect_value not in check_value:
                            return True
                        else:
                            return False, '待校验的字段值是{0}, 包含了期望值{1}'.format(check_value, expect_value)
                    else:
                        return True
                else:
                    return True
            else:
                return False, '待校验的字段值是{0}, 包含了期望值{1}'.format(check_value, expect_value)
        else:
            return False, '待校验的字段值是{0}, 类型是{1}'.format(check_value, type(check_value))
    except Exception as err:
        return False, err.args[0]
Ejemplo n.º 11
0
def httprunner_request_update():
    """已废弃,请勿执行"""
    from atp.api.mysql_manager import TestcaseInfoManager
    tc_objs = TestcaseInfoManager.get_all_testcases()
    count = 0
    for tc_obj in tc_objs:
        if tc_obj:
            if tc_obj.request:
                request = json_loads(tc_obj.request)
                count += 1
                new_request = handle_step_dic(request)
                print(count)
                print(json_dumps(new_request))
Ejemplo n.º 12
0
    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})
Ejemplo n.º 13
0
    def get_testcase_id_list_filter_by_tag(self, intf_id=None, product_line_id=None):
        """ 根据任务配置的测试标签,过滤接口用例和全链路用例"""
        try:
            related_tag_id_list = json_loads(self.task_obj.related_tag_id_list)
        except Exception:
            related_tag_id_list = None

        if not related_tag_id_list:
            return []

        if intf_id:
            res = ApiTestcaseInfoManager.filter_task_testcase_ids(intf_id, related_tag_id_list)
            return [row[0] for row in res]
        elif product_line_id:
            res = ApiTestcaseMainManager.filter_task_testcase_ids(product_line_id, related_tag_id_list)
            return [row[0] for row in res]
Ejemplo n.º 14
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
Ejemplo n.º 15
0
 def _param_check_update(testset, tc_obj):
     """
     识别是否"入参字段校验用例", 是:更新teststeps结构
     """
     include_list = json_loads(tc_obj.include)
     if include_list and isinstance(include_list, list) and len(include_list) >= 3:
         param_check_dict = include_list[2]["param_check"]
         original_step = copy.deepcopy(testset["teststeps"][0])
         step_name = original_step['name'][:-2] if original_step['name'].endswith('.1') else original_step['name']
         step_no = 1
         for item, check_key_list in param_check_dict.items():
             # 入参值为空字符串校验
             if item == 'empty':
                 testset["teststeps"] = []
                 for key in check_key_list:
                     copy_step = copy.deepcopy(original_step)
                     if key in copy_step['request']['json']:
                         copy_step['name'] = '{0}.{1}'.format(step_name, step_no)
                         copy_step['request']['json'][key] = ''
                         testset["teststeps"].append(copy_step)
                         step_no += 1
     return testset
Ejemplo n.º 16
0
    def _add_step_to_testset(self, testset, tc_obj, intf_obj, tm_obj=None):
        """
        添加tc_obj的step到testset
        """
        # testset增加主用例用例后置信息
        if tm_obj and tm_obj.main_teardown_hooks:
            main_teardown_hooks = json_loads(tm_obj.main_teardown_hooks)
            if main_teardown_hooks:
                parsed_teardown_hooks = []
                for teardown_hook_str in main_teardown_hooks:
                    parsed_teardown_hook_str = setup_or_teardown_string_add_param(teardown_hook_str, is_setup=False)
                    parsed_teardown_hooks.append(parsed_teardown_hook_str)
                if 'teardown_hooks' not in testset['config']:
                    testset['config']['teardown_hooks'] = parsed_teardown_hooks
                else:
                    testset['config']['teardown_hooks'].extend(parsed_teardown_hooks)
                    testset['config']['teardown_hooks'] = list(set(testset['config']['teardown_hooks']))

        setup_testset = self._get_testset_from_obj(tc_obj, intf_obj, tm_obj=tm_obj)
        setup_teststep = setup_testset['teststeps'][0]
        testset['teststeps'].insert(0, setup_teststep)
        return testset
Ejemplo n.º 17
0
def repair_sub_case_public_var_error():
    import re
    variable_regexp = r"\$([\w_]+)"
    sub_objs = ApiTestcaseSubManager.get_testcase_subs()
    repair_count = 0
    for sub_obj in sub_objs:
        if not sub_obj.include or sub_obj.include in ['[]', '[{"public_variables": []}]']:
            continue
        include_list = json_loads(sub_obj.include)
        pv_id_list = include_list[0]['public_variables']
        pv_dic = {}
        for public_v_id in pv_id_list:
            pv_obj = ApiPublicVariableInfoManager.get_variable(id=public_v_id)
            pv_dic[public_v_id] = pv_obj.variable_name
        request_obj = ApiTestcaseRequestQllManager.get_request(api_testcase_id=sub_obj.id)
        new_pv_id_list = []
        if request_obj and request_obj.request:
            variables = re.findall(variable_regexp, str(request_obj.request))
            variables = list(set(variables))
            for variable_name in variables:
                for pv_id, pv_name in pv_dic.items():
                    if pv_name == variable_name:
                        new_pv_id_list.append(pv_id)
                        break
        if set(pv_id_list) != set(new_pv_id_list):
            new_pv_id_list.append(137)
            if set(pv_id_list) != set(new_pv_id_list):
                if 137 not in pv_id_list:
                    new_pv_id_list.remove(137)
                print('sub_obj.id:{2}, old:{0}, new:{1}'.format(pv_id_list, new_pv_id_list, sub_obj.id))
                new_include = [{"public_variables": new_pv_id_list}]
                include_str = json_dumps(new_include)
                print(include_str)
                ApiTestcaseSubManager.update_testcase_sub(id_=sub_obj.id, include=include_str)
                repair_count += 1

    print(repair_count)
Ejemplo n.º 18
0
def merge_sub_case():
    """合并相同的sub_case, 可重复执行"""
    to_update_main_sub_list_dic = {}
    testcase_main_objs = ApiTestcaseMainManager.get_testcase_mains()
    main_sub_list_dic = {}
    for testcase_main_obj in testcase_main_objs:
        main_sub_list_dic[testcase_main_obj.id] = json_loads(testcase_main_obj.sub_list)
    redundant_requests = ApiTestcaseRequestQllManager.get_redundant_requests()
    len_redundant_requests = len(redundant_requests)
    print('总计:{}'.format(len_redundant_requests))
    index = 0
    for row in redundant_requests:
        index += 1
        process = index*100.0/len_redundant_requests
        print('进度:{:.2f}%'.format(process))
        print('开始处理:{}'.format(row[0]))
        request = row[0]
        request_objs = ApiTestcaseRequestQllManager.get_requests(request=request)
        print('重复个数:{}'.format(len(request_objs)))
        target_sub_id = request_objs[0].api_testcase_id
        for request_obj in request_objs:
            print(request_obj.api_testcase_id)
            to_update_sub_id = request_obj.api_testcase_id
            if to_update_sub_id == target_sub_id:
                continue
            else:
                for main_id in main_sub_list_dic:
                    if to_update_sub_id in main_sub_list_dic[main_id]:
                        new_sub_list = [
                            target_sub_id if i == to_update_sub_id else i for i in main_sub_list_dic[main_id]
                        ]
                        main_sub_list_dic[main_id] = copy.deepcopy(new_sub_list)
                        print(new_sub_list)
                        to_update_main_sub_list_dic[main_id] = new_sub_list

    for main_id, sub_list in to_update_main_sub_list_dic.items():
        ApiTestcaseMainManager.update_testcase_main(main_id, sub_list=json_dumps(sub_list))
Ejemplo n.º 19
0
    def _add_public_env_to_config(self, testset):
        """
        给testset增加公共环境信息
        """
        if testset['config']['variables']:
            return testset

        env_info = self.env_info

        variables_list = testset['config']['variables']
        variables_list.append({"DUBBO_ZOOKEEPER": env_info.dubbo_zookeeper})
        variables_list.append({"ENV_NAME": env_info.env_name})
        variables_list.append({"DB_CONNECT": env_info.db_connect})
        variables_list.append({"BASE_HOST": env_info.base_host})
        variables_list.append({"REMOTE_HOST": env_info.remote_host})
        variables_list.append({"DISCONF_HOST": env_info.disconf_host})
        variables_list.append({"REDIS_CONNECT": env_info.redis_connect})
        variables_list.append({"SERVER_APP_MAP": env_info.server_app_map})
        variables_list.append({"SERVER_DEFAULT_USER": env_info.server_default_user})
        mq_key = json_loads(env_info.mq_key)
        variables_list.append({"MQ_AK": mq_key["ak"]})
        variables_list.append({"MQ_SK": mq_key["sk"]})

        return testset
Ejemplo n.º 20
0
    def _add_intf_info(self, testset, intf_obj, is_first=False):
        """
        添加接口基本信息
        """
        intf_type = intf_obj.intf_type
        intf_info_dic = json_loads(intf_obj.intf_info)

        # teststep = testset["teststeps"][0]
        for teststep in testset["teststeps"]:

            if intf_type == "HTTP":
                base_url = self.env_info.base_host
                api_url = intf_info_dic["apiUrl"].strip()
                if absolute_http_url_regexp.match(api_url):
                    teststep["request"]["url"] = api_url
                elif api_url.startswith('/'):
                    teststep["request"]["url"] = base_url + api_url
                else:
                    teststep["request"]["url"] = base_url + '/' + api_url
                teststep["request"]["method"] = intf_info_dic["method"]
                teststep["request"]["headers"] = json_loads(intf_info_dic["headers"].replace("'", "\""))
                teststep["request"]["allow_redirects"] = False

            elif intf_type == "DUBBO":
                base_url = self.env_info.remote_host
                teststep["request"]["url"] = base_url + "/invokeDubbo"
                teststep["request"]["method"] = "POST"

                teststep["variables"].append({"DUBBO_METHOD": intf_info_dic["dubboMethod"]})
                teststep["variables"].append({"DUBBO_INTERFACE": intf_info_dic["dubboService"]})
                teststep["variables"].append({"DUBBO_VERSION": intf_info_dic["version"]})
                teststep["request"]["json"]["version"] = "$DUBBO_VERSION"
                teststep["request"]["json"]["interfaceName"] = "$DUBBO_INTERFACE"
                teststep["request"]["json"]["zkUrl"] = "$DUBBO_ZOOKEEPER"
                teststep["request"]["json"]["methodName"] = "$DUBBO_METHOD"
                teststep["request"]["json"]["parameterTypes"] = []

                parameter_type_count = 0
                try:
                    parameter_type_list = json_loads(intf_info_dic["parameterTypes"])
                except json.decoder.JSONDecodeError:
                    logger.error('ERROR parameterTypes: intf_id {}'.format(intf_obj.id))
                    parameter_type_list = []
                for parameter_type in parameter_type_list:
                    parameter_type_count += 1
                    teststep["variables"].append({
                        "DUBBO_PARAMETER_TYPE_{no}".format(no=parameter_type_count): parameter_type
                    })
                    teststep["request"]["json"]["parameterTypes"].append(
                        "$DUBBO_PARAMETER_TYPE_{no}".format(no=parameter_type_count)
                    )

            elif intf_type == "MQ":
                if self.env_info.env_name == "SIT":
                    default_env = self.env_info.env_name
                else:
                    default_env = "ALIUAT"  # MQ的env默认为定值'ALIUAT'
                base_url = self.env_info.remote_host
                teststep["request"]["url"] = base_url + "/sendMQ"
                teststep["request"]["method"] = "POST"

                teststep["variables"].append({"MQ_TOPIC": intf_info_dic["topic"]})
                teststep["variables"].append({"MQ_TAG": intf_info_dic["tag"]})
                teststep["variables"].append({"MQ_PID": "PID_{mid}_{env}".format(
                    mid=intf_info_dic["topic"][3:], env=default_env)})

                teststep["request"]["json"]["env"] = default_env
                teststep["request"]["json"]["topic"] = "$MQ_TOPIC"
                teststep["request"]["json"]["tag"] = "$MQ_TAG"
                teststep["request"]["json"]["pid"] = "$MQ_PID"
                teststep["request"]["json"]["onsSecretKey"] = "{{\"{env}\":\"$MQ_SK\"}}".format(env=default_env)
                teststep["request"]["json"]["onsAccessKey"] = "{{\"{env}\":\"$MQ_AK\"}}".format(env=default_env)
                if "appid" in intf_info_dic and intf_info_dic["appid"]:
                    teststep["request"]["json"]["appid"] = intf_info_dic["appid"]

            # 非首次加载接口信息的情况,只处理testset["teststeps"][0]
            if not is_first:
                break

        return testset
Ejemplo n.º 21
0
def http_runner_run(**kwargs):
    """调用HttpRunner运行测试"""
    log_dir = kwargs.pop('log_dir')
    env_id = kwargs.pop('env_id')
    testset = kwargs.pop('testset')
    test_meta_list = kwargs.pop('test_meta_list')
    run_task_result_id = kwargs.pop('run_task_result_id')
    intf_id = kwargs.pop('intf_id', None)
    main_case_id = kwargs.pop('main_case_id', None)
    main_case_id_list = kwargs.pop('main_case_id_list', None)

    if intf_id:
        log_path = '{0}task_run_{1}_intf_{2}.log'.format(log_dir, run_task_result_id, intf_id)
    elif main_case_id:
        log_path = '{0}task_run_{1}_main_case_{2}.log'.format(log_dir, run_task_result_id, main_case_id)
    else:
        log_path = '{0}task_run_{1}_main_case_list_{2}.log'.format(log_dir, run_task_result_id, main_case_id_list)

    # 初始化hr_runner
    hr_kwargs = {
        "failfast": True,
        "log_path": log_path
    }
    hr_runner = HttpRunner(**hr_kwargs)

    start_time = time.strftime('%Y-%m-%d %H-%M-%S', time.localtime(time.time()))
    hr_logger.log_warning("【START】测试开始! (ง •_•)ง")
    hr_logger.log_warning("【环境】: {}".format(env_id))
    # time.sleep(3)
    try:
        testset_json = json_dumps(testset)
    except Exception:
        testset_json = testset

    # 执行测试
    try:
        # hr_logger.log_warning("【调用HttpRunner】: {0}".format(testset_json))
        hr_runner.run(testset)
        hr_logger.log_info("【结束调用HttpRunner】")
    except Exception:
        raise Exception(traceback.format_exc())

    for detail in hr_runner.summary["details"]:
        for record in detail["records"]:
            record["meta_data"]["request"].pop("files", None)

    # 去除summary中的文件对象
    summary_remove_file_obj(hr_runner.summary)

    # 完善summary
    summary = deepcopy(hr_runner.summary)
    # summary = hr_runner.summary
    perfect_summary(summary, test_meta_list)

    # print(json_dumps(summary))
    summary = add_memo(summary)

    # 识别错误
    # print(json_dumps(summary))
    summary = identify_errors(summary)

    return {"summary": json_loads(json_dumps(summary)), "run_task_result_id": run_task_result_id, 'log_dir': log_dir}
Ejemplo n.º 22
0
    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)
        })
Ejemplo n.º 23
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)
Ejemplo n.º 24
0
    def _get_testset_from_obj(tc_obj, intf_obj, tm_obj=None):
        """
        从数据库对象obj中获取request值,并转成dict格式,并进行一些预处理,把缺少必要环境变量的地方加上环境变量
        e.g:
            change from
            "variables": [
                {
                    "encrypted_newPassword": "******"
                }
            ],
            to
            "variables": [
                {
                    "encrypted_newPassword": "******"
                }
            ],
        更新:识别"入参字段校验用例"
        """
        if tm_obj:
            testset_str = atrqm.get_request(api_testcase_id=tc_obj.id).request
        else:
            testset_str = atrm.get_request(api_testcase_id=tc_obj.id).request

        try:
            testset = json.loads(testset_str)
        except JSONDecodeError:
            raise LoadCaseError('Json Load testcase_info.request Error')

        # for v_dic in testset["teststeps"][0]["variables"]:
        #     for v_name in v_dic:
        #         if isinstance(v_dic[v_name], str) and v_dic[v_name].startswith(
        #                 "${encrypt_by_public_key") and not v_dic[v_name].endswith(
        #                 "||$REMOTE_HOST)}"):
        #             v_dic[v_name] = v_dic[v_name][:-2] + "||$REMOTE_HOST)}"

        new_variables = []
        for variable_dic in testset["teststeps"][0]["variables"]:
            for variable_name, variable_str in variable_dic.items():
                if isinstance(variable_str, str):
                    parsed_variable_str = variable_string_add_param(variable_str)
                else:
                    parsed_variable_str = variable_str
                new_variables.append({variable_name: parsed_variable_str})
        testset["teststeps"][0]["variables"] = new_variables

        new_setup_hooks = []
        for setup_hook_str in testset["teststeps"][0]["setup_hooks"]:
            # if setup_hook_str.startswith("${setup_fund_order_conf") and not setup_hook_str.endswith(
            #         "||$DB_CONNECT)}"):
            #     setup_hook_str = setup_hook_str[:-2] + "||$DB_CONNECT)}"
            # if setup_hook_str.startswith("${setup_disconf_operation_merge") and not setup_hook_str.endswith(
            #         "||$DISCONF_HOST)}"):
            #     setup_hook_str = setup_hook_str[:-2] + "||$DISCONF_HOST)}"
            parsed_setup_hook_str = setup_or_teardown_string_add_param(setup_hook_str, is_setup=True)
            new_setup_hooks.append(parsed_setup_hook_str)
        testset["teststeps"][0]["setup_hooks"] = new_setup_hooks

        new_teardown_hooks = []
        for teardown_hook_str in testset["teststeps"][0]["teardown_hooks"]:
            # if teardown_hook_str.startswith("${teardown_disconf_operation_merge") and not teardown_hook_str.endswith(
            #         "||$DISCONF_HOST)}"):
            #     teardown_hook_str = teardown_hook_str[:-2] + "||$DISCONF_HOST)}"
            parsed_teardown_hook_str = setup_or_teardown_string_add_param(teardown_hook_str, is_setup=False)
            new_teardown_hooks.append(parsed_teardown_hook_str)
        testset["teststeps"][0]["teardown_hooks"] = new_teardown_hooks

        if "request_teardown_hooks" in testset["teststeps"][0]:
            new_request_teardown_hooks = []
            for teardown_hook_str in testset["teststeps"][0]["request_teardown_hooks"]:
                parsed_teardown_hook_str = setup_or_teardown_string_add_param(teardown_hook_str, is_setup=False)
                new_request_teardown_hooks.append(parsed_teardown_hook_str)
            testset["teststeps"][0]["request_teardown_hooks"] = new_request_teardown_hooks

        if tm_obj:
            testset["teststeps"][0]["case_id"] = tm_obj.id
            testset["teststeps"][0]["sub_case_id"] = tc_obj.id
            testset["teststeps"][0]["is_main"] = True
        else:
            testset["teststeps"][0]["case_id"] = tc_obj.id
            testset["teststeps"][0]["is_main"] = False

        # # 注释合并请求报文
        # intf_r_obj = aidrm.get_request(api_intf_id=tc_obj.api_intf_id)
        # if intf_r_obj and intf_r_obj.request:
        #     default_body_base = json_loads(intf_r_obj.request)
        #     default_body_detail = json_loads(intf_r_obj.request_detail)
        #     # 根据intf_r_obj.request_detail中首层字段的必填性,把非必填字段去除
        #     for key_dic in default_body_detail:
        #         if not key_dic["isRequired"]:
        #             if isinstance(default_body_base, list):
        #                 default_body_base = []
        #             else:
        #                 default_body_base.pop(key_dic["paramName"])
        #
        #     if default_body_base:
        #         request_type = tc_obj.request_type if tm_obj else tc_obj.type
        #
        #         # 合并请求报文
        #         # http
        #         if request_type == 1:
        #             tc_body = testset["teststeps"][0]["request"]["json"]
        #             testset["teststeps"][0]["request"]["json"] = merge_request_body(default_body_base, tc_body)
        #         # dubbo
        #         elif request_type == 2:
        #             tc_body = testset["teststeps"][0]["request"]["json"]["args"]
        #             testset["teststeps"][0]["request"]["json"]["args"] = merge_request_body(
        #                 default_body_base, tc_body, is_list=True
        #             )
        #         # mq
        #         elif request_type == 3:
        #             tc_body_str = testset["teststeps"][0]["request"]["json"]["msg"]
        #             tc_body = json_loads(tc_body_str)
        #             testset["teststeps"][0]["request"]["msg"] = json_dumps(
        #                 merge_request_body(default_body_base, tc_body)
        #             )
        testset["teststeps"][0]["request"].pop("isMerge", None)

        # 增加支持form表单类型接口
        # intf_obj = aiim.get_intf(id=tc_obj.api_intf_id)
        if intf_obj.intf_type == 'HTTP':
            intf_info_dic = json_loads(intf_obj.intf_info)
            headers_dic = json_loads(intf_info_dic["headers"].replace("'", "\""))
            if 'Content-Type' in headers_dic:
                if 'application/x-www-form-urlencoded' in headers_dic['Content-Type']:
                    testset["teststeps"][0]["request"]["data"] = testset["teststeps"][0]["request"]["json"]
                    testset["teststeps"][0]["request"].pop("json")
        return testset
Ejemplo n.º 25
0
    def save_task_results(self):
        """保存测试结果到任务运行结果表api_run_task_result和用例复用表api_testcase_reuse_record"""

        summary_list = []
        for summary_path in self.summary_path_list:
            if not summary_path or 'worker_summary_path is None' == summary_path:
                continue
            with open(summary_path, 'r') as f:
                summary_str = f.readline()
                summary_dict = json_loads(summary_str)
                summary_list.append(summary_dict)
                if not self.run_task_result_id:
                    self.run_task_result_id = summary_dict['run_task_result_id'] if 'run_task_result_id' in summary_dict else None
                if not self.log_dir:
                    self.log_dir = summary_dict['log_dir'] if 'log_dir' in summary_dict else None

        # run_task_result_id = summary_list[0]['run_task_result_id']
        # log_dir = summary_list[0]['log_dir']

        # 保存summary_list到服务器文件目录run_task_logs
        with open('{0}task_run_{1}_summary.log'.format(self.log_dir, self.run_task_result_id), 'w') as f:
            f.write(json_dumps(summary_list))

        callback_task_obj = CeleryTaskRecordManager.get_callback_celery(api_run_task_result_id=self.run_task_result_id)

        try:
            # 更新celery_task_record表的字段celery_task_status为RUNNING
            CeleryTaskRecordManager.update_celery(callback_task_obj.id, celery_task_status='RUNNING')

            total_cases = 0
            for summary in summary_list:
                total_cases += summary.pop('total_cases')

            res_obj = ApiRunTaskResultManager.get_result(id=self.run_task_result_id)
            task_obj = ApiTaskInfoManager.get_task(id=res_obj.api_task_id)

            # 获取task全部的intf_id_list
            if task_obj.task_type in (1, 3):
                task_intf_id_list = json_loads(task_obj.case_tree)['intf_id_list']
            else:
                task_intf_id_list = json_loads(task_obj.effect_intf_id_list)

            # 更新api_testcase_reuse_record表, 并获取covered_intf_id_set, run_cases, success_cases
            res_list = save_testcase_reuse_record(summary_list)

            # 本次测试包含的接口id集合
            covered_intf_id_set = res_list[0]
            # 本次运行的用例数
            run_cases = res_list[1]
            # 本次成功的用例数
            success_cases = res_list[2]
            # 本次未覆盖的接口id列表
            uncovered_intf_id_list = list(set(task_intf_id_list) ^ covered_intf_id_set)
            # 本次失败的用例数
            fail_cases = run_cases - success_cases
            # 本次未运行的用例数
            not_run_cases = total_cases - run_cases

            # 更新api_run_task_result表
            ApiRunTaskResultManager.update_result(
                self.run_task_result_id, total_cases=total_cases,
                not_run_cases=not_run_cases, run_cases=run_cases, success_cases=success_cases, fail_cases=fail_cases,
                end_time=datetime.now(), covered_intf_id_list=json_dumps(list(covered_intf_id_set)),
                uncovered_intf_id_list=json_dumps(uncovered_intf_id_list)
            )

            # 更新celery_task_record表的字段celery_task_status为SUCCESS
            CeleryTaskRecordManager.update_celery(callback_task_obj.id, celery_task_status='SUCCESS')

        except Exception as err:
            # 更新api_run_task_result表
            ApiRunTaskResultManager.update_result(self.run_task_result_id, end_time=datetime.now())
            # 更新celery_task_record表的字段celery_task_status为ERROR
            CeleryTaskRecordManager.update_celery(callback_task_obj.id, celery_task_status='ERROR')
            print('\n'.join([str(err), traceback.format_exc()]))
            raise Exception(err)
Ejemplo n.º 26
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
Ejemplo n.º 27
0
    def _add_pv(self, testset, tc_obj, intf_obj, tm_obj=None):
        """
        添加公共变量到config
        """
        # testset增加主用例用例独立后置中的公共变量
        if not self.has_extract_variable_in_main_teardown and tm_obj and tm_obj.main_teardown_hooks:
            variable_regexp = r"\$([\w_]+)"
            # main_teardown_hooks = json_loads(tm_obj.main_teardown_hooks)
            main_teardown_variables = re.findall(variable_regexp, str(tm_obj.main_teardown_hooks))
            for target in main_teardown_variables:
                system_id = intf_obj.api_system_id
                s_var_obj = ApiPublicVariableInfoManager.get_variable(variable_name=target, api_system_id=system_id)

                if s_var_obj:
                    testset["config"]["variables"].append({
                        target: s_var_obj.value.split('##')[0]
                    })
                else:
                    company_id = ApiSystemInfoManager.get_system(id=system_id).api_company_id
                    c_var_obj = ApiPublicVariableInfoManager.get_variable(
                        variable_name=target, api_company_id=company_id)
                    if c_var_obj:
                        testset["config"]["variables"].append({
                            target: c_var_obj.value.split('##')[0]
                        })
            self.has_extract_variable_in_main_teardown = True

        teststep = testset["teststeps"][0]
        include_list = json_loads(tc_obj.include)
        pv_list = None
        for include in include_list:
            if "public_variables" in include:
                pv_list = include["public_variables"]
                break

        """用例存在引用公共变量"""
        if pv_list:
            """存在公共变量临时修改"""
            if self.confirmed_pv_changes:
                for pv_change_dic in self.confirmed_pv_changes:
                    if pv_change_dic['changedValue']:
                        if pv_change_dic['type'] == 'files':
                            continue  # 暂不支持文件类型公共变量临时修改
                        elif pv_change_dic['type'] in ['constant', 'function', 'db']:
                            if int(pv_change_dic['pvId']) in pv_list:
                                pv_list.remove(int(pv_change_dic['pvId']))
                                testset["config"]["variables"].append({
                                    pv_change_dic['name']: pv_change_dic['changedValue']
                                })

                        # if int(pv_change_dic['pvId']) in pv_list:
                        #     if pv_change_dic['type'] == 'files':
                        #         continue  # 暂不支持文件类型公共变量临时修改
                        #     pv_list.remove(int(pv_change_dic['pvId']))
                        #     testset["config"]["variables"].append({
                        #         pv_change_dic['name']: pv_change_dic['changedValue']
                        #     })

            pv_objs = avim.get_variables_in_id_list(pv_list)
            for obj in pv_objs:
                if obj.type == 'files':
                    """特殊处理files类型的公共变量"""
                    file_variable_name = obj.variable_name
                    try:
                        file_path_list = eval(obj.value)
                    except (SyntaxError, NameError):
                        file_path_list = None

                    if not isinstance(file_path_list, list):
                        continue

                    target_key = None
                    for key in teststep['request']['json']:
                        if teststep['request']['json'][key] == '$' + file_variable_name:
                            teststep['request']['files'] = []
                            for i in range(len(file_path_list)):
                                if 'f_name' in teststep['request']['json']:
                                    file_name = teststep['request']['json']['f_name'][i]
                                else:
                                    file_name = str(file_path_list[i]).split('/')[-1]
                                try:
                                    teststep['request']['files'].append(
                                        (key, (file_name, open(file_path_list[i], "rb"), "multipart/form-data"))
                                    )
                                except FileNotFoundError:
                                    # 公共变量指定的文件不存在
                                    pass
                            target_key = key
                            break
                    if target_key:
                        teststep['request']['json'].pop('f_name', 0)
                        teststep['request']['json'].pop(target_key)
                        teststep['request']['data'] = teststep['request']['json']
                        teststep['request'].pop('json')
                elif obj.type == 'function':
                    """处理自定义方法类型的公共变量"""
                    is_exist = False
                    for exist_pv_dic in testset["config"]["variables"]:
                        for key in exist_pv_dic:
                            if key == obj.variable_name:
                                is_exist = True
                        if is_exist:
                            break
                    if not is_exist:
                        variable_string = variable_string_add_param(str(obj.value))
                        testset["config"]["variables"].append({
                            obj.variable_name: variable_string
                        })
                elif obj.type == 'db':
                    """处理db类型的公共变量"""
                    is_exist = False
                    for exist_pv_dic in testset["config"]["variables"]:
                        for key in exist_pv_dic:
                            if key == obj.variable_name:
                                is_exist = True
                        if is_exist:
                            break
                    if not is_exist:
                        testset["config"]["variables"].append({
                            obj.variable_name: [v.strip() for v in str(obj.value).strip('##').split('##')][0]
                        })
                else:
                    """处理key-value类型的公共变量"""
                    is_exist = False
                    for exist_pv_dic in testset["config"]["variables"]:
                        for key in exist_pv_dic:
                            if key == obj.variable_name:
                                is_exist = True
                        if is_exist:
                            break
                    if not is_exist:
                        var_value = [v.strip() for v in str(obj.value).strip('##').split('##')][0]
                        save_as = obj.save_as if obj.save_as else 'str'
                        if save_as in ['num', 'bool', 'list', 'dict']:
                            try:
                                var_value = eval(var_value)
                            except SyntaxError:
                                var_value = var_value
                        testset["config"]["variables"].append({
                            obj.variable_name: var_value
                        })

        return testset
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
def celery_run_debug(**kwargs):
    # with app.app_context():
    if True:
        log_dir = kwargs.get('log_dir')
        report_id = kwargs.pop('report_id', None)
        plan_name = kwargs.pop('plan_name', None)
        project_id = kwargs.pop('project_id', None)
        testcase_main_id_list = kwargs.get('testcase_main_id_list', None)
        if testcase_main_id_list:
            is_main = True
        else:
            is_main = False

        print('=============================={dir}run_{report_id}.log'.format(
            dir=log_dir, report_id=report_id))
        hr_kwargs = {
            "failfast":
            True,
            "log_path":
            '{dir}run_{report_id}.log'.format(dir=log_dir, report_id=report_id)
        }
        runner = HttpRunner(**hr_kwargs)

        try:
            loader = ApiTestLoader(**kwargs)
            testset = loader.get_testset_list()
            test_meta_list = loader.get_test_meta_list()

            if not testset:
                raise LoadCaseError('没有可执行的用例')

            # logger.debug("{1} testset:{0}".format(testset, type(testset)))

        except Exception as err:
            save_report(report_path=None,
                        runner_summary=None,
                        project_id=project_id,
                        report_id=report_id)
            hr_logger.log_error("【ERROR】组装用例出错!")
            hr_logger.log_error('\n'.join([str(err), traceback.format_exc()]))
            hr_logger.log_info("【END】测试结束!")
            hr_logger.remove_handler(runner.handler)
            raise LoadCaseError

        try:
            hr_logger.log_info("【START】测试开始! (ง •_•)ง")
            hr_logger.log_info("【环境】: {}".format(kwargs.get('env_name', None)))
            # time.sleep(3)
            try:
                testset_json = json_dumps(testset)
            except Exception:
                testset_json = testset
            hr_logger.log_info("【调用HttpRunner】: {0}".format(testset_json))
            runner.run(testset)
            hr_logger.log_info("【结束调用HttpRunner】")
            # raise RunCaseError
            perfect_summary(runner.summary, test_meta_list)
            """记录用例复用记录"""
            api_runner.summary_remove_file_obj(runner.summary)
            summary_for_reuse = copy.deepcopy(runner.summary)
            # print(json_dumps(summary_for_reuse))
            summary_for_reuse = api_runner.add_memo(summary_for_reuse)
            # 识别错误
            summary_for_reuse = api_runner.identify_errors(summary_for_reuse)
            # 更新api_testcase_reuse_record表, 并获取covered_intf_id_set, run_cases, success_cases
            save_testcase_reuse_record([{
                "summary":
                json_loads(json_dumps(summary_for_reuse))
            }])
            del summary_for_reuse

            # hr_logger.log_info("【runner.summary】: {}".format(runner.summary))
            '''报告优化:1、汉化(包括日志里面的字段)
                        2、开始时间和持续时间合并成一行
                        3、增加一个字段“错误类型”,如果用例错误,显示该字段,并说明期望与预期值;
                                                    否则该字段不显示
                        4.log里面去掉一些数据重复和不重要的;行和字段(请求headers,返回体的headers,reason,url,“”ok”)
                        5.将请求体和返回值数据缩进,且字典里面的key颜色加粗
                        6.新增接口请求类型字段,http、dubbo、mq'''

            from atp.utils.custom import json_contains, db_validate, db_json_validate
            for detail in runner.summary["details"]:
                for record in detail["records"]:
                    '''增加用例类型:test_meta_list["intf_type"]'''
                    record["intf_type"] = test_meta_list[0]["intf_type"]
                    '''删除报告一些无需关注的字段'''
                    request_keys = ["json", "start_timestamp"]
                    response_keys = [
                        "elapsed_ms", "encoding", 'ok', 'url', 'reason',
                        'cookies'
                    ]
                    for request_key in request_keys:
                        if request_key in record["meta_data"]["request"]:
                            del record["meta_data"]["request"][request_key]
                    for respones_key in response_keys:
                        if respones_key in record["meta_data"]["response"]:
                            del record["meta_data"]["response"][respones_key]
                    '''record.status出现error, 抛出错误信息'''
                    if record['status'] == 'error':
                        error_msg = record['attachment']
                        raise Exception(error_msg)
                    '''报告增加一列:错误类型:'''
                    for validate in record["meta_data"]["validators"]:
                        if validate["comparator"] == "json_contains":
                            check_value = validate["check_value"]
                            expect_value = validate["expect"]
                            if json_contains(check_value,
                                             expect_value) is not True:
                                validate["check_result"] = "fail"
                                record["status"] = "failure"
                                detail["stat"]["failures"] += 1
                                detail["stat"]["successes"] -= 1
                                runner.summary["stat"]["failures"] += 1
                                runner.summary["stat"]["successes"] -= 1
                                error_log = (
                                    "预期:{}未在返回报文内".format(expect_value))
                                validate["error_log"] = {
                                    "json_contains": error_log
                                }
                        elif validate["comparator"] == "db_validate":
                            check_value = validate["check_value"]
                            expect_value = validate["expect"]
                            if db_validate(check_value,
                                           expect_value) is not True:
                                validate["check_result"] = "fail"
                                record["status"] = "failure"
                                detail["stat"]["failures"] += 1
                                detail["stat"]["successes"] -= 1
                                runner.summary["stat"]["failures"] += 1
                                runner.summary["stat"]["successes"] -= 1
                                error_log = ("预期:{0},实际是:{1}".format(
                                    expect_value, check_value))
                                validate["error_log"] = {
                                    "db_validate": error_log
                                }
                        elif validate["comparator"] == "db_json_validate":
                            check_value = validate["check_value"]
                            expect_value = validate["expect"]
                            if not db_json_validate(check_value, expect_value):
                                validate["check_result"] = "fail"
                                record["status"] = "failure"
                                detail["stat"]["failures"] += 1
                                detail["stat"]["successes"] -= 1
                                runner.summary["stat"]["failures"] += 1
                                runner.summary["stat"]["successes"] -= 1
                                error_log = ("预期:{0},实际是:{1}".format(
                                    expect_value,
                                    json.dumps(check_value).encode(
                                        'utf-8').decode('unicode_escape')))
                                validate["error_log"] = {
                                    "db_json_validate": error_log
                                }

            hr_logger.log_info("【runner.summary】: {}".format(runner.summary))
            runner_summary = copy.deepcopy(runner.summary)
            """把每条用例执行成功与否记录到testcase_info.last_run"""
            try:
                save_last_run(runner_summary, is_main=is_main)
            except Exception as e:
                print('\n'.join([str(e), traceback.format_exc()]))
                # hr_logger.log_error("【ERROR】运行用例出错!")
                # hr_logger.log_error('\n'.join([str(e), traceback.format_exc()]))

            # print("runner_summary_list{}".format(runner.summary))
            # report_path = runner.gen_html_report(
            #     html_report_name=plan_name if plan_name else 'default',
            #     html_report_template=config.REPORT_TEMPLATE_PATH,
            #     html_report_dir=config.REPORT_DIR
            # )
            # print('report_path:{}'.format(report_path))
            # report_path = report_path.split('reports')[1]
            # report_url = get_host() + r':8899/reports' + report_path
            #
            # print('AC report_path:{}'.format(report_path))
            report_url = '不生成报告'
            save_report(report_url,
                        runner_summary,
                        project_id,
                        report_id=report_id,
                        is_main=is_main)

        except Exception as err:
            save_report(report_path=None,
                        runner_summary=runner.summary,
                        project_id=project_id,
                        report_id=report_id)
            hr_logger.log_error("【ERROR】运行用例出错!")
            hr_logger.log_error('\n'.join([str(err), traceback.format_exc()]))
            time.sleep(1)
            raise RunCaseError
        finally:
            time.sleep(1)
            hr_logger.log_info("【END】测试结束!")
            hr_logger.remove_handler(runner.handler)

        return report_url
Ejemplo n.º 30
0
    def run_task(self, task_id):
        """运行回归测试任务"""

        # 获取回归测试任务详细内容
        self.get_task_obj(task_id)

        # celery_no_list = []
        # total_cases = 0

        # 获取待测试的接口id列表
        to_run_intf_id_list = []
        product_line_id_list = []
        if self.task_obj.task_type in (1, 3):
            to_run_dic = json_loads(self.task_obj.case_tree)
            to_run_intf_id_list = to_run_dic.get('intf_id_list', [])
            # to_run_testcase_main_id_list = to_run_dic.get('testcase_main_id_list', [])
            product_line_id_list = to_run_dic.get('product_line_id_list', [])

        elif self.task_obj.task_type == 2:
            to_run_intf_id_list = json_loads(self.task_obj.effect_intf_id_list)

        # 待测试列表为空
        if not isinstance(to_run_intf_id_list, list) or not isinstance(product_line_id_list, list) or \
                (not to_run_intf_id_list and not product_line_id_list):
            # if self.run_task_result_id:
            #     ApiRunTaskResultManager.delete_result(self.run_task_result_id)
            return None

        # 接口用例智能去重
        intf_testcase_map = {}
        for intf_id in to_run_intf_id_list:
            testcase_id_list = self.get_testcase_id_list_filter_by_tag(intf_id=intf_id)
            if testcase_id_list:
                intf_testcase_map[intf_id] = testcase_id_list

        if not intf_testcase_map:
            # 如果没有可运行的用例,直接返回
            return None
        filtered_intf_testcases_map = smart_filter_testcase(intf_testcase_map, self.table_data)

        # 写入回归测试任务记录表
        self.set_run_task_result(task_id)

        # 拆分测试任务
        header = []
        countdown = self.reboot_sleep if self.reboot_sleep else 1
        print(countdown)

        # 拆分全链路测试用例
        if self.run_main_case_in_parallel:
            # 每条全链路用例分配一个worker
            timed_to_run_product_line_id_list = []
            for _ in range(self.times):  # 循环次数
                timed_to_run_product_line_id_list.extend(product_line_id_list)
            for product_line_id in timed_to_run_product_line_id_list:
                testcase_main_id_list = self.get_testcase_id_list_filter_by_tag(product_line_id=product_line_id)
                for testcase_main_id in testcase_main_id_list:
                    header.append(
                        celery_run_single_intf_or_single_main_case.signature(
                            (self.run_task_result_id, self.env_id, testcase_main_id, False, self.run_task_log_dir),
                            countdown=countdown
                        )
                    )
                    countdown = self.get_next_countdown(countdown)
                    print(countdown)
        else:
            # 每个最末产品线分配一个worker
            for product_line_id in product_line_id_list:
                testcase_main_id_list = self.get_testcase_id_list_filter_by_tag(product_line_id=product_line_id)
                if testcase_main_id_list:
                    timed_testcase_main_id_list = []
                    for _ in range(self.times):  # 循环次数
                        timed_testcase_main_id_list.extend(testcase_main_id_list)
                    header.append(
                        celery_run_main_case_list.signature(
                            (self.run_task_result_id, self.env_id, timed_testcase_main_id_list, self.run_task_log_dir),
                            countdown=countdown
                        )
                    )
                    countdown = self.get_next_countdown(countdown)
                    print(countdown)

        # 拆分接口测试用例 -- 每个接口分配一个worker
        for intf_id, testcase_id_list in filtered_intf_testcases_map.items():
            if testcase_id_list:
                timed_testcase_id_list = []
                for _ in range(self.times):  # 循环次数
                    timed_testcase_id_list.extend(testcase_id_list)
                header.append(
                    celery_run_single_intf_or_single_main_case.signature(
                        (self.run_task_result_id, self.env_id, intf_id, True, self.run_task_log_dir,
                         timed_testcase_id_list),
                        countdown=countdown
                    )
                )
                countdown = self.get_next_countdown(countdown)
                print(countdown)

        # worker_num = len(header)
        # logger.info('本次运行总共需要的worker数量: {}'.format(worker_num))
        # # time.sleep(3)
        # # 分配异步测试任务, 增加回调任务收集测试结果
        # callback = celery_collect_results.s()
        # chord_result = chord(header)(callback)
        # callback_celery_no = chord_result.id
        #
        # # 更新api_run_task_result表,本次运行总共需要的worker数量
        # ApiRunTaskResultManager.update_result(id_=self.run_task_result_id, worker_num=worker_num)
        # # 写入celery任务表
        # CeleryTaskRecordManager.insert_celery(celery_task_no=callback_celery_no, celery_task_status='WAITING',
        #                                       api_run_task_result_id=self.run_task_result_id)
        #
        # return callback_celery_no

        # 分配异步测试任务, 增加回调任务收集测试结果
        callback_celery_no = self._assign_celery_tasks(header)
        return callback_celery_no