Пример #1
0
    def execute(self, request):
        zk = KazooClient(hosts=request['zk_url'])
        try:
            zk.start()
            path_ = request['node_path']
            value_ = request['node_value'].encode('utf-8')
            is_update_timestamp_ = request.get('is_update_timestamp', False)
            is_delete_node_ = request.get('is_delete_node', None)

            if zk.exists(path_):
                if is_delete_node_:
                    zk.delete(path_, recursive=True)
                    return self.resp_dict, ''
                if is_update_timestamp_:
                    zk.set(path_ + '/TIMESTAMP', ZkTestPoint.get_timestamp_bytes())
                if value_:
                    zk.set(path_, value_)
                else:
                    data_, stat_ = zk.get(path_)
                    if data_:
                        self.resp_dict['result_value'] = data_.decode()
            elif value_:
                # 新加节点时也需要添加 '/TIMESTAMP' 节点
                zk.create(path_, value_, makepath=True)
                zk.create(path_ + '/TIMESTAMP', ZkTestPoint.get_timestamp_bytes(), makepath=True)

            return self.resp_dict, ''
        except Exception as e:
            logger.exception('zkTestPoint execute error, cause: %s', str(e))
            raise Exception('zkTestPoint execute error, cause: ' + str(e))
        finally:
            zk.stop()
Пример #2
0
    def execute(self, request):
        # 发起接口调用请求并接收响应
        try:
            host = self.tp_conf.get(ActiveMqTestPointEnum.host.key)
            port = self.tp_conf.get(ActiveMqTestPointEnum.port.key)
            user_name = self.tp_conf.get(ActiveMqTestPointEnum.port.key)
            password = self.tp_conf.get(ActiveMqTestPointEnum.password.key)
            destination = self.tp_conf.get(
                ActiveMqTestPointEnum.destination.key)

            conn = stomp.Connection10(host_and_ports=[(host, port)])
            conn.start()
            conn.connect(username=user_name, password=password)
            conn.send(destination=destination,
                      body=json.dumps(request),
                      headers={'amq-msg-type': 'text'})
            conn.disconnect()
            logger.info('tp->active mq:消息发送成功,destination=' + destination +
                        'msg=' + json.dumps(request))
            result = {'result_value': True}
            return result, ''

        except ConnectionError as e:
            logger.error('tp->active mq:connection error:', str(e))
            raise RuntimeError('active mq测试,调用被测系统时连接异常')
        except Exception as e:
            logger.exception('tp->active mq:runtime error:', str(e))
            raise RuntimeError('active mq测试,调用被测系统时执行异常')
Пример #3
0
def runtask(filename, joblist, flag):
    """
    start a task
    """
    if not filename:
        click.echo(click.style('file name error, please check !', fg='red'))
        sys.exit()
    create_sqlite_db()
    init_db_info()
    task_id = common.get_time_uuid().replace('-', '')
    try:
        task_detail_loader = ParameterTaskDetailLoader(
            task_id,
            filename,
            joblist,
            None,
            flag,
            None,
            'agbot-cmd',
            'agbot-cmd'
        )
        # task_content 配置
        task_detail = task_detail_loader.load()  # type: TaskDetail
        logger.info('start task-------------------------------------------task_id:' + task_id)
        # 检查任务是否已经存在
        _, tab_task_log = DBUtils.query(TableTaskLog, filter_dict={'task_id': task_id})
        if tab_task_log:
            click.echo(click.style('task already exists', fg='red'))
            sys.exit(-1)
        # 直接使用线程执行 task , 然后返回前端成功状态
        click.echo(click.style('task [{}] running, please wait ...'.format(task_id), fg='green'))
        event_loop.run_until_complete(task_executor.execute(task_detail))
    except Exception as e:
        logger.exception('runtask error, {}'.format(str(e)))
        click.echo(click.style('创建任务失败, 请检查脚本文件. 错误原因: {}'.format(str(e)), fg='red'))
