Example #1
0
 def init_serialize(self):
     init = self.api_info['init'].strip().replace(
         '\n', '') if self.api_info.get('init') else None
     log.info(
         string.Template("api request init info is: $init").substitute(
             init=init))
     if not init:
         return
     res = self._json_serialize(init)
     srlz_res = []
     if res:
         for case in res:
             sr = Serialize(case)
             sr.url_prepare()
             sr.method_check()
             sr.wait_time_value_check()
             srlz_res.append(sr.api_info)
         self.api_info['init'] = srlz_res
         return srlz_res
     else:
         log.error(
             string.Template(
                 "api request init format error, init info: $init").
             substitute(init=self.api_info['init']))
         return False
Example #2
0
    def append_row(self, sheet_name, data_list, passed):
        """
        往Excel表格中追加数据
        :param sheet_name:
        :param data_list:
        :param passed 用例是否执行通过
        :return:
        """
        passed = passed or 'PASS'
        if not isinstance(data_list, list):
            log.error("要写入的结果的入参类型错误")
            return False
        if sheet_name not in self.sheet_info:
            self.sheet = self.workbook.add_sheet(sheet_name,
                                                 cell_overwrite_ok=True)
            self.sheet_info[sheet_name] = {"row": 1, "col": 0}
            self.write_row(sheet_name, 0, 0, self.sheet_title)
        else:
            self.sheet = self.workbook.get_sheet(sheet_name)
        row = self.sheet_info[sheet_name]['row']
        col = self.sheet_info[sheet_name]['col']

        if passed.upper() == 'PASS':
            style = self.set_style('green')
        elif passed.upper() == 'FAIL':
            style = self.set_style('red')
        elif passed.upper() == 'WARNING':
            style = self.set_style('yellow')
        else:
            style = self.set_style('green')
        try:
            self.write_row(sheet_name, row, col, data_list, style)
        except Exception as e:
            log.error(Template("往Excel表格中写入数据异常,异常信息:$e").substitute(e=e))
        self.sheet_info[sheet_name]['row'] += 1
Example #3
0
    def smtp_link(self):
        """
        func: 连接smtp服务器,判断当前所在的平台,连接smtp服务
        :return:
        """

        if "win" in sys.platform.lower():
            log.info('mail server in windows platform')
            smtp = smtplib.SMTP_SSL(self.server)
        elif "linux" in sys.platform.lower():
            log.info('mail server in linux platform')
            smtp = smtplib.SMTP_SSL(self.server)
        else:
            log.error('mail server not support this system platform')
            raise SystemError('mail server not support this system platform')
        try:
            smtp.connect(self.server, self.port)
            log.info('smtp connect server success')
            smtp.login(self.sender, self.pwd)
            log.info('login mail server success')
            self.smtp_handler = smtp
            return smtp
        except Exception as e:
            log.error('login mail server fail, error info is: {}'.format(e))
            return False
Example #4
0
    def append_row(self, sheet_name, data_list, passed):
        """
        往Excel表格中追加数据
        :param sheet_name:
        :param data_list:
        :param passed 用例是否执行通过
        :return:
        """
        passed = passed or 'PASS'
        if not isinstance(data_list, list):
            log.error("要写入的结果的入参类型错误")
            return False
        if sheet_name not in self.sheet_info:
            self.append(sheet_name, self.sheet_title)
        else:
            self.sheet = self.workbook.get_sheet(sheet_name)

        if passed.upper() == 'PASS':
            style = self.set_style('green')
        elif passed.upper() == 'FAIL':
            style = self.set_style('red')
        elif passed.upper() == 'WARNING':
            style = self.set_style('yellow')
        else:
            style = self.set_style('green')
        self.append(sheet_name, data_list, style)
