def login(self):
     """
     触发登录接口请求并XX业务请求令牌Token值
     :return:
     """
     logger.info('[Start]:开始请求登录XX业务{}环境后台服务...'.format(self.env))
     login_res = RequestTool().post(url=self.login_url,
                                    headers={"Content-Type": "application/json;charset=UTF-8"},
                                    data=json.dumps(
                                        {"username": "******".format(self.username),
                                         "password": "******".format(encrypt.MD5(self.password)),
                                         "verificationCode": "{}".format(self.validcode),
                                         "code": "hlwyy",
                                         "userType": 3, "token": ""}),
                                    verify=True)
     response_str = login_res.text.split("\"")[1]
     # response_str = login_res.text
     decrypt_login_res = ResponseDecrypt(response_str=response_str).decrypt()
     decrypt_login_res = re.sub(r"\n|\t|\r|\r\n|\n\r|\x08|\\", "", decrypt_login_res)
     login_res_dict = json.loads(decrypt_login_res)
     if login_res_dict.get("err") == 0 and login_res_dict.get("errmsg") == '操作成功':
         self.token = login_res_dict['data']['token']
         logger.info('[Success]:XX业务{}环境后台服务登录成功, 请求令牌Token值为: {}'.format(self.env, self.token))
         return self
     else:
         logger.warning(
             "[WARNING]:XX业务{}环境后台服务登录失败,接口响应为【{}】,重试登录中...".format(self.env, login_res_dict))
         sys.exit(1)
Exemplo n.º 2
0
 def check_duplicate_urlpath(self):
     """
     检测映射接口文档中匹配的UrlPath是否存在重复值
     :return:
     """
     pass_flag = False
     try:
         if self.check_exist_urlpath is True:
             case_doc_urlpath_veriry = {
                 i: j
                 for i, j in dict(
                     Counter([
                         str(i).strip() for i in
                         self.case_doc_df["UrlPath"].values.tolist()
                     ])).items() if j > 1
             }
             if case_doc_urlpath_veriry == {}:
                 logger.info(
                     "[Success]:映射接口文档中匹配的UrlPath是否存在重复值检测通过,其匹配的UrlPath均唯一."
                 )
                 return True
             if case_doc_urlpath_veriry != {}:
                 logger.warning(
                     '[WARNING]:检测到映射接口文档中存在重复的UrlPath,检测结果:{},请仔细核对并明确需求!'.
                     format(case_doc_urlpath_veriry))
                 pass_flag = False
             return pass_flag
         else:
             logger.error(
                 "[Fail]:Swagger接口文档与接口抓包文档进行UrlPath数据匹配检测失败,请仔细检查相关文档数据!")
             sys.exit(1)
     except Exception:
         logger.exception(
             "[Exception]:检测映射接口文档中匹配的UrlPath是否存在重复值过程中发生异常,请检查!")
         return False
Exemplo n.º 3
0
 def check_match_urlpath(self):
     """
     检测接口抓包文档与映射接口文档中匹配的UrlPath是否存在一一映射匹配关系
     :return:
     """
     try:
         case_doc_df_count = self.case_doc_df.shape[0]
         capture_doc_df_count = self.capture_doc_cid_check.__len__()
         if case_doc_df_count < capture_doc_df_count:
             swagger_doc_less_set = set([
                 str(i).strip()
                 for i in self.capture_doc_df["CID"].values.tolist()
             ]) - set([
                 str(i).strip()
                 for i in self.case_doc_df["UrlPath"].values.tolist()
             ])
             logger.warning(
                 "[WARNING]:检测到映射接口文档中缺少接口抓包文档中映射匹配的UrlPath,检测结果:{},请检查相关接口文档是否符合需求或手动追加!"
                 .format(swagger_doc_less_set))
             return False
         if case_doc_df_count == capture_doc_df_count:
             logger.info(
                 "[Success]:映射接口文档与接口抓包文档中UrlPath一一映射匹配关系检测通过,二者存在一一映射匹配的UrlPath."
             )
             return True
     except Exception:
         logger.exception(
             "[Exception]:检测映射接口文档与接口抓包文档进行UrlPath一一映射匹配关系过程中发生异常,请检查!")
         return False