Пример #4
0
    def build_request(self):
        tc_ctx_dict = self.vertical_context.tc_context
        try:
            # 获取请参
            TpBase.build_request(self)

            # 组装heard
            # 20190403 edit by jun.hu
            # 新加支持 http_header 配置字典写法
            head_dict = {}
            tc_data_dict = tc_ctx_dict.tc_detail.data
            tp_conf_header = self.tp_conf.get('http_header', None)
            if tp_conf_header:
                try:
                    # 默认配置支持字典的写法
                    self.__header = json.loads(tp_conf_header)
                except Exception as ex:
                    logger.info(str(ex))
                    # 字典取值发生错误时取逗号隔开的值
                    params_name_list = self.tp_conf.get('http_header').split(
                        ',')
                    for name in params_name_list:
                        head_dict[name] = tc_data_dict.get(name)
                    self.__header = head_dict

            if self.tp_conf.get('upload_file_path'):
                upload_file_path = self.tp_conf.get('upload_file_path')
                upload_file_path = upload_file_path.split('/')[-1]
                upload_file = next(
                    filter(
                        lambda a: a.id.endswith(upload_file_path), self.
                        vertical_context.job_context.job_model.attachment),
                    None)
                assert upload_file is not None, 'file not found: {}'.format(
                    upload_file_path)
                files = {
                    self.tp_conf.get('upload_file_name'): upload_file.content
                }
                self.__file = files

            # 构造json请求参数
            if self.tp_conf.get('json_param_name'):
                json_param_dict = {}
                if self.tp_conf.get('req_json_data'):
                    params_name_list = self.tp_conf.get('req_json_data').split(
                        ',')
                    for name in params_name_list:
                        json_param_dict[name] = tc_data_dict.get(name)
                # json参数放入请参字典
                self.req_param[self.tp_conf.get(
                    'json_param_name')] = json.dumps(json_param_dict)

            return {'content': self.req_param, 'header': self.__header}

        except Exception as e:
            logger.exception('tp->api:build params error', str(e))
            raise Exception(str(e))
Пример #5
0
def handle_flask_error(error):
    # 打印异常
    logger.exception(str(error))
    # response 的 json 内容为自定义错误代码和错误信息
    response = jsonify({'return_code': COMMON_ERROR, 'message': str(error)})

    # response 返回 error 发生时定义的标准错误代码
    response.status_code = 500
    return response
Пример #6
0
    def build_request(self):

        try:
            # 获取请参
            TpBase.build_request(self)
            return self.req_param

        except Exception as e:
            logger.exception('tp->active mq:build params error', str(e))
            raise Exception('active mq测试,构建参数时错误,测试脚本没有找到或者解析失败')
Пример #7
0
    def execute(self, request):
        ftp = None
        try:
            host_port = request[FtpTestPointEnum.address.key].split(':')

            if request[FtpTestPointEnum.server_type.key] == 'sftp':
                sf = paramiko.Transport(host_port[0], int(host_port[1]))
                sf.connect(username=request[FtpTestPointEnum.username.key],
                           password=request[FtpTestPointEnum.password.key])
                sftp = paramiko.SFTPClient.from_transport(sf)
                # sftp下载需要先新建本地文件
                cur_path = os.getcwd()
                file_path = os.path.join(
                    cur_path,
                    '/download' + request[FtpTestPointEnum.req_data.key])
                create_file(file_path)
                sftp.get(request[FtpTestPointEnum.req_data.key], file_path)
                # 读取本地文件
                file_object = open(file_path, 'rb')
                try:
                    file_context = file_object.read()
                finally:
                    file_object.close()
                resp_dict = {'result_value': file_context}
                # 删除文件
                os.remove(file_path)
            elif request[FtpTestPointEnum.server_type.key] == 'ftp':
                ftp = FTP()
                ftp.connect(host_port[0], int(host_port[1]))
                ftp.login(request[FtpTestPointEnum.username.key],
                          request[FtpTestPointEnum.password.key])
                self.file_download = io.BytesIO()
                ftp.retrbinary(
                    'RETR %s' % request[FtpTestPointEnum.req_data.key],
                    self.file_download.write)
                resp_dict = {'result_value': self.file_download}
            else:
                logger.exception('FtpTestPoint execute error, cause: %s',
                                 'server_type配置错误')
                raise Exception('FtpTestPoint execute error, cause: ' +
                                'server_type配置错误')
            self.resp_dict = resp_dict
            return self.resp_dict, ''

        except Exception as e:
            logger.exception('FtpTestPoint execute error, cause: %s', str(e))
            raise Exception('FtpTestPoint execute error, cause: ' + str(e))
        finally:
            if ftp is not None:
                ftp.close()