Example #5
0
 def restore_serialize(self):
     restore = self.api_info['restore'].strip().replace(
         '\n', '') if self.api_info.get('restore') else None
     log.info(
         string.Template("api request restore info is: $restore").
         substitute(restore=restore))
     if not restore:
         return
     res = self._json_serialize(restore)
     srlz_res = []
     if res:
         for case in res:
             sr = Serialize(case)
             sr.url_prepare()
             sr.method_check()
             sr.wait_time_value_check()
             srlz_res.append(sr.api_info)
         self.api_info['restore'] = srlz_res
         return srlz_res
     else:
         log.error(
             string.Template(
                 "api request restore format error, restore info: $restore"
             ).substitute(restore=self.api_info['restore']))
         return False
Example #6
0
def check_response_header(fields, headers):
    error_info = ""
    if not fields:
        return error_info
    log.debug(
        Template("fields: $fields, headers: $headers").substitute(
            fields=fields, headers=headers))
    if not fields:
        return error_info
    if isinstance(fields, str):
        log.debug('is a string fields, value is:'.format(fields))
        fs = fields.split(',')
    elif isinstance(fields, list):
        log.debug('is a list fields, value is: '.format(str(fields)))
        fs = fields
    else:
        log.error('fields param type error')
        raise TypeError('fields param type error')
    for text in fs:
        text = text.lstrip("'").lstrip('"').rstrip("'").rstrip('"')
        if text:
            if isinstance(headers, dict):
                # if not headers.get(text):
                isempty = jmespath.search(text, headers)
                if isempty is None:
                    error_info += Template(
                        "接口响应内容没有待校验的字段:$t,响应内容:$res").substitute(t=text,
                                                                  res=headers)
            else:
                if text not in headers:
                    error_info += Template(
                        "接口响应内容没有待校验的字段:$t,响应内容:$res").substitute(t=text,
                                                                  res=headers)

    return error_info
Example #7
0
def check_response_text(fields, response):
    error_info = ""
    log.debug(
        Template("fields: $fields, response: $response").substitute(
            fields=fields, response=response))
    if not fields:
        return error_info
    if isinstance(fields, str):
        log.debug('is a string fields, value is:'.format(fields))
        fs = fields.split(',')
    elif isinstance(fields, list):
        log.debug('is a list fields, value is: '.format(str(fields)))
        fs = fields
    else:
        log.error('fields param type error')
        return 'check res_text error, fields param type error'
    for text in fs:
        text = text.lstrip("'").lstrip('"').rstrip("'").rstrip('"')
        if text:
            log.debug(Template("待校验的内容: $text").substitute(text=text))
            if isinstance(response, dict):
                isempty = jmespath.search(text, response)
                if isempty is None:
                    error_info += Template(
                        "接口响应内容没有待校验的字段:$t,响应内容:$res").substitute(t=text,
                                                                  res=response)
            else:
                if text not in response:
                    error_info += Template(
                        "接口响应内容没有待校验的字段:$t,响应内容:$res").substitute(t=text,
                                                                  res=response)

    return error_info
Example #8
0
 def _order_for_testcase(self, cases, base_num):
     """
     func:用于给所有测试用例编排执行顺序
     :param cases:
     :return:
     """
     orders = self._get_cases_orders(cases)
     log.debug(
         string.Template("**************$o****************").substitute(
             o=orders))
     max_num = max(orders) + 1 if orders else 1
     ordered = []
     for case in cases:
         try:
             order = int(case['order']) if case['order'] else None
         except Exception as e:
             log.error(
                 string.Template(
                     "integer order number error, error info: $e").
                 substitute(e=e))
             order = None
         if order:
             case['order'] = base_num + order
         else:
             case['order'] = base_num + max_num
             max_num += 1
         ordered.append(case)
     return ordered
Example #9
0
 def __init__(self, filepath):
     if not os.path.isfile(filepath):
         log.error(
             string.Template(
                 "test case file not found, please check! $filepath").
             substitute(filepath=filepath))
         raise FileNotFoundError("test case file not found, please check!")
     self.filepath = filepath
     self.excel_fields = settings.excel_fields
     self.init_case = None  # 数据初始化sheet
     self.restore_case = None  # 数据恢复sheet
     self.base_configs = None  # 基础配置sheet
     self.all_sheets = None  # Excel文件所有sheet
     self.testsuites = {}  # 除了已有固定的sheet外的其他测试sheet
     self.testsuite_local_vars_line_name = "local_line"
     self.testsuite_init_line_name = "init_line"
     self.testsuites_restore_line_name = "restore_line"
     self.testsuites_testcase_line_name = "testcase_line"
     self._read_file()
     self.parse_base_configs()
     self.parse_global_vars()
     self.parse_init_datas()
     self.parse_testsuite()
     self.parse_restore_datas()
     self.cases_order()
