def cron_mission(self): 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"] else: raise TypeError('定时任务执行中未找到任何可执行用例!') tester_for_cron = tester(test_case_list=cron_test_cases_list, domain=self.test_domain) test_result_list = tester_for_cron.execute_all_test_for_cron_and_single_test( ) 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 len(test_result_list) > 0: self.generate_test_report(project_id, self.get_id(), test_result_list) 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 if is_send_ding_ding: dingding_title = '智能测试平台钉钉服务' dingding_content = '### ⛔️ 泰斯特平台 \n >⛔ 测试失败 \n > 生成报告id: {}'.format(self.report_id)\ if self.failed_count > 0 else '### ✅️ 泰斯特平台 \n >👍️️️️ 测试通过 \n > 生成报告id: {}'\ .format(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 报告编号为:" \ " {} \n\n 报告生成时间为: {}"\ .format(self.report_id, self.report_created_time.strftime('%Y-%m-%d %H:%M:%S')) result_json = self.send_report_to_staff( project_id, self.alarm_mail_list, mesg_title, mesg_content) if result_json.get('status') == 'failed': raise BaseException('邮件发送异常: {}'.format( result_json.get('data'))) else: raise TypeError('无任何测试结果!')
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})
def cron_mission(self): 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"] else: raise TypeError('定时任务执行中未找到任何可执行用例!') tester_for_cron = tester(test_case_list=cron_test_cases_list, domain=self.test_domain) test_result_list = tester_for_cron.execute_all_test_for_cron_and_single_test() 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 len(test_result_list) > 0: self.generate_test_report(project_id, self.get_id(), test_result_list) 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 if is_send_enterprise_wechat: """发送企业微信群消息 1. 创建企业微信-群机器人 2. 在添加机器人时,设置【自定义关键字】为下面的enterprise_wechat_title """ enterprise_wechat_title = 'SeeYou测试平台' enterprise_wechat_content = 'SeeYou平台 \n >⛔ 测试失败 \n > 生成报告id: {}'.format(self.report_id) \ if self.failed_count > 0 else 'SeeYou平台 \n >👍️️️️ 测试通过 \n > 生成报告id: {}' \ .format(self.report_id) # 发送失败 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: """发送钉钉群消息 1. 进入https://oa.dingtalk.com/ 钉钉开发平台注册团队群 2. 在群里创建钉钉-群机器人 3. 在添加机器人时,设置【自定义关键字】为下面的dingding_title """ dingding_title = 'SeeYou测试平台' dingding_content = '### ⛔️ SeeYou平台 \n >⛔ 测试失败 \n > 生成报告id: {}'.format(self.report_id) \ if self.failed_count > 0 else '### ✅️ SeeYou平台 \n >👍️️️️ 测试通过 \n > 生成报告id: {}' \ .format(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) print('执行失败,发送钉钉消息', dingding_res) 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) print('执行成功,发送钉钉消息', dingding_res) 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 报告编号为:" \ " {} \n\n 报告生成时间为: {}" \ .format(self.report_id, self.report_created_time.strftime('%Y-%m-%d %H:%M:%S')) # 发送成功 result_json = self.send_report_to_staff(project_id, self.alarm_mail_list, mesg_title, mesg_content) # 发送失败 if result_json.get('status') == 'failed': raise BaseException('邮件发送异常: {}'.format(result_json.get('data'))) else: raise TypeError('无任何测试结果!')
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