Пример #8
0
    def build_request(self):

        try:
            # 获取请参
            self.req_param['zk_url'] = self.tp_conf.get('zk_url')
            self.req_param['node_path'] = self.tp_conf.get('node_path')
            self.req_param['node_value'] = self.tp_conf.get('node_value')
            self.req_param['is_update_timestamp'] = self.tp_conf.get('is_update_timestamp', False)
            self.req_param['is_delete_node'] = self.tp_conf.get('is_delete_node', False)
            return self.req_param

        except Exception as e:
            logger.exception('zkTestPoint build_params error, cause: %s', str(e))
            raise Exception('zkTestPoint build_params error, make sure param is correct')
Пример #9
0
 def execute_move_to_element_click(self, **kwargs):
     try:
         exec_element = kwargs['exec_element']
         # 滑动的元素
         exec_param = kwargs['exec_param']
         # 需要根据 exec_param 找到 hover 所在层
         hover_element = find_element(self.driver, exec_param)
         if not hover_element:
             return False
         # 向下滑动
         ActionChains(self.driver).move_to_element(hover_element).click(
             exec_element).perform()
         return True
     except Exception as ex:
         logger.exception(ex)
         return False
Пример #10
0
    def build_request(self):
        tc_params_dict = self.vertical_context.tc_context
        self._tc_params_dict = tc_params_dict
        script_name = self.tp_conf.get(
            UiTestPointEnum.script_file_path.key,
            self.tp_conf.get(UiTestPointEnum.script.key))
        script_name = script_name.split('/')[-1]
        xml_script = next(
            filter(lambda a: a.id.endswith(script_name),
                   self.vertical_context.job_context.job_model.attachment),
            None)
        assert xml_script is not None, 'can not fond xml script {}'.format(
            script_name)
        xml_script_content_raw = xml_script.content.decode('utf-8')

        try:
            xml_script_content, replacement = get_placeholder_value(
                xml_script_content_raw, self.vertical_context)
            self.__extend_tp_replacement(replacement)

            # 获取命令列表
            self._command_list = self._get_command_list(xml_script_content)

            target_url = ''
            for command in self._command_list:

                # 请求参数作用于 open 函数的目标
                if command['command'] == 'open':
                    target_url = self._get_command_param(command['target'])
                    logger.info("ui 原始请求地址为 :{}".format(target_url))
                    # 组装页面地址
                    if UiTestPointEnum.req_data.key in self.tp_conf and self.tp_conf[
                            UiTestPointEnum.req_data.key]:
                        TpBase.build_request(self)
                        target_url = target_url + splice_url_params(
                            self.req_param)
                        logger.info("ui 请求地址,拼接参数后为 :{}".format(target_url))
                        flag = self._set_command_param(command['target'],
                                                       target_url)
                        if not flag:
                            command['target'] = target_url
                    break
        except Exception as e:
            logger.exception('ui 测试脚本: %s ,没有找到或者解析失败', str(self.tp_conf))
            raise RuntimeError('ui 测试脚本:' + str(self.tp_conf) + ',没有找到或者解析失败')
        return {'url': target_url}
Пример #11
0
    def build_request(self):

        try:
            # 获取请参
            # TpBase.build_params(self, tc_ctx_dict)

            self.req_param['req_data'] = self.tp_conf.get('req_data')
            self.req_param['socket_address'] = self.tp_conf.get(
                'socket_address')
            self.req_param['charset'] = self.tp_conf.get('charset')
            return self.req_param

        except Exception as e:
            logger.exception('SocketTestPoint build_params error, cause: %s',
                             str(e))
            raise Exception(
                'SocketTestPoint build_params error, make sure [cache_key, cache_type] is correct'
            )