Example #10
0
    def trend_detail(self, report_dir):
        log.info('处理allure测试报告trend内容')
        if not os.path.isdir(report_dir):
            log.error('需要处理trend的目录不是一个有效路径,请检查')
            return False
        allure_json_file_dirs = []  # 所有allure json报告的所有目录
        suffix_dir = os.path.split(report_dir)[0]  # 测试报告路径前缀
        relative_path = os.path.split(report_dir)[1]  # 当前测试报告目录
        for item in os.listdir(suffix_dir):
            if re.match(r'^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}', item):
                allure_json_file_dirs.append(item)

        allure_json_file_dirs = sorted(allure_json_file_dirs, reverse=True)
        log.info(
            'all the allure report dirs is: {}'.format(allure_json_file_dirs))

        last_allure_report_dir = os.path.join(
            suffix_dir, self.allure_report)  # 最近一次allure json报告的目录
        log.info(
            'last_allure_report_dir is: {}'.format(last_allure_report_dir))
        if not os.path.isdir(last_allure_report_dir):
            log.info('no last_allure_report_dir, no need to detail trend')
            return None
        else:
            last_allure_report_history_dir = os.path.join(
                last_allure_report_dir,
                "history")  # 最近一次allure_report目录中的history目录
            last_allure_json_dir = os.path.join(
                suffix_dir, allure_json_file_dirs[0])  # 最近一次allure json文件目录
            last_history_dir = os.path.join(
                last_allure_json_dir,
                "history")  #最近一次allure json文件目录中history目录

            self.manual_join_trend_file(last_allure_report_history_dir,
                                        last_history_dir, report_dir)
Example #11
0
 def build_connection(self):
     try:
         self.database = pymysql.connect(**self.cfg)
         log.info('connect mysql success')
         return self.database
     except Exception as e:
         log.error(Template('connect mysql fail, the error info: $e, the database config info: $cfg'
                            '').substitute(e=e, cfg=self.cfg))
Example #12
0
 def _json_serialize(cls, s):
     try:
         # s = json.dumps(s)
         return ast.literal_eval(s)
     except Exception as e:
         log.error(
             string.Template(
                 "string serialize json fail, source string: $s, error info: $e"
             ).substitute(s=s, e=e))
         raise JsonSerializeException("serialize to JSON format error")
Example #13
0
    def db_verify_serialize(self):
        """
        func:对测试用例中的db_verify项进行json格式化和基本字段校验
        首先判断db_verify字段是否符合json格式,如果符合,则该字段进行sql语句判断有无,db配置是否在基础配置中已配置,检查的类型是否正确
        能检查的类型为:= or == 表示查询的值和预期值要相等,~ or ~=表示预期值包含在查询结果中,! or != 表示查询值不能等于预期值,
                     ~ or !~ 表示预期值不能包含在查询值中
        :return:json格式化之后的db_verify字段
        """
        db_verify = self.api_info['db_verify'].strip() if self.api_info.get(
            'db_verify') else None
        log.info(
            string.Template("api request db_verify info is: $db_verify").
            substitute(db_verify=db_verify))
        if not db_verify:
            return
        res = self._json_serialize(db_verify)
        if res:
            flag = True
            databases_list = Process.base_configs.get('database') or {}
            type_list = ["=", '==', '!', '!=', '~', '~=', '!~', '~!']
            error_msg = ""
            for k, v in res.items():
                sql_ = v.get('sql')
                db = v.get('db')
                type_ = v.get('type') or '='
                if not sql_:
                    flag = False
                    error_msg += "{} sql键不能为空,请检查\n".format(k)
                if not db or db not in databases_list:
                    flag = False
                    error_msg += "{} 配置的db选项没有在基础配置中配置相关的参数\n".format(k)
                else:
                    v['ip'] = databases_list[db].get('ip')
                    v['port'] = databases_list[db].get('port')
                    v['db_type'] = databases_list[db].get('type')
                    v['user'] = databases_list[db].get('user')
                    v['pwd'] = databases_list[db].get('pwd')
                if type_ not in type_list:
                    flag = False
                    error_msg += "{} 配置的type目前无法识别,请检查type选项是否以下选项:{}\n".format(
                        k, type_list)
                res[k] = v
            if not flag:
                log.error(error_msg)
                raise JsonSerializeException

            self.api_info['db_verify'] = res
            return res
        else:
            log.error(
                string.Template(
                    "api request db_verify format error, db_verify info: $db_verify"
                ).substitute(db_verify=self.api_info['db_verify']))
            return False