Exemplo n.º 4
0
 def __init__(self, swagger_api_file, capture_api_file):
     """
     初始化指定Swagger接口文档和接口抓包文档
     :param swagger_api_file: Swagger接口文档(Excel文件)
     :param capture_api_file: 接口抓包文档(如Charles、Fiddler或微信开发者工具完成抓包并同步文档)
     """
     if os.path.exists(swagger_api_file):
         if os.path.exists(capture_api_file):
             self.swagger_doc_df = DataframeOperation(
                 test_case_file=swagger_api_file).df.rename(
                     columns={"ID": "AID"})
             self.capture_doc_df = DataframeOperation(
                 test_case_file=capture_api_file).df.rename(columns={
                     "ID": "CID"
                 }).sort_values(by=["Group", "CID"], ascending=True)
             self.capture_doc_cid_check = [
                 str(i).strip() for i in list(
                     dict(
                         self.capture_doc_df.groupby(
                             ["CID"], sort=True).groups).keys()) if i != ''
             ]
             self.case_doc_df = self.swagger_doc_df.loc[
                 self.swagger_doc_df["UrlPath"].isin(
                     self.capture_doc_cid_check)].sort_values(
                         by="UrlPath", ascending=True)
         else:
             logger.warning(
                 '[WARNING]:接口抓包文档"{}"当前并不存在,请先完成相关接口抓包操作!'.format(
                     capture_api_file))
             sys.exit(1)
     else:
         logger.warning(
             '[WARNING]:Swagger接口文档"{}"当前并不存在,请先完成接口文档生成操作!'.format(
                 swagger_api_file))
         sys.exit(1)
Exemplo n.º 5
0
 def check_exist_urlpath(self):
     """
     检测接口抓包文档在Swagger接口文档中是否存在匹配的UrlPath
     :return:
     """
     try:
         if self.capture_doc_df["CID"].shape[
                 0] == 0 or self.capture_doc_cid_check == []:
             logger.warning(
                 "[WARNING]:接口抓包文档中UrlPath当前无任何填充数据,请首先完成接口抓包工作!")
             sys.exit(1)
         if self.case_doc_df["UrlPath"].shape[0] == 0:
             logger.warning(
                 "[WARNING]:接口抓包文档中UrlPath在Swagger接口文档中未匹配到任何数据,请检查接口抓包文档和Swagger接口文档是否符合需求!"
             )
             return False
         if self.case_doc_df["UrlPath"].shape[
                 0] != 0 and self.capture_doc_df["CID"].shape[0] != 0:
             logger.info(
                 "[Success]:Swagger接口文档及接口抓包文档中UrlPath是否存在匹配数据检测通过,二者UrlPath存在匹配数据."
             )
             return True
     except Exception:
         logger.exception(
             "[Exception]:检测接口抓包文档中UrlPath在Swagger接口文档中是否存在匹配数据过程中发生异常,请检查!"
         )
         return False
Exemplo n.º 6
0
 def check_match_urlpath(self):
     """
     检测Swagger接口文档与接口抓包文档中的UrlPath是否映射匹配
     :return:
     """
     try:
         case_doc_df_count = self.case_doc_df.shape[0]
         capture_doc_df_count = self.capture_doc_df.shape[0]
         if case_doc_df_count == 0:
             logger.warning(
                 "[WARNING]:检测到Swagger接口文档中无任何映射匹配的UrlPath,请检查相关接口文档是否符合需求或手动追加!"
             )
             return False
         if case_doc_df_count < capture_doc_df_count:
             swagger_doc_less_set = set([
                 str(i).strip()
                 for i in self.capture_doc_df["CID"].values.tolist()
             ]) - set([
                 str(i).strip()
                 for i in self.case_doc_df["UrlPath"].values.tolist()
             ])
             logger.warning(
                 "[WARNING]:检测到Swagger接口文档中缺少映射匹配的UrlPath,检测结果:{},请检查相关接口文档是否符合需求或手动追加!"
                 .format(swagger_doc_less_set))
             return False
         if case_doc_df_count == capture_doc_df_count:
             logger.info(
                 "[Success]:Swagger接口文档与接口抓包文档中UrlPath映射匹配规则检测通过,二者存在数量相等且映射匹配的UrlPath."
             )
             return True
     except Exception:
         logger.exception(
             "[Exception]:检测Swagger接口文档与接口抓包文档进行UrlPath映射匹配规则过程中发生异常,请检查!")
         return False
Exemplo n.º 7
0
 def __init__(self, dbtype, env, dbname=None):
     """
     指定数据库类型、所处环境及数据库名称
     :param dbtype: 数据库类型(当前支持mysql/redis/mongodb)
     :param env: 所处环境
     :param dbname: 数据库名称
     """
     try:
         if str(dbtype).lower() not in [r'mysql', r'redis', r'mongodb']:
             raise DatabaseTypeError
         if str(env).lower() not in [r'test', r'stg', r'dev', r'qa']:
             raise EnvironmentTypeError
         else:
             self.dbtype = str(dbtype).lower()
             self.env = str(env).lower()
             self.dbname = dbname
     except DatabaseTypeError:
         logger.warning(
             '[WARNING]:检测到非法或不支持的数据库类型"{}",当前仅支持[mysql, redis, mongodb]'.
             format(dbtype))
         sys.exit(1)
     except EnvironmentTypeError:
         logger.warning(
             '[WARNING]:检测到非法或不支持的测试环境"{}",当前仅支持[test, stg, dev, qa]'.
             format(env))
         sys.exit(1)