Пример #12
0
    def build_request(self):
        try:
            # 获取请参
            # TpBase.build_params(self, tc_ctx_dict)
            self.req_param[FtpTestPointEnum.req_data.key] = self.tp_conf.get(
                FtpTestPointEnum.req_data.key)
            self.req_param[FtpTestPointEnum.address.key] = self.tp_conf.get(
                FtpTestPointEnum.address.key)
            self.req_param[FtpTestPointEnum.username.key] = self.tp_conf.get(
                FtpTestPointEnum.username.key)
            self.req_param[FtpTestPointEnum.password.key] = self.tp_conf.get(
                FtpTestPointEnum.password.key)
            self.req_param[
                FtpTestPointEnum.server_type.key] = self.tp_conf.get(
                    FtpTestPointEnum.server_type.key)
            return self.req_param

        except Exception as e:
            logger.exception('FtpTestPoint build_params error, cause: %s',
                             str(e))
            raise Exception(
                'FtpTestPoint build_params error, make sure [cache_key, cache_type] is correct'
            )
Пример #13
0
 def execute(self, request):
     s = None
     try:
         host_port = request['socket_address'].split(':')
         s = socket.socket()
         s.settimeout(5)
         s.connect((host_port[0], int(host_port[1])))
         s.sendall(request['req_data'].encode(request['charset']))
         recv_str = s.recv(1024)
         recv_str = recv_str.decode(request['charset'])
         try:
             resp_dict = {'result_value': json.loads(recv_str)}
         except:
             resp_dict = {'result_value': recv_str}
         self.resp_dict = resp_dict
         return self.resp_dict, ''
     except Exception as e:
         logger.exception('SocketTestPoint execute error, cause: %s',
                          str(e))
         raise Exception('SocketTestPoint execute error, cause: ' + str(e))
     finally:
         if s is not None:
             s.close()
Пример #14
0
    def execute(self, request):
        # 开始逐条执行命令, 捕获并输出异常, 有异常即认为该案例失败
        semaphore_acquired = False
        try:
            logger.info('ui waiting: {}'.format(self._semaphore._value))
            semaphore_acquired = self._semaphore.acquire()
            logger.info('ui executing: {}'.format(self._semaphore._value))
            # 加载浏览器驱动
            self._load_driver(self.tp_conf[UiTestPointEnum.browser_type.key],
                              request)

            # 增加命令计数器,进行计数
            command_num = 0

            for command in self._command_list:
                command_num += 1
                try:
                    execute_result = AgWait(
                        self._driver, 10, ignored_exceptions=Exception).until(
                            lambda x: self.__execute_command(
                                command['command'],
                                self._get_command_param(command['target']),
                                self._get_command_param(command['value'])))

                    # 2019.5.20 修改所有环境 ui 测试都等待时间
                    # local 环境下,每执行一个指令就等待 1s
                    time.sleep(1)
                    # 当最后一条执行的时候,等待 2s
                    if command_num == len(self._command_list):
                        time.sleep(2)

                    if not execute_result:
                        logger.info('ui 测试命令执行失败: 第' + str(command_num) +
                                    '条命令, command=' + command['command'] +
                                    ',target=' + command['target'] +
                                    ',value=' + command['value'])
                        self._execute_flag = False
                        raise RuntimeError('ui 测试命令执行失败: 第' +
                                           str(command_num) + '条命令, command=' +
                                           command['command'] + ',target=' +
                                           command['target'] + ',value=' +
                                           command['value'])
                except NoSuchElementException as e:
                    logger.exception(
                        '第' + str(command_num) +
                        '条命令, ui 测试命令: %s ,没有找到指定页面元素', str(command))
                    self._execute_flag = False
                    raise RuntimeError('第' + str(command_num) +
                                       '条命令, ui 测试命令:' + str(command) +
                                       ',没有找到指定页面元素')
                except NoAlertPresentException as e:
                    logger.exception(
                        '第' + str(command_num) +
                        '条命令, ui 测试命令: %s ,没有 alert 弹框, 建议脚本中添加等待时间',
                        command['command'])
                    self._execute_flag = False
                    raise RuntimeError('第' + str(command_num) +
                                       '条命令, ui 测试命令:' + str(command) +
                                       ',没有 alert 弹框, 建议脚本中添加等待时间')
                except Exception as e:
                    logger.exception(
                        '第' + str(command_num) + '条命令, ui 测试命令: %s ,执行异常',
                        str(command))
                    self._execute_flag = False
                    raise RuntimeError('第' + str(command_num) +
                                       '条命令, ui 测试命令:' + str(command) +
                                       ',执行异常')
                finally:
                    if not self._execute_flag:
                        shot_path = os.path.join(agbot_config.basedir,
                                                 'log/screenshot')
                        if not os.path.exists(shot_path):
                            os.makedirs(shot_path)
                        self._driver.save_screenshot(
                            os.path.join(
                                shot_path, '{}_{}_{}_{}.png'.format(
                                    self.vertical_context.task_context.
                                    task_model.id, self.vertical_context.
                                    job_context.job_model.id, self.
                                    vertical_context.tc_context.tc_detail.id,
                                    self.vertical_context.tc_context.
                                    current_tp_context.id)))

            return {'execute_flag': self._execute_flag}, ''
        finally:
            try:
                # time.sleep(120)
                # 关闭页面, 释放对象
                # 本地环境,出现错误时,不退出
                if not self._execute_flag and self.vertical_context.sys_conf_dict[
                        _root_conf_name]['quit_on_error'] == 'false':
                    pass
                else:
                    self._driver.quit()
            finally:
                if semaphore_acquired:
                    self._semaphore.release()
                    logger.info('ui exit: {}'.format(self._semaphore._value))
