def report_detail(project_id, report_id): test_report = TestReport.find_one({'_id': ObjectId(report_id)}) test_report = common.format_response_in_dic(test_report) return jsonify({'status': 'ok', 'data': test_report}) if test_report else \ jsonify({'status': 'failed', 'data': '未找到报告详情'})
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
def get_project(project_id): res = Project.find_one({'_id': ObjectId(project_id)}) return jsonify({'status': 'ok', 'data': common.format_response_in_dic(res)})
def storage_detail(project_id, storage_id): storage = TestDataStorage.find_one({'_id': ObjectId(storage_id)}) storage = common.format_response_in_dic(storage) return jsonify({'status': 'ok', 'data': storage}) if storage else \ jsonify({'status': 'failed', 'data': '未找到测试数据仓库详情'})
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: enterprise_wechat_title = '智能测试平台企业微信服务' enterprise_wechat_content = '泰斯特平台 \n >⛔ 测试失败 \n > 生成报告id: {}'.format(self.report_id) \ if self.failed_count > 0 else '泰斯特平台 \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: 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 get_env_config(test_env_id): res = EnvConfig.find_one({'_id': ObjectId(test_env_id)}) return jsonify({'status': 'ok', 'data': common.format_response_in_dic(res)}) if res else \ jsonify({'status': 'failed', 'data': '未找到该envConfig信息'})
def start_api_test_by_case(): request_data = request.get_json() test_case_id_list = None execution_user = None execution_mode = None test_env_id = None if 'testEnvId' not in request_data: return jsonify({'status': 'failed', 'data': '尚未选择环境!'}) else: test_env_id = request_data["testEnvId"] if 'testCaseIdList' in request_data: test_case_id_list = request_data["testCaseIdList"] if not test_case_id_list or len(test_case_id_list) < 1: return jsonify({'status': 'failed', 'data': '请选择接口测试用例'}) if 'executionUser' in request_data: execution_user = request_data["executionUser"] if 'executionMode' in request_data: execution_mode = request_data["executionMode"] testing_case_list = [] for test_case_id in test_case_id_list: testing_case = TestCase.find_one({ '_id': ObjectId(test_case_id), 'isDeleted': { '$ne': True }, 'status': True }) if testing_case: testing_case_list.append( common.format_response_in_dic(testing_case)) if len(testing_case_list) < 1: 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) (env_name, protocol, domain) = get_env_name_and_domain(test_env_id) if not protocol or not domain or not env_name: return jsonify({'status': 'failed', 'data': '测试环境配置存在问题,请前往环境设置检查'}) global_env_vars = get_global_env_vars(test_env_id) execute_engine = ExecutionEngine(test_env_id=test_env_id, protocol=protocol, domain=domain, global_env_vars=global_env_vars) test_result_list = execute_engine.execute_manual_test_by_case( testing_case_list) try: for test_result in test_result_list: test_case_id = test_result["_id"] if execution_user: test_result['executionUser'] = execution_user test_result['env'] = env_name test_result = common.format_response_in_dic(test_result) TestCase.update({"_id": ObjectId(test_case_id)}, {'$set': { 'lastManualResult': test_result }}) return jsonify({'status': 'ok', 'data': "执行完毕"}) except BaseException as e: current_app.logger.error("start_api_test_by_case failed. - %s" % str(e)) return jsonify({'status': 'failed', 'data': "出错了 - %s" % e})
def test_case_detail(project_id, test_suite_id, test_case_id): res = TestCase.find_one({'_id': ObjectId(test_case_id)}) test_case = common.format_response_in_dic(res) return jsonify({'status': 'ok', 'data': test_case}) if test_case else \ jsonify({'status': 'failed', 'data': '未找到用例详情'})
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"] 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) 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), "testCount": test_count, "passCount": passed_count, "failedCount": failed_count, "passRate": passed_rate, "comeFrom": execution_mode, "executorNickName": executor_nick_name, "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 case_detail(project_id, case_suite_id, case_id): test_case = list(TestingCase.find({'_id': ObjectId(case_id)})) test_case = common.format_response_in_dic(test_case[0]) return jsonify({'status': 'ok', 'data': test_case}) if test_case else \ jsonify({'status': 'failed', 'data': '未找到用例详情'})
def get_project_suite(project_id, test_suite_id): res = TestSuite.find_one({'_id': ObjectId(test_suite_id)}) return jsonify({ 'status': 'ok', 'data': common.format_response_in_dic(res) })