Exemplo n.º 8
0
 def send(self, msgtype):
     """
     发送钉钉机器人消息提醒
     :param msgtype: 消息提醒类型
     :return:
     """
     try:
         if msgtype not in [
                 'text', 'link', 'markdown', 'actionCard', 'feedCard'
         ]:
             logger.warning(
                 '[WARNING]:检测到非法消息类型"{}",当前仅支持text、link、markdown、actionCard、feedCard,请重新指定!'
                 .format(msgtype))
             sys.exit(1)
         url = "https://oapi.dingtalk.com/robot/send?access_token={}&timestamp={}&sign={}".format(
             self.token, self.timestamp, self.get_sign)
         headers = {'Content-Type': 'application/json'}
         response = requests.request("POST",
                                     url,
                                     headers=headers,
                                     data=self.generate_msg(msgtype))
         result = response.json()
         if result.get("errcode") == 0 and result.get("errmsg") == 'ok':
             logger.info("[Done]:钉钉机器人消息提醒成功.")
         else:
             logger.warning(
                 "[WARNING]:钉钉机器人消息提醒失败,接口响应为【{}】,开始重试...".format(result))
             sys.exit(1)
     except Exception:
         logger.exception("[Exception]:发送钉钉机器人消息提醒过程中发生异常,请检查!")
         sys.exit(1)
Exemplo n.º 9
0
 def __init__(self, env, dbname, auth_dict=None):
     """
     指定所处环境及数据库名称
     :param env: 所处环境
     :param dbname: 数据库名称
     :param auth_dict: 授权字典,样例格式为{"auth_db":"admin", "auth_username":"******", "auth_password":"******"}
     """
     mongodbParam = YamlConfig(config=APPLICATION_CONFIG_FILE).get(
         "mongodb", 1).get(env)
     self.mongodb = MongoClient(host=mongodbParam['host'],
                                port=mongodbParam['port'])
     if not mongodbParam.__contains__("auth") and auth_dict is None:
         logger.warning("请在应用配置文件中指定MongoDB授权信息,或者通过auth_dict字典进行指定!")
         sys.exit(1)
     if auth_dict is not None:
         if isinstance(auth_dict, dict):
             auth_db = auth_dict.get("auth_db")
             auth_username = auth_dict.get("auth_username")
             auth_password = str(auth_dict.get("auth_password"))
             auth = eval("self.mongodb.{}".format(auth_db))
             auth.authenticate(auth_username, auth_password)
             self.db_client = eval("self.mongodb.{}".format(dbname))
         else:
             logger.warning("auth_dict授权信息必须为字典形式,请检查!")
             sys.exit(1)
     if auth_dict is None and mongodbParam.__contains__("auth"):
         mongodbAuth = mongodbParam.get("auth")
         auth_db = mongodbAuth.get("db")
         auth_username = mongodbAuth.get("username")
         auth_password = str(mongodbAuth.get("password"))
         auth = eval("self.mongodb.{}".format(auth_db))
         auth.authenticate(auth_username, auth_password)
         self.db_client = eval("self.mongodb.{}".format(dbname))
Exemplo n.º 10
0
 def generate(self, test_case_file, sep=r'|', encoding='utf-8'):
     """
     生成测试用例文件(当前支持Excel文件[xls/xlsx]及文本文件[csv/txt])
     :param test_case_file: 测试用例文件路径
     :param sep: 文件分隔符,默认"|"。
     :param encoding: 文件编码格式。
     :return:
     """
     logger.info("[Initial]:开始自动评估测试用例生成条件......")
     file_extend = str(os.path.splitext(test_case_file)[-1]).lower()
     try:
         test_case_df = self.load_test_case
         if file_extend not in [".csv", ".txt", ".xls", ".xlsx"]:
             logger.warning(
                 "[WARNING]:自动生成的测试用例文件扩展名当前仅支持[csv、txt、xls、xlsx],请检查!")
             sys.exit(1)
         if file_extend in ['.xls', '.xlsx']:
             logger.info(
                 "[Loading]:开始自动生成{}格式测试用例文件......".format(file_extend))
             test_case_df.to_excel(test_case_file, index=False)
         if file_extend in ['.csv', '.txt']:
             logger.info(
                 "[Loading]:开始自动生成{}格式测试用例文件......".format(file_extend))
             test_case_df.to_csv(test_case_file,
                                 sep=sep,
                                 index=False,
                                 header=True,
                                 encoding=encoding)
         logger.info('[Done]:{}格式测试用例文件已经成功自动生成,路径为"{}".'.format(
             file_extend, test_case_file))
     except Exception:
         logger.exception(
             "[Exception]: {}格式测试用例文件自动生成过程中发生异常,请检查!".format(file_extend))
         sys.exit(1)