Пример #15
0
    def _load_driver(self, driver_type, req_param):
        # 之后驱动包应打入 docker 镜像, 不应再放置在工程目录下
        # 只使用 Chrome 无浏览器模式
        # local 环境下使用与 .exe 同一目录下的 /web_driver/chromedriver.exe
        if driver_type == BrowserType.FIREFOX.value:
            driver_name = 'geckodriver'
            option = webdriver.FirefoxOptions()
        else:
            # 默认是 chrome
            option = webdriver.ChromeOptions()
            driver_name = 'chromedriver'

        driver_path = None
        driver_dir = self.vertical_context.sys_conf_dict[_root_conf_name][
            'driver_dir']
        for root, dirs, files in os.walk(driver_dir):
            for file in files:
                if file.startswith(driver_name):
                    driver_path = os.path.join(root, file)
                    break

        assert driver_path is not None, 'unsupported browser: {}'.format(
            driver_type)

        logger.info('驱动文件路径为: {}'.format(driver_path))

        is_silent_mode = self.vertical_context.sys_conf_dict[_root_conf_name][
            'silent_mode'] == 'true'
        if is_silent_mode:
            # 静默模式
            option.add_argument('--disable-gpu')
            option.add_argument('--headless')
            option.add_argument('--no-sandbox')

        # 使用代理
        if self.tp_conf.get(UiTestPointEnum.proxy_server.key):
            # http://10.153.201.20:8443
            proxy_server = self.tp_conf.get(UiTestPointEnum.proxy_server.key)
            logger.info('ui 测试 添加代理 {}'.format(proxy_server))
            try:
                if driver_type == BrowserType.FIREFOX.value:
                    option.set_preference('network.proxy.type', 1)
                    # IP为你的代理服务器地址:如 ‘127.0.0.0’,字符串类型
                    ip = ':'.join(proxy_server.split(':')[:-1])
                    option.set_preference('network.proxy.http', ip)
                    port = int(proxy_server.split(':')[-1])
                    option.set_preference('network.proxy.http_port', port)
                else:
                    option.add_argument("--proxy-server=" + proxy_server)
            except Exception as ex:
                logger.exception('添加代理错误:{}'.format(ex))
                raise Exception(ex)

        try:
            # firefox
            if driver_type == BrowserType.FIREFOX.value:
                profile = webdriver.FirefoxProfile()
                # 使用手机模式打开
                if self.tp_conf.get(UiTestPointEnum.device_name.key):
                    device_name = self.tp_conf.get(
                        UiTestPointEnum.device_name.key)
                    if device_name.lower().startswith('iphone'):
                        user_agent = (
                            "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) "
                            "AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16"
                        )
                    else:
                        user_agent = (
                            "Firefox 28/Android: Mozilla/5.0 (Android; Mobile; rv:28.0) "
                            "Gecko/24.0 Firefox/28.0")
                    profile.set_preference("general.useragent.override",
                                           user_agent)

                # firefox 禁用缓存
                profile.set_preference("browser.cache.disk.enable", False)
                profile.set_preference("browser.cache.memory.enable", False)
                profile.set_preference("browser.cache.offline.enable", False)

                self._driver = webdriver.Firefox(executable_path=driver_path,
                                                 firefox_profile=profile,
                                                 firefox_options=option)
            else:
                # chrome 限制缓存
                option.add_argument('--disable-dev-shm-usage')
                if self.tp_conf.get(UiTestPointEnum.device_name.key):
                    # 使用手机模式打开
                    mobileEmulation = {
                        'deviceName':
                        self.tp_conf.get(UiTestPointEnum.device_name.key)
                    }
                    option.add_experimental_option('mobileEmulation',
                                                   mobileEmulation)
                self._driver = webdriver.Chrome(executable_path=driver_path,
                                                chrome_options=option)
        except Exception as ex:
            logger.exception(ex)
            raise Exception(ex)

        window_size = self.vertical_context.sys_conf_dict[_root_conf_name].get(
            'window_size')
        if window_size:
            # 设定窗口尺寸以使截图范围更大
            window_size_tuple = window_size.split(',')
            self._driver.set_window_size(int(window_size_tuple[0]),
                                         int(window_size_tuple[1]))
        else:
            self._driver.maximize_window()