Example #14
0
 def query(self, sql):
     with self.__conn.cursor() as cursor:
         log.info('query sql is: {}'.format(sql))
         try:
             cursor.execute(sql)
             # data_one = cursor.fetchone()
             data_all = cursor.fetchall()
             log.debug(Template('query results is: $all').substitute(all=data_all))
             return data_all
         except Exception as e:
             log.error('query fail, error info: {}, the sql is: {}'.format(str(e), str(sql)))
             return False
Example #15
0
def parse_interface_var(source: object, response: object) -> object:
    var_dict = {}

    for k, v in source.items():
        try:
            var_dict[k] = jmespath.search(v, response)
        except Exception as e:
            log.error(
                string.Template(
                    "get interface_var:$v from response fail,error info: $e").
                substitute(v=v, e=e))
    return var_dict
Example #16
0
 def _read_sheet_rows(cls, sheet):
     """
     获取整个sheet表的所有行数据
     :param sheet:
     :return: 所有行的数据
     """
     try:
         return sheet.get_rows()
     except Exception as e:
         log.error(
             string.Template("get sheet rows fail, sheet is: $sheet").
             substitute(sheet=sheet.name))
         log.exception(e)
Example #17
0
 def _testcase_dir_init(self):
     if os.path.isdir(self.testcase_dir):
         try:
             shutil.rmtree(self.testcase_dir)
         except Exception as e:
             log.error(
                 Template("testcase目录无法删除,请检查是否有其他应用正在使用该目录下的资源,错误信息:$e").
                 substitute(e=e))
             return False
     os.makedirs(self.testcase_dir)
     with open(os.path.join(self.testcase_dir, "__init__.py"),
               'w',
               encoding='utf-8') as f:
         f.write("# -*- coding: utf-8 -*-")
Example #18
0
 def url_prepare(self):
     url = self.api_info['url'].strip().replace(
         '\n', '') if self.api_info.get('url') else None
     log.info(
         string.Template("api info url info is: $url").substitute(url=url))
     if not url:
         log.error(string.Template("url params are required").substitute())
         raise JsonSerializeException
     elif not url.startswith('http://'):
         res = Process.base_configs['hostname'] + url
         self.api_info['url'] = res
         return res
     else:
         return url
Example #19
0
def check_status_code(code, response):
    error_info = ""
    if not code:
        return error_info
    try:
        code = int(code)
    except Exception as e:
        log.error(Template("接口响应状态码入参错误,请检查, 入参值:$code").substitute(code=code))
        error_info += Template("接口响应状态码入参错误,请检查, 入参值:$code").substitute(
            code=code)
        return error_info
    if code != response:
        error_info += Template("接口响应码校验失败:预期值:$n,响应值:$res").substitute(
            n=code, res=response)
    return error_info