Exemplo n.º 11
0
 def load_test_case(self):
     """
     依据swagger接口文档及接口抓包文档生成测试用例
     :return:
     """
     try:
         if self.check_duplicate_urlpath is True:
             if self.check_match_urlpath is True:
                 self.case_doc_df["Platform"] = [
                     str(platform).strip().capitalize() for platform in
                     self.capture_doc_df["Platform"].values.tolist()
                 ]
                 self.case_doc_df["Level"] = [
                     str(level).strip().upper() for level in
                     self.capture_doc_df["Level"].values.tolist()
                 ]
                 self.case_doc_df["Active"] = True
                 self.case_doc_df["Group"] = self.capture_doc_df[
                     "Group"].values.tolist()
                 self.case_doc_df["Order"] = self.capture_doc_df[
                     "Order"].values.tolist()
                 self.case_doc_df["RequestPath"] = self.capture_doc_df[
                     "Path"].values.tolist()
                 self.case_doc_df["RequestHeader"] = self.capture_doc_df[
                     "Header"].values.tolist()
                 self.case_doc_df["RequestParam"] = self.capture_doc_df[
                     "Param"].values.tolist()
                 self.case_doc_df["RequestData"] = self.capture_doc_df[
                     "Data"].values.tolist()
                 self.case_doc_df["RequestFile"] = self.capture_doc_df[
                     "File"].values.tolist()
                 self.case_doc_df["DependencyInfo"] = self.capture_doc_df[
                     "Dependency"].values.tolist()
                 self.case_doc_df["AssertInfo"] = self.capture_doc_df[
                     "Assert"].values.tolist()
                 self.case_doc_df = self.case_doc_df.sort_values(
                     by="Order", ascending=True)
                 self.case_doc_df = self.case_doc_df.reset_index(
                     drop=True).reset_index().rename(
                         columns={"index": "ID"})
                 self.case_doc_df["ID"] = self.case_doc_df["ID"].apply(
                     lambda x: "TC_{}".format(x + 1))
                 return self.case_doc_df
             else:
                 logger.warning(
                     "[WARNING]:Swagger接口文档与接口抓包文档中UrlPath映射匹配规则检测未通过,请查看相关检测结果!"
                 )
                 sys.exit(1)
         else:
             logger.warning(
                 "[WARNING]:Swagger接口文档或接口抓包文档中各自UrlPath列是否存在重复值检测未通过,请查看相关检测结果!"
             )
             sys.exit(1)
     except Exception:
         logger.exception(
             "[Exception]:依据Swagger接口文档及接口抓包文档自动生成测试用例过程中发生异常,请检查!")
         sys.exit(1)
 def get_token(self):
     """
     获取请求令牌Token值
     :return:
     """
     if self.token is None:
         logger.warning("[WARNING]:检查到XX业务{}环境后台服务请求令牌Token值为空, 请先登录!".format(self.env))
         sys.exit(1)
     return self.token
Exemplo n.º 13
0
 def get_job_info(self, job_name):
     """
     获取构建项目信息
     :param job_name: 构建项目名称
     :return:
     """
     try:
         if self.session.job_exists(name=job_name):
             info = self.session.get_job_info(name=job_name)
             return info
         else:
             logger.warning(
                 '[WARNING]: Jenkins构建项目"{}"并不存在,请检查!'.format(job_name))
             sys.exit(1)
     except Exception:
         logger.exception('查看Jenkins构建项目"{}"过程中发生异常,请检查!'.format(job_name))
Exemplo n.º 14
0
 def write_column(self, col, value, style="black"):
     """
     整列赋值并设置字体颜色。
     :param col: 列索引
     :param value: 赋值
     :param style: 字体颜色样式(默认黑色)
     :return:
     """
     if str(style).lower() not in [
             "orange", "green", "red", "boldorange", "gray", "black"
     ]:
         logger.warning(
             '当前字体样式不支持"{}"颜色,请选择如下字体颜色["orange", "green", "red", "boldorange","gray", "black"]'
             .format(style))
     for row in range(1, self.row_count):
         self.write(row, col, value, style)
     return self
Exemplo n.º 15
0
 def generate_report(cls):
     """
     根据json结果文件自动生成Allure测试报告。
     """
     try:
         if cls.check_result() is True:
             command = "allure generate {0} -o {1} --clean".format(ALLURE_RESULT, ALLURE_REPORT)
             time.sleep(1)
             logger.info('开始执行Allure测试报告生成命令:"{}"'.format(command))
             run_command(command)
             logger.info("[Done]:已经成功生成Allure测试报告.")
         else:
             logger.warning("[Warning]:由于未检测到Allure测试结果json文件,停止生成Allure测试报告!")
     except CalledProcessError:
         logger.exception("[Exception]:Allure测试报告生成命令执行失败!")
     except Exception:
         logger.exception("[Exception]:生成Allure测试报告过程中发生异常,请检查!")
Exemplo n.º 16
0
 def write(self, row, col, value, style="black"):
     """
     写入单元格并设置字体颜色。
     :param row: 行索引
     :param col: 列索引
     :param value: 赋值
     :param style: 字体颜色样式(默认黑色)
     :return:
     """
     if str(style).lower() not in [
             "orange", "green", "red", "boldorange", "gray", "black"
     ]:
         logger.warning(
             '当前字体样式不支持"{}"颜色,请选择如下字体颜色["orange", "green", "red", "boldorange", "gray", "black"]'
             .format(style))
     self.w.write(row, col, value, self.__STYLE_DICT.get(style))
     return self