Пример #16
0
    def execute(self, request):
        content = request.get('content')
        # 请求地址可从数据文件中读取
        api_url = self.tp_conf.get('http_url')
        # 获取 http 请求方法名称
        method = self.tp_conf.get('http_method')
        # 发起接口调用请求并接收响应
        try:
            # 反射得到 http 的方法
            exec_func = getattr(requests, method.lower())
            # 请求超时时间
            try:
                timeout = int(self.tp_conf.get('timeout', 10))
            except Exception as _:
                timeout = 10
            timeout = min(timeout, 120)

            # 20190315 edit by jun.hu
            #  根据  conf 中的 content-type 来决定请求数据组织方式
            if self.__header.get('Content-Type') == 'application/json':
                response = exec_func(api_url,
                                     json=content,
                                     headers=self.__header,
                                     files=self.__file,
                                     timeout=timeout)
            else:
                if method.lower() == 'delete':
                    response = exec_func(api_url,
                                         headers=self.__header,
                                         timeout=timeout)
                else:
                    files = self.__file
                    response = exec_func(api_url,
                                         content,
                                         headers=self.__header,
                                         files=files,
                                         timeout=timeout)

            self.__resp_code = str(response.status_code)

            try:
                content = response.json()
                logger.info('[{}, {}, {}] tp->api load as json: {}, {}'.format(
                    self.vertical_context.task_context.task_model.id,
                    self.vertical_context.job_context.job_model.id,
                    self.vertical_context.tc_context.tc_detail.id,
                    response.status_code, content))
                return content, self.__resp_code
            except JSONDecodeError as e:
                logger.info(
                    '[{}, {}, {}] tp->api load as json error: {}, {}'.format(
                        self.vertical_context.task_context.task_model.id,
                        self.vertical_context.job_context.job_model.id,
                        self.vertical_context.tc_context.tc_detail.id,
                        response.status_code, response.text))
                pass

            try:
                content = self.__get_xml_dict(response.text)
                logger.info('[{}, {}, {}] tp->api load as xml: {}, {}'.format(
                    self.vertical_context.task_context.task_model.id,
                    self.vertical_context.job_context.job_model.id,
                    self.vertical_context.tc_context.tc_detail.id,
                    response.status_code, content))
                return content, self.__resp_code
            except Exception as e:
                logger.info(
                    '[{}, {}, {}] tp->api load as xml error: {}, {}'.format(
                        self.vertical_context.task_context.task_model.id,
                        self.vertical_context.job_context.job_model.id,
                        self.vertical_context.tc_context.tc_detail.id,
                        response.status_code, response.text))
                pass

            if isinstance(response.text, str) and self.tp_conf.get(
                    'resp_default_key', ''):
                return {
                    self.tp_conf.get('resp_default_key'): response.text
                }, self.__resp_code

            return response.text, self.__resp_code

        except RequestException as e:
            logger.error('[{}, {}, {}] tp->api连接异常'.format(
                self.vertical_context.task_context.task_model.id,
                self.vertical_context.job_context.job_model.id,
                self.vertical_context.tc_context.tc_detail.id))
            raise RuntimeError('api连接异常, {}'.format(str(e)))
        except RuntimeError as e:
            logger.exception('[{}, {}, {}] tp->api运行时异常, {}'.format(
                self.vertical_context.task_context.task_model.id,
                self.vertical_context.job_context.job_model.id,
                self.vertical_context.tc_context.tc_detail.id, str(e)))
            raise RuntimeError('api运行时异常, {}'.format(str(e)))
