コード例 #1
0
def set_project_name(project_report):
    if isinstance(project_report, dict):
        project_id = project_report.get("projectId")
        project = common.format_response_in_dic(
            Project.find_one({"_id": ObjectId(project_id)}))
        project_name = project.get(
            "name") if project else "Get project name failed"
        project_report["projectName"] = project_name
    return project_report
コード例 #2
0
def start_test():
    # TODO 性能优化
    from testframe.interfaceTest.tester import tester
    request_data = request.get_json()
    case_suite_id_list = None
    case_id_list = None
    executor_nick_name = None
    execution_mode = None
    is_single_test = None

    if 'domain' not in request_data:
        return jsonify({'status': 'failed', 'data': '缺失domain字段!'})
    else:
        domain = request_data["domain"]

    if 'caseSuiteIdList' in request_data:
        case_suite_id_list = request_data["caseSuiteIdList"]

    if 'caseIdList' in request_data:
        case_id_list = request_data["caseIdList"]

    if 'executorNickName' in request_data:
        executor_nick_name = request_data["executorNickName"]

    if 'executionMode' in request_data:
        execution_mode = request_data["executionMode"]

    testing_case_list = []
    testing_cases = copy.deepcopy(
        TestingCase.find({
            'isDeleted': {
                '$ne': True
            },
            'status': True
        })  # sort吃顺序
        .sort([('caseSuiteId', pymongo.ASCENDING),
               ('createAt', pymongo.ASCENDING)]))

    if case_suite_id_list:
        for case_suite_id in case_suite_id_list:
            is_forbiddened_case_suite = len(
                list(
                    CaseSuite.find({
                        '_id': ObjectId(case_suite_id),
                        'status': {
                            '$ne': True
                        }
                    }))) > 0
            if is_forbiddened_case_suite:
                return jsonify({'status': 'failed', 'data': '请先「启用」测试用例'})

        for testing_case in testing_cases:
            if "caseSuiteId" in testing_case and str(
                    testing_case["caseSuiteId"]) in case_suite_id_list:
                testing_case_list.append(testing_case)

    if not case_id_list and len(testing_case_list) < 1:
        return jsonify({
            'status': 'failed',
            'data': '未在「测试用例」中找到任何「启用的」接口测试用例'
        })

    testing_cases = copy.deepcopy(
        TestingCase.find({
            'isDeleted': {
                '$ne': True
            },
            'status': True
        })  # sort吃顺序
        .sort([('caseSuiteId', pymongo.ASCENDING),
               ('createAt', pymongo.ASCENDING)]))  # 再次初始化 Cursor object
    if case_id_list:
        for testing_case in testing_cases:
            if str(testing_case["_id"]) in case_id_list:
                testing_case_list.append(testing_case)

    if len(testing_case_list) > 0:
        project_id = testing_case_list[0]["projectId"]
        project_name = Project.find_one({'_id': ObjectId(project_id)})['name']
    else:
        return jsonify({'status': 'failed', 'data': '请先「启用」接口测试用例'})

    # 去除相同的测试用例
    def remove_duplicated_case(case_list):
        id_list = []
        for case in case_list:
            case_id = case["_id"]
            if case_id in id_list:
                case_list.remove(case)
            else:
                id_list.append(case_id)
        return case_list

    testing_case_list = remove_duplicated_case(testing_case_list)

    if 'caseSuiteIdList' not in request_data and len(testing_case_list) == 1:
        is_single_test = True

    tester = tester(test_case_list=testing_case_list, domain=domain)

    if not is_single_test:
        try:
            tester.execute_all_test_and_send_report(TestingCase, TestReport,
                                                    project_id,
                                                    executor_nick_name,
                                                    execution_mode,
                                                    project_name)
            return jsonify({'status': 'ok', 'data': '测试已启动,稍后请留意自动化测试报告'})
        except BaseException as e:
            return jsonify({'status': 'failed', 'data': '测试启动失败: %s' % e})
    else:
        # TODO 单个接口测试需要返回测试结果,使用同步方法, 需重构
        test_result_list = tester.execute_all_test_for_cron_and_single_test()
        for index, test_result in enumerate(test_result_list):
            test_case_id = test_result["_id"]
            test_result = common.format_response_in_dic(test_result)
            test_result_list[index] = test_result
            TestingCase.update({"_id": ObjectId(test_case_id)},
                               {'$set': {
                                   'lastManualTestResult': test_result
                               }})
        test_count = len(test_result_list)
        passed_count = len(
            list(
                filter(lambda x: x == 'ok', [
                    test_result["status"] for test_result in test_result_list
                ])))
        failed_count = len(
            list(
                filter(lambda x: x == 'failed', [
                    test_result["status"] for test_result in test_result_list
                ])))
        passed_rate = '%d' % round((passed_count / test_count) * 100, 2) + '%'

        if test_count > 0:
            for test_result in test_result_list:
                if 'testBaseInfo' in test_result and 'lastManualTestResult' in test_result[
                        'testBaseInfo']:
                    test_result['testBaseInfo'].pop('lastManualTestResult')

            raw_data = {
                "projectId":
                ObjectId(project_id),
                "projectName":
                project_name,
                "testCount":
                test_count,
                "passCount":
                passed_count,
                "failedCount":
                failed_count,
                "passRate":
                passed_rate,
                "comeFrom":
                execution_mode,
                "executorNickName":
                executor_nick_name,
                "totalTestSpendingTimeInSec":
                test_result_list[0]['spendingTimeInSec'],
                "testDomain":
                domain,
                "testDetail":
                test_result_list,
                "createAt":
                datetime.datetime.utcnow()
            }
            filtered_data = TestReport.filter_field(raw_data,
                                                    use_set_default=True)
            TestReport.insert(filtered_data)

        return jsonify({'status': 'ok', 'data': test_result_list})