Exemplo n.º 17
0
 def generate_msg(self, msgtype):
     """
     构造钉钉机器人消息体
     :param msgtype: 消息提醒类型(当前仅支持Text/Link/MarkDown/ActionCard/FeedCard)
     :return:
     """
     try:
         if msgtype == 'text':
             return json.dumps(self.ding.get('text'))
         if msgtype == 'link':
             return json.dumps(self.ding.get('link'))
         if msgtype == 'markdown':
             return json.dumps(self.ding.get('markdown'))
         if msgtype == 'actionCard':
             return json.dumps(self.ding.get('actionCard'))
         if msgtype == 'feedCard':
             return json.dumps(self.ding.get('feedCard'))
     except Exception:
         logger.warning("[WARNING]:构造钉钉机器人消息体过程中发生异常,请检查!")
Exemplo n.º 18
0
 def write_column(self, col, value, style="black"):
     """
     整列赋值并设置字体颜色。
     :param col: 列索引
     :param value: 赋值
     :param style: 字体颜色样式(默认黑色)
     :return:
     """
     if str(style).lower() not in [
             "orange", "green", "red", "boldorange", "gray", "black"
     ]:
         logger.warning(
             '当前字体样式不支持"{}"颜色,请选择如下字体颜色["orange", "green", "red", "boldorange","gray", "black"]'
             .format(style))
     for row in range(2, self.row_count + 1):
         self.sheet_reader.cell(row, col + 1).value = value
         self.sheet_reader.cell(row,
                                col + 1).font = self.__STYLE_DICT[style]
     return self
Exemplo n.º 19
0
    def __init__(self, swagger_doc_urls, swagger_domain_urls=None):
        """
        初始化Swagger接口文档。
        :param swagger_doc_urls: Swagger接口地址, 必须使用";"分隔。
        :param swagger_domain_urls: Swagger接口域名, 必须使用";"分隔。
        """
        # Swagger接口文档地址列表
        swagger_doc_url_list = [
            swagger_doc_url.strip()
            for swagger_doc_url in str(swagger_doc_urls).split(";")
            if swagger_doc_url != ""
        ]
        self.swagger_protocols = [
            swagger_doc_url.split(":")[0]
            for swagger_doc_url in swagger_doc_url_list
        ]
        self.swagger_domain_url_list = [
            swagger_domain.strip()
            for swagger_domain in str(swagger_domain_urls).split(";")
            if swagger_domain != ""
        ] if swagger_domain_urls is not None else swagger_domain_urls
        if isinstance(self.swagger_domain_url_list, list):
            if self.swagger_domain_url_list.__len__(
            ) < swagger_doc_url_list.__len__():
                logger.warning(
                    "[Warning]:当前配置文件中已有的Swagger替换域名少于Swagger接口文档地址列表,请检查并明确域名替换规则![当前会默认启用首个域名替换全部Swagger请求域]"
                )
                self.swagger_domain_url_list = [
                    self.swagger_domain_url_list[0]
                    for count in range(swagger_doc_url_list.__len__())
                ]

        # JSON样式Swagger接口文档列表
        self.swagger_res_dict_list = []
        try:
            session = requests.session()
            for swagger_doc_url in swagger_doc_url_list:
                swagger_res = session.get(url=swagger_doc_url)
                self.swagger_res_dict_list.append(json.loads(swagger_res.text))
        except Exception:
            logger.exception("[Exception]: 请求Swagger过程中发生异常,请检查网络或服务状态!")
            sys.exit(1)
Exemplo n.º 20
0
 def sync_history(cls):
     """
     追加Allure历史追溯信息
     :return:
     """
     ALLURE_REPORT_HISTORY = os.path.join(ALLURE_REPORT, "history")
     ALLURE_RESULT_HISTORY = os.path.join(ALLURE_RESULT, "history")
     try:
         if os.path.exists(ALLURE_RESULT_HISTORY):
             raise FileExistsError
         if os.path.exists(ALLURE_REPORT_HISTORY):
             time.sleep(1)
             shutil.copytree(ALLURE_REPORT_HISTORY, ALLURE_RESULT_HISTORY)
             logger.info("[Success]:已经成功同步Allure历史追溯信息.")
         else:
             logger.warning('[WARNING]:Allure历史追溯信息"{}"当前并不存在,无法完成同步!'.format(ALLURE_REPORT_HISTORY))
     except FileExistsError:
         logger.exception('[Exception]:已同步Allure历史追溯信息至"{}",无需再次同步!'.format(ALLURE_RESULT_HISTORY))
     except Exception:
         logger.exception("[Exception]:同步Allure历史追溯信息过程中发生异常,请检查!")