Пример #17
0
    def test_status(self):
        tc_ctx = self.vertical_context.tc_context
        try:
            # 配置的期望参数名称
            if self.tp_conf.get('expect_data'):
                self.resolve_expect_data(tc_ctx)

                params_name_list = self.tp_conf.get('expect_data').split(
                    ',(?=(?:[^\"]*(?:"[^\"]*")?[^\"]*)*$)')
                # 如果期望判断首个值满足表达式,则认为是表达式
                if exp.is_exp(params_name_list[0]):
                    diff_key_set = set()
                    for e in params_name_list:
                        if not self.run_exp(e):
                            diff_key_set.add(e)

                    if not diff_key_set:
                        return TestStatus.PASSED
                    else:
                        logger.info(
                            '[{}, {}, {}] tp->api 断言不通过: {} @ {}'.format(
                                self.vertical_context.task_context.task_model.
                                id,
                                self.vertical_context.job_context.job_model.id,
                                self.vertical_context.tc_context.tc_detail.id,
                                params_name_list,
                                self.vertical_context.tc_context))
                        return TestStatus.NOT_PASSED

            # 获取数据文件期望返回的状态码
            if self.tp_conf.get('expect_resp_code'):
                if self.__resp_code != self.tp_conf.get('expect_resp_code'):
                    return TestStatus.NOT_PASSED
                else:
                    return TestStatus.PASSED

            # 是否需要 urldecode
            if self.tp_conf.get('resp_urldecode_name'):
                name_list = self.tp_conf.get('resp_urldecode_name').split(',')
                response_str = self.__response_urldecode(
                    str(tc_ctx.current_tp_context.response.content), name_list)
            else:
                response_str = tc_ctx.current_tp_context.response.content

            if response_str is not None:
                # 校验期望值,验证返回码是否与期望返回码保持一致
                diff_key_set = set()
                diff_key_set = self.__expect_dict_check(
                    self.expect_dict,
                    tc_ctx.current_tp_context.response.content, diff_key_set)

                check_expect_flag = not diff_key_set
                check_type = self.tp_conf.get('check_type') \
                    if self.tp_conf.get('check_type') else CheckExpectType.EQUAL.value
                if CheckExpectType.UNEQUAL.value == check_type:
                    if check_expect_flag:
                        check_expect_flag = TestStatus.NOT_PASSED
                    else:
                        check_expect_flag = TestStatus.PASSED
                else:
                    if check_expect_flag:
                        check_expect_flag = TestStatus.PASSED
                    else:
                        check_expect_flag = TestStatus.NOT_PASSED

                logger.info('check result:' + str(check_expect_flag) +
                            ' diff set:' + str(diff_key_set))
            else:
                check_expect_flag = TestStatus.NOT_PASSED
                logger.info('check result:' + str(check_expect_flag) +
                            ' target response is none.')

        except Exception as e:
            logger.exception('[{}, {}, {}] tp->api期望值判断异常: {} @ {}'.format(
                self.vertical_context.task_context.task_model.id,
                self.vertical_context.job_context.job_model.id,
                self.vertical_context.tc_context.tc_detail.id, str(e),
                self.vertical_context.tc_context))
            raise Exception('期望值判断异常: {}: {}'.format(str(e.__class__.__name__),
                                                     str(e)))

        return check_expect_flag