コード例 #3
0
def get_project(project_id):
    res = Project.find_one({'_id': ObjectId(project_id)})
    return jsonify({
        'status': 'ok',
        'data': common.format_response_in_dic(res)
    })
コード例 #4
0
    def cron_mission(self):
        # print(self.stop_alert_and_wait_until_resume )
        cron_test_cases_list = self.get_cron_test_cases_list()
        if len(cron_test_cases_list) > 0:
            project_id = cron_test_cases_list[0]["projectId"]
            project_name = Project.find_one({'_id': ObjectId(project_id)})['name']
        else:
            raise TypeError('定时任务执行中未找到任何可执行用例!')

        tester_for_cron = tester(test_case_list=cron_test_cases_list,
                                 domain=self.test_domain)

        total_test_start_time = time.time()

        test_result_list = tester_for_cron.execute_all_test_for_cron_and_single_test()

        total_test_end_time = time.time()

        total_test_spending_time = round(total_test_end_time - total_test_start_time, 3)

        for index, test_result in enumerate(test_result_list):
            test_result = common.format_response_in_dic(test_result)
            test_result_list[index] = test_result

        if not len(test_result_list):
            return

        self.failed_count = len(
            list(filter(lambda x: x == 'failed', [test_result["status"] for test_result in test_result_list])))

        self.current_retry_count += 1 if self.failed_count > 0 else -self.current_retry_count

        generate_retry_cron = self.failed_count > 0 and self.current_retry_count < self.retry_limit

        self.generate_test_report(project_id, self.get_id(), test_result_list, total_test_spending_time, project_name)

        if generate_retry_cron:

            print(f'当前失败用例个数:{self.failed_count}')
            print(f'正在重试第 {self.current_retry_count} 次')

            time.sleep(self.retry_interval)

            self.cron_mission()

        else:
            is_send_mail = self.failed_count > 0 and isinstance(self.alarm_mail_list, list) \
                           and len(self.alarm_mail_list) > 0

            is_send_ding_ding = self.ding_ding_access_token if hasattr(self, 'ding_ding_access_token') else False

            is_send_enterprise_wechat = self.enterprise_wechat_access_token if hasattr(self,
                                                                                       'enterprise_wechat_access_token') \
                else False

            finally_passed_and_send_resume_notify = not self.failed_count and self.stop_alert_and_wait_until_resume.get(self.cron_name)

            failed_again_but_wait_for_resume = self.failed_count and self.stop_alert_and_wait_until_resume.get(self.cron_name)

            if finally_passed_and_send_resume_notify:

                print(f'finally_passed_and_send_resume_notify... report id: {self.report_id}')

                if is_send_enterprise_wechat:

                    enterprise_wechat_title = '### 接口测试平台企业微信服务'
                    enterprise_wechat_content = f' ✅️ {project_name} 项目 \n\n > 👍️️️️ {self.cron_name} 测试通过 \n\n ' \
                                                f'> 😄 于 {self.recorded_first_failed_time[self.cron_name]} 发生的告警已恢复~ \n\n ' \
                                                f'> 过往报错报告id: {self.recorded_first_failed_report_id[self.cron_name]} \n\n' \
                                                f'> 最新生成报告id: {self.report_id} \n\n > ⬇️ 此时下方应有最新报告详情 '

                    if hasattr(self, 'enterprise_wechat_notify_strategy'):
                        enterprise_wechat_res = self.send_enterprise_wechat_notify(title=enterprise_wechat_title,
                                                                                   content=enterprise_wechat_content)
                        if not enterprise_wechat_res.status_code == 200:
                            raise BaseException('企业微信发送异常: {}'.format(enterprise_wechat_res.text))

                if is_send_ding_ding:
                    dingding_title = '### 接口测试平台钉钉服务'
                    dingding_content = f' ✅️ {project_name} 项目 \n\n > 👍️️️️ {self.cron_name} 测试通过 \n\n ' \
                                       f'> 😄 于 {self.recorded_first_failed_time[self.cron_name]} 发生的告警已恢复~ \n\n ' \
                                       f'> 过往报错报告id: {self.recorded_first_failed_report_id[self.cron_name]} \n\n' \
                                       f'> 最新生成报告id: {self.report_id}'

                    if hasattr(self, 'ding_ding_notify_strategy'):
                        dingding_res = self.send_ding_ding_notify(title=dingding_title, content=dingding_content)
                        if not dingding_res.status_code == 200:
                            raise BaseException('钉钉发送异常: {}'.format(dingding_res.text))

                mesg_title = '接口测试平台告警恢复提醒 :)'
                mesg_content = "Dears: \n\n 于 【{}】 【{}】 项目下 【{}】 测试任务 (报告 id: {}) 中报错测试用例已全部恢复通过~ 最新测试报告详情内容请查阅附件 ~ \n\n   最新报告 id 为:" \
                               " {} \n\n   最新报告生成时间为: {}" \
                    .format(self.recorded_first_failed_time[self.cron_name], project_name, self.cron_name,
                            self.recorded_first_failed_report_id[self.cron_name], self.report_id,
                            self.report_created_time.strftime('%Y-%m-%d %H:%M:%S'))
                mesg_attachment_name = f'接口测试报告_{self.report_created_time.strftime("%Y-%m-%d %H:%M:%S")}.xlsx'
                mesg_attachment_content = TestReport.get_test_report_excel_bytes_io(self.report_id).read()
                result_json = self.send_report_to_staff(project_id, self.alarm_mail_list, mesg_title, mesg_content,
                                                        mesg_attachment_name, mesg_attachment_content)
                if result_json.get('status') == 'failed':
                    raise BaseException('邮件发送异常: {}'.format(result_json.get('data')))

                self.stop_alert_and_wait_until_resume[self.cron_name] = False

            elif failed_again_but_wait_for_resume:
                # 在等待中且有失败的情况,暂时不做任何操作,防止使用者被不断的定时任务提醒轰炸
                print(f'failed_again_but_wait_for_resume, report_id: {self.report_id}')
            elif not self.stop_alert_and_wait_until_resume.get(self.cron_name):
                if self.failed_count > 0:
                    self.recorded_first_failed_report_id[self.cron_name] = copy.deepcopy(self.report_id)
                    date_now = str(datetime.datetime.now())
                    dot_index = date_now.rindex('.')
                    self.recorded_first_failed_time[self.cron_name] = date_now[:dot_index]
                    self.stop_alert_and_wait_until_resume[self.cron_name] = True if self.failed_count else False

                if is_send_enterprise_wechat:

                    enterprise_wechat_title = '### 接口测试平台企业微信服务'
                    enterprise_wechat_content = f' ⛔ {project_name} 项目 \n\n > 🚑 {self.cron_name} 测试失败 \n\n' \
                                                f' > 生成报告id: {self.report_id} \n\n > ⬇️ 此时下方应有报告详情 ' \
                        if self.failed_count > 0 else f' ✅️ {project_name} 项目 \n\n > 👍️️️️ {self.cron_name} 测试通过 \n\n ' \
                                                      f'> 生成报告id: {self.report_id} \n\n > ⬇️ 此时下方应有报告详情 '
                    if hasattr(self,
                               'enterprise_wechat_notify_strategy') and self.enterprise_wechat_notify_strategy.get(
                            'fail') \
                            and self.failed_count > 0:
                        enterprise_wechat_res = self.send_enterprise_wechat_notify(title=enterprise_wechat_title,
                                                                                   content=enterprise_wechat_content)
                        if not enterprise_wechat_res.status_code == 200:
                            raise BaseException('企业微信发送异常: {}'.format(enterprise_wechat_res.text))
                    if hasattr(self,
                               'enterprise_wechat_notify_strategy') and self.enterprise_wechat_notify_strategy.get(
                            'success') \
                            and self.failed_count <= 0:
                        enterprise_wechat_res = self.send_enterprise_wechat_notify(title=enterprise_wechat_title,
                                                                                   content=enterprise_wechat_content)
                        if not enterprise_wechat_res.status_code == 200:
                            raise BaseException('企业微信发送异常: {}'.format(enterprise_wechat_res.text))

                if is_send_ding_ding:
                    dingding_title = '### 接口测试平台钉钉服务'
                    dingding_content = f' ⛔ {project_name} 项目 \n\n > 🚑 {self.cron_name} 测试失败 \n\n' \
                                       f' > 生成报告id: {self.report_id}' \
                        if self.failed_count > 0 else f' ✅️ {project_name} 项目 \n\n > 👍️️️️ {self.cron_name} 测试通过 \n\n ' \
                                                      f'> 生成报告id: {self.report_id}'
                    if hasattr(self, 'ding_ding_notify_strategy') and self.ding_ding_notify_strategy.get('fail') \
                            and self.failed_count > 0:
                        dingding_res = self.send_ding_ding_notify(title=dingding_title, content=dingding_content)
                        if not dingding_res.status_code == 200:
                            raise BaseException('钉钉发送异常: {}'.format(dingding_res.text))
                    if hasattr(self, 'ding_ding_notify_strategy') and self.ding_ding_notify_strategy.get('success') \
                            and self.failed_count <= 0:
                        dingding_res = self.send_ding_ding_notify(title=dingding_title, content=dingding_content)
                        if not dingding_res.status_code == 200:
                            raise BaseException('钉钉发送异常: {}'.format(dingding_res.text))

                if is_send_mail:
                    mesg_title = '接口测试平台告警 :('
                    mesg_content = "Dears: \n\n  【{}】 项目下 【{}】 测试任务中存在未通过的测试用例!测试报告详情内容请查阅附件 ~ \n\n   报告 id 为:" \
                                   " {} \n\n   报告生成时间为: {}" \
                        .format(project_name, self.cron_name, self.report_id,
                                self.report_created_time.strftime('%Y-%m-%d %H:%M:%S'))
                    mesg_attachment_name = f'接口测试报告_{self.report_created_time.strftime("%Y-%m-%d %H:%M:%S")}.xlsx'
                    mesg_attachment_content = TestReport.get_test_report_excel_bytes_io(self.report_id).read()
                    result_json = self.send_report_to_staff(project_id, self.alarm_mail_list, mesg_title, mesg_content,
                                                            mesg_attachment_name, mesg_attachment_content)
                    if result_json.get('status') == 'failed':
                        raise BaseException('邮件发送异常: {}'.format(result_json.get('data')))
            else:
                pass