Exemplo n.º 21
0
 def get_swagger_to_excel(self, file_path):
     """
     根据Swagger生成Excel接口文档。
     :param file_path: Excel文件路径。
     :return:
     """
     try:
         if str(os.path.splitext(file_path)[-1]).lower() not in [
                 ".xls", ".xlsx"
         ]:
             logger.warning("[WARNING]:生成的Excel文件扩展名必须为xls或xlsx格式,请检查!")
             sys.exit(1)
         logger.info("[Initial]:开始通过Swagger转换生成Excel接口文档[依赖环境配置]......")
         swagger_dataframe = self.get_swagger_to_dataframe
         swagger_dataframe.to_excel(file_path, index=False)
         logger.info(
             '[Done]:已通过Swagger成功转换生成Excel接口文档,路径为"{}".'.format(file_path))
     except Exception:
         logger.exception("[Exception]: 通过Swagger生成Excel接口文档失败,请检查原因!")
         sys.exit(1)
Exemplo n.º 22
0
 def check_result(cls, check_count=CHECK_COUNT):
     """
     检查Allure测试结果json文件是否生成。
     :param check_count: 检测次数。
     :return:
     """
     check_result = None
     for count in range(check_count):
         if os.listdir(ALLURE_RESULT) == list() and count < check_count:
             if count == check_count - 1:
                 logger.warning("仍未检测到Allure测试结果json文件,已达检测次数上限({}),停止检测。".format(check_count))
                 check_result = False
                 break
             logger.info("未检测到Allure测试结果json文件,可能正在生成......")
             time.sleep(2)
             continue
         if os.listdir(ALLURE_RESULT) != list():
             logger.info("[Success]:已检测到Allure测试结果json文件.")
             check_result = True
             break
     return check_result
Exemplo n.º 23
0
 def check_empty_urlpath(self):
     """
     检查Swagger接口文档及接口抓包文档中UrlPath是否全部填充
     :return:
     """
     try:
         if self.swagger_doc_df["UrlPath"].shape[
                 0] == 0 or self.capture_doc_df["CID"].shape[0] == 0:
             logger.warning(
                 "[WARNING]:Swagger接口文档或接口抓包文档中UrlPath列当前无任何填充数据,请检查并完全填充相关数据!"
             )
             return False
         if self.swagger_doc_df["UrlPath"].shape[
                 0] != 0 and self.capture_doc_df["CID"].shape[0] != 0:
             logger.info(
                 "[Success]:Swagger接口文档及接口抓包文档中UrlPath列完全填充状态检测通过,二者UrlPath列均已填充完全."
             )
             return True
     except Exception:
         logger.exception(
             "[Exception]:检测Swagger接口文档及接口抓包文档中UrlPath列是否完全填充过程中发生异常,请检查!")
         return False
Exemplo n.º 24
0
 def __init__(self, ding_notify_file, preview_mode=False):
     """
     从应用配置文件获取钉钉请求token及签名secret
     :param ding_notify_file: 钉钉消息模板文件
     :param preview_mode: 测试报告截图预览
     """
     try:
         DingTools.__init__(self)
         if not os.path.exists(ding_notify_file):
             raise FileNotFoundError
         with open(file=ding_notify_file, mode=r'r',
                   encoding='utf-8') as ding_file:
             if preview_mode is False:
                 self.ding = json.loads(ding_file.read().replace(
                     "ip_address",
                     get_ip()).replace("![Allure](report_url)",
                                       ">      🐾🐾🐾 ~ {}".format(get_ip())))
             else:
                 self.ding = json.loads(ding_file.read().replace(
                     "ip_address", get_ip()).replace(
                         "report_url",
                         face_bed(pic=capture_image(
                             width=1440,
                             height=797,
                             url="http://localhost:5000/allure",
                             sleep=10,
                             pic=os.path.join(RESOURCE_PATH, "Allure",
                                              "Allure.png")),
                                  alias="Allure.png")))
         self.token = YamlConfig(
             config=APPLICATION_CONFIG_FILE).get("ding")["token"]
         self.secret = YamlConfig(
             config=APPLICATION_CONFIG_FILE).get("ding")["secret"]
         self.timestamp = str(round(time.time() * 1000))
     except FileNotFoundError:
         logger.warning(
             '[WARNING]:钉钉消息通知模板文件"{}"当前并不存在,请检查!'.format(ding_notify_file))
         sys.exit(1)
Exemplo n.º 25
0
 def send(self, message='FYI', image_flag=False, *filepath):
     '''
     触发邮件发送
     :param message: 邮件文本信息
     :param image_flag: 是否发送图片
     :param filepath: 邮件附件元组
     :return:
     '''
     self.message = message
     self.image_flag = image_flag
     for p in filepath:
         if os.path.isdir(p):
             self.files = list()
             for f in os.listdir(p):
                 self.files.append(os.path.join(p, f))
             self.checkAtType(self.files)
         elif os.path.isfile(p):
             self.files = p
             self.checkAtType(self.files)
         else:
             self.files = p
             filename = re.split(r'[\\|/]', str(p))[-1]
             logger.warning('注意! 邮件附件"{0}"的路径"{1}"可能无效, 附件无法上传.'.
                            format(filename, p))
     try:
         logger.info("开始发送测试结果邮件......")
         session = self.createSession()
         session.sendmail(self.sender,
                          self.receiver.split(';'),
                          self.build_all_msg().as_string() if self.image_flag else self.build_html_msg().as_string()
                          )
     except (gaierror and error):
         logger.exception('邮件发送失败! ~ 无法连接到SMTP服务器, 请检查网络以及邮件配置.')
     else:
         logger.info('[Done]:{0}邮件发送成功! 收件人:{1}.'.format(self.title, self.receiver))
         session.quit()
         session.close()