Example #20
0
    def send(self,
             mail_body,
             receivers,
             attachs=None,
             subject="auto-test mail notify"):
        """
        func: 发送邮件功能
        :param mail_body: 邮件文本主体,字符串类型
        :param receivers: 接收者列表,list类型
        :param attachs: 需要添加的附件,list类型,list中的每个元素需要是dict类型,并且需要有filename和filepath两个属性
        :param subject: 邮件主题
        :return:
        """
        if not attachs:
            if not isinstance(attachs, list):
                log.error('attach param is not a list')
                attach = None
        msg = MIMEMultipart()  # 支持邮件中附带附件
        msg['Subject'] = Header(subject, 'utf-8')
        msg['From'] = Header(self.sender, 'utf-8')
        for receiver in receivers:
            msg['To'] = Header(receiver, 'utf-8')

        mail_body = "(本邮件是程序自动下发的,请勿回复!)\r\n" + mail_body
        text_content = MIMEText(mail_body, 'plain', 'utf-8')
        msg.attach(text_content)
        # 添加附件
        if attachs:
            attachs = self.attach_check(attachs)
            for att in attachs:
                filepath = att.get('filepath')
                filename = att.get('filename')
                log.debug('filepath is: {}'.format(filepath))
                att_tmp = MIMEText(
                    open(filepath, 'rb').read(), 'base64', 'utf-8')
                att_tmp['Content-type'] = 'application/octet-stream'
                att_tmp[
                    'Content-Disposition'] = 'attachment; filename="{}"'.format(
                        filename)
                msg.attach(att_tmp)
        try:
            if self.smtp_link():
                self.smtp_handler.sendmail(self.sender, receivers,
                                           msg.as_string())
                log.info("send mail success!")

        except Exception as e:
            log.error("发送邮件异常, 错误信息:{}".format(e))
Example #21
0
def dyparam_parse(testcase: dict, var_object: object):
    """
    func: 根据dyparam里的sql信息,进行数据库查询,将查询到的结果存入var_object对象的interface_vars属性中
    :param dyparam: 测试用例中的dyparam信息经过json转换后的内容
    :param var_object: 用于存放测试sheet接口变量的对象
    :return: 添加了从数据库中查询出来的值之后的var_object对象
    """
    if not isinstance(testcase, dict):
        return "testcase is not a dict"
    dyparam = testcase.get('dyparam')
    if not dyparam:
        return None
    if not isinstance(dyparam, dict):
        return "dyparam is not a dict type"
    if not hasattr(var_object, "interface_vars"):
        var_object.interface_vars = {}
    log.info('进入dyparam解析')
    for name_, sql_info in dyparam.items():
        ip = sql_info.get('ip')
        port = sql_info.get('port')
        pwd = sql_info.get('pwd')
        user = sql_info.get('user')
        db_type = sql_info.get('db_type')
        values = sql_info.get('values')
        sql = sql_info.get('sql')
        rs = DbHelper().query(ip=ip,
                              port=port,
                              user=user,
                              pwd=pwd,
                              db_type=db_type,
                              sql=sql)
        if not rs:
            log.warning("sql: {} 查询结果为空".format(sql))
            for var_name, reslut_key in values.items():
                var_object.interface_vars[var_name] = ""
            continue

        rs = rs[0]
        try:
            for var_name, reslut_key in values.items():
                log.info('添加interface_var: {}={}'.format(
                    var_name, rs.get(reslut_key)))
                var_object.interface_vars[var_name] = rs.get(reslut_key)
        except Exception as e:
            log.error('add interface_vars fail, error info is: {}'.format(e))
            return False
    return var_object
Example #22
0
def parse_interface_var(source: object, response: object) -> object:
    var_dict = {}
    if not isinstance(source, dict):
        return 'response is not a dict'
    for k, v in source.items():
        try:
            res = jmespath.search(v, response)
            if isinstance(res, list):
                var_dict[k] = res[0]
            else:
                var_dict[k] = res
        except Exception as e:
            log.error(
                string.Template(
                    "get interface_var:$v from response fail,error info: $e").
                substitute(v=v, e=e))
    return var_dict
Example #23
0
 def order_fields_check(self):
     order = self.api_info['order'] if self.api_info.get("order") else None
     log.info(
         string.Template("api request order info is: $order").substitute(
             order=order))
     if not order:
         return None
     try:
         res = int(order)
         self.api_info['order'] = res
         return res
     except Exception as e:
         log.error(
             string.Template(
                 "api order param format error, please input a integer number "
                 "error info: $e").substitute(e=e))
         raise JsonSerializeException