Exemplo n.º 26
0
 def get_swagger_to_csv(self, file_path, sep=r',', encoding='utf-8'):
     """
     根据Swagger生成CSV接口文档。
     :param file_path: CSV文件路径。
     :param sep: 文件分隔符,默认","。
     :param encoding: 文件编码格式。
     :return:
     """
     try:
         if str(os.path.splitext(file_path)[-1]).lower() != 'csv':
             logger.warning("[WARNING]:生成的CSV文件扩展名必须为csv格式,请检查!")
             sys.exit(1)
         logger.info("[Initial]:开始通过Swagger转换生成CSV接口文档[依赖环境配置]......")
         swagger_dataframe = self.get_swagger_to_dataframe
         swagger_dataframe.to_csv(file_path,
                                  sep=sep,
                                  index=False,
                                  header=True,
                                  encoding=encoding)
         logger.info(
             '[Done]:已通过Swagger成功转换生成CSV接口文档,路径为"{}".'.format(file_path))
     except Exception:
         logger.exception("[Exception]: 通过Swagger生成CSV接口文档失败,请检查原因!")
         sys.exit(1)
Exemplo n.º 27
0
 def send(self, message):
     """
     发送钉钉机器人消息提醒
     :param message: 消息提醒
     :return:
     """
     try:
         if not isinstance(message, dict):
             logger.warning("[WARNING]:参数message必须以字典形式入参,请检查!")
             sys.exit(1)
         if not message.__contains__('msgtype'):
             logger.warning("[WARNING]:消息体message必须包含消息类型msgtype,请检查!")
             sys.exit(1)
         if message.get('msgtype') not in [
                 'text', 'link', 'markdown', 'actionCard', 'feedCard'
         ]:
             logger.warning(
                 '[WARNING]:检测到非法消息类型"{}",当前仅支持text、link、markdown、actionCard、feedCard,请重新指定!'
                 .format(message.get('msgtype')))
             sys.exit(1)
         url = "https://oapi.dingtalk.com/robot/send?access_token={}&timestamp={}&sign={}".format(
             self.token, self.timestamp, self.get_sign)
         headers = {'Content-Type': 'application/json'}
         response = requests.request("POST",
                                     url,
                                     headers=headers,
                                     data=json.dumps(message))
         result = response.json()
         if result.get("errcode") == 0 and result.get("errmsg") == 'ok':
             logger.info("[Done]:『{}』钉钉机器人消息提醒成功.".format(self.alias))
         else:
             logger.warning(
                 "[WARNING]:『{}』钉钉机器人消息提醒失败,接口响应为【{}】,开始重试...".format(
                     self.alias, result))
             sys.exit(1)
     except Exception:
         logger.exception("[Exception]:『{}』发送钉钉机器人消息提醒过程中发生异常,请检查!".format(
             self.alias))
         sys.exit(1)
Exemplo n.º 28
0
 def check_duplicate_urlpath(self):
     """
     检查Swagger接口文档及接口抓包文档中是否存在重复的UrlPath.
     :return:
     """
     pass_flag = False
     try:
         if self.check_empty_urlpath is True:
             swagger_doc_urlpath_veriry = {
                 i: j
                 for i, j in dict(
                     Counter([
                         str(i).strip() for i in
                         self.swagger_doc_df["UrlPath"].values.tolist()
                     ])).items() if j > 1
             }
             capture_doc_urlpath_veriry = {
                 i: j
                 for i, j in dict(
                     Counter([
                         str(i).strip() for i in
                         self.capture_doc_df["CID"].values.tolist()
                     ])).items() if j > 1
             }
             if swagger_doc_urlpath_veriry == {} and capture_doc_urlpath_veriry == {}:
                 logger.info(
                     "[Success]:Swagger接口文档或接口抓包文档中各自UrlPath列是否存在重复值检测通过,二者各自UrlPath列均无重复值."
                 )
                 return True
             if swagger_doc_urlpath_veriry != {}:
                 logger.warning(
                     '[WARNING]:检测到Swagger接口文档中存在重复的UrlPath,检测结果:{},请仔细核对并明确需求!'
                     .format(swagger_doc_urlpath_veriry))
                 pass_flag = False
             if capture_doc_urlpath_veriry != {}:
                 logger.warning(
                     '[WARNING]:检测到接口抓包文档中存在重复的UrlPath,检测结果:{},请仔细核对并明确需求!'.
                     format(capture_doc_urlpath_veriry))
                 pass_flag = False
             return pass_flag
         else:
             logger.warning("[WARNING]:请先正常初始化Swagger接口文档和接口抓包文档!")
             sys.exit(1)
     except Exception:
         logger.exception(
             "[Exception]:检测Swagger接口文档或接口抓包文档中各自UrlPath列是否存在重复值过程中发生异常,请检查!"
         )
         return False
Exemplo n.º 29
0
 def get_group_data(self, id=[], group=[], order=[], check_active=False):
     """
     获取分组修饰的数据。
     :param id: 用例编号列表,如["TC_1", "TC_2"], 开启id参数后,分组group及序号order不生效。
     :param group: 分组名称列表,如["A", "B"]
     :param order: 用例顺序列表,如[1, 2]
     :param check_active: 校验开关
     :return:
     """
     if not isinstance(id, list):
         logger.warning('[WARNING]:用例编号参数id必须以列表方式入参,如["TC_1","TC_2"]方式!')
         import sys
         sys.exit(1)
     if not isinstance(group, list):
         logger.warning('[WARNING]:测试分组参数group必须以列表方式入参,如["A","B"]方式!')
         import sys
         sys.exit(1)
     if not isinstance(order, list):
         logger.warning('[WARNING]:用例顺序参数order必须以列表方式入参,如[1,2]方式!')
         import sys
         sys.exit(1)
     if id != [] and check_active is False:
         return self.test_case_df[self.test_case_df["ID"].isin(id)]
     if id != [] and check_active is True:
         return self.test_case_df[(self.test_case_df["Active"] == True)
                                  & (self.test_case_df["ID"].isin(id))]
     if id == [] and group == [] and order == [] and check_active is False:
         return self.get_all_data(check_active=False)
     if id == [] and group == [] and order == [] and check_active is True:
         return self.get_all_data(check_active=True)
     if id == [] and group != [] and order == [] and check_active is False:
         return self.test_case_df[self.test_case_df["Group"].isin(group)]
     if id == [] and group != [] and order == [] and check_active is True:
         return self.test_case_df[(self.test_case_df["Active"] == True) &
                                  (self.test_case_df["Group"].isin(group))]
     if id == [] and group == [] and order != [] and check_active is False:
         return self.test_case_df[self.test_case_df["Order"].isin(order)]
     if id == [] and group == [] and order != [] and check_active is True:
         return self.test_case_df[(self.test_case_df["Active"] == True) &
                                  (self.test_case_df["Order"].isin(order))]
     if id == [] and group != [] and order != [] and check_active is False:
         return self.test_case_df[(self.test_case_df["Group"].isin(group)) &
                                  (self.test_case_df["Order"].isin(order))]
     if id == [] and group != [] and order != [] and check_active is True:
         return self.test_case_df[(self.test_case_df["Active"] == True)
                                  & (self.test_case_df["Group"].isin(group))
                                  &
                                  (self.test_case_df["Order"].isin(order))]
Exemplo n.º 30
0
 def page_frequency(self, es_index, es_dsl):
     """
     计算ELK查询分页频次(size:10000条)
     :param es_index: ES索引
     :param es_dsl: ES查询语句
     :return:
     """
     es_res = self.dsl_search(es_index, es_dsl)
     if es_res:
         hits_count_list = jsonpath(es_res.json(), "$.hits.total.value")
         if hits_count_list:
             hits_count = hits_count_list[0]
             if hits_count == 0:
                 logger.warning("【ELK】DSL查询结果为空,请知悉!")
                 sys.exit(1)
             logger.info("【ELK】DSL查询匹配结果总量为:{}".format(hits_count))
             pages = divmod(hits_count, 10000)
             total_page = pages[0]
             leave_page = pages[1]
             if total_page == 0:
                 logger.info("【ELK】已计算数据采集预期DSL分页频次为:1")
                 return dict(count=hits_count,
                             frequency=1,
                             total_page=1,
                             leave_page=0)
             elif total_page > 0 and leave_page == 0:
                 logger.info("【ELK】已计算数据采集预期DSL分页频次为:{}".format(total_page))
                 return dict(count=hits_count,
                             frequency=total_page,
                             total_page=total_page,
                             leave_page=0)
             elif total_page > 0 and leave_page > 0:
                 logger.info("【ELK】已计算数据采集预期DSL分页频次为:{}".format(total_page +
                                                                1))
                 return dict(count=hits_count,
                             frequency=total_page + 1,
                             total_page=total_page,
                             leave_page=1)
             else:
                 logger.warning("【ELK】未成功计算预期DSL分页频次,请检查!")
                 sys.exit(1)
         else:
             logger.error("【ELK】查询匹配结果总量获取失败,请检查查询结果或JsonPath表达式是否合法!")
             sys.exit(1)
     else:
         logger.warning("【ELK】由于DSL查询失败,导致结果总量未能获取!")
         sys.exit(1)