Example #24
0
def check_response_time(_time, response):
    error_info = ""
    if not _time:
        return error_info
    try:
        _time = float(_time)
        if _time < response:
            log.error(
                Template("接口响应时间超时,期望值: $t, 响应值: $r").substitute(t=_time,
                                                                 r=response))
            error_info += Template("接口响应时间超时,期望值: $t, 响应值: $r").substitute(
                t=_time, r=response)
            return error_info
    except Exception as e:
        log.error(Template("接口响应时间入参错误,请检查: $t").substitute(t=_time))
        error_info += Template("接口响应时间入参错误,请检查: $t").substitute(t=_time)
        return error_info
Example #25
0
 def dyparam_serialize(self):
     dyparam = self.api_info['dyparam'].strip().replace(
         '\n', '') if self.api_info.get('dyparam') else None
     log.info(
         string.Template("api request dyparam info is: $dyparam").
         substitute(dyparam=dyparam))
     if not dyparam:
         return
     res = self._json_serialize(dyparam)
     if res:
         self.api_info['dyparam'] = res
         return res
     else:
         log.error(
             string.Template(
                 "api request dyparam format error, dyparam info: $dyparam"
             ).substitute(dyparam=self.api_info['dyparam']))
         return False
Example #26
0
 def restore_serialize(self):
     restore = self.api_info['restore'].strip().replace(
         '\n', '') if self.api_info.get('restore') else None
     log.info(
         string.Template("api request restore info is: $restore").
         substitute(restore=restore))
     if not restore:
         return
     res = self._json_serialize(restore)
     if res:
         self.api_info['restore'] = res
         return res
     else:
         log.error(
             string.Template(
                 "api request restore format error, restore info: $restore"
             ).substitute(restore=self.api_info['restore']))
         return False
Example #27
0
 def init_serialize(self):
     init = self.api_info['init'].strip().replace(
         '\n', '') if self.api_info.get('init') else None
     log.info(
         string.Template("api request init info is: $init").substitute(
             init=init))
     if not init:
         return
     res = self._json_serialize(init)
     if res:
         self.api_info['init'] = res
         return res
     else:
         log.error(
             string.Template(
                 "api request init format error, init info: $init").
             substitute(init=self.api_info['init']))
         return False
Example #28
0
 def expression_serialize(self):
     expression = self.api_info['expression'].strip().replace(
         '\n', '') if self.api_info.get('expression') else None
     log.info(
         string.Template("api request expression info is: $expression").
         substitute(expression=expression))
     if not expression:
         return
     res = self._json_serialize(expression)
     if res:
         self.api_info['expression'] = res
         return res
     else:
         log.error(
             string.Template(
                 "api request expression format error, expression info: $expression"
             ).substitute(expression=self.api_info['expression']))
         return False
Example #29
0
 def verify_fields_serialize(self):
     verify = self.api_info['verify_fields'].strip().replace(
         '\n', '') if self.api_info.get('verify_fields') else None
     log.info(
         string.Template("api request verify_fields info is: $verify").
         substitute(verify=verify))
     if not verify:
         return
     res = self._json_serialize(verify)
     if res:
         self.api_info['verify_fields'] = res
         return res
     else:
         log.error(
             string.Template(
                 "api request verify_fields format error, verify_fields info: $verify_fields"
             ).substitute(verify_fields=self.api_info['verify_fields']))
         return False
Example #30
0
 def interface_var_serialize(self):
     var = self.api_info['interface_var'].strip().replace(
         '\n', '') if self.api_info.get("interface_var") else None
     log.info(
         string.Template(
             "api request interface_var info is: $var").substitute(var=var))
     if not var:
         return
     res = self._json_serialize(var)
     if res:
         self.api_info['interface_var'] = res
         return res
     else:
         log.error(
             string.Template(
                 "api request interface_var format error, interface_var info: $var"
             ).substitute(var=self.api_info['interface_var']))
         return False