コード例 #1
0
def request(data, context):
    log.info('执行请求步骤: ', data.get(NAME))
    req = data.get(REQUEST)
    variables = context.get(VAIABLES)  # todo 改为result
    config = context.get(CONFIG)
    context.setdefault(REQUEST_SESSION, requests.session())
    session = context.get(REQUEST_SESSION)
    if config and isinstance(config, dict):
        # 组装url
        pack_url(config, req)
        # 设置默认请求想
        set_default_request(config, session)

    # 设置默认方法
    set_default_method(req)

    if req and isinstance(req, dict):
        res = session.request(**req)
        # 注册变量
        variables['response'] = res
        variables['response_json'] = res.json()  # todo
        variables['content'] = res.json()  # todo
        variables['status_code'] = res.status_code

        log.debug('请求数据:', req, '响应数据:', res.text)
        return res
コード例 #2
0
 def _run_step_with_times(self, step, times: int, context):
     """多轮运行"""
     ensure_type(times, int)
     results = []
     for i in range(times):
         logging.info(f'  运行Step {step} 第{i + 1}轮')
         results.append(self._run_step(step, context))
     return results
コード例 #3
0
 def sequence_run(self):
     results = []
     for i in range(self.times):
         log.info('执行步骤:', self.name, f'第{i+1}轮' if self.times > 1 else '')
         result = self.run(self.data, self.context)
         results.append(result)
         self.context['result'] = self.result
     return results
コード例 #4
0
 def do_extract(self, extract: list):
     """处理提取变量"""
     for line in extract:
         logging.info(f'  提取变量: {line}')
         key, expr = tuple(line.items())[0]
         ensure_type(expr, str)
         ensure_type(key, str)
         value = self._context.dot_get(expr)
         logging.info(f'  注册变量: {key}={value}')
         self._context.register_variables({key: value})
コード例 #5
0
 def should_skip(self):
     skip = self.skip
     if isinstance(skip, str):
         try:
             skip = eval(skip)
         except Exception as ex:
             log.exception(ex)
             log.info('跳过步骤:', self.name, '原因: skip表达式出错')
             return True
     if skip:
         log.info('跳过步骤:', self.name, f'原因: skip={self.skip}')
     return skip
コード例 #6
0
    def parallel_run(self):
        times = self.times // self.concurrency
        results = []
        for i in range(times):
            log.info(
                '执行步骤:', self.name,
                f'第{i+1}轮 并发量: {self.concurrency}' if self.times > 1 else '')

            threads = [
                MyThread(self.run, self.data, self.context)
                for i in range(self.concurrency)
            ]
            [t.start() for t in threads]
            [t.join() for t in threads]
            results.extend([t.result for t in threads])
コード例 #7
0
 def do_validate(self, validate):
     """处理断言"""
     for line in validate:
         logging.info(f'  处理断言: {line}')
         if 'comparator' in line:
             comparator = line.get('comparator')
             check = line.get('check')
             expect = line.get('expect')
         else:
             comparator, value = tuple(line.items())[0]
             check, expect = value
         compare_func = COMPARE_FUNCS.get(comparator)
         field = self._context.dot_get(check.strip('.'))
         assert compare_func(
             field, expect
         ), f'表达式: {check} 实际结果: {field} not {comparator} 期望结果: {expect}'
コード例 #8
0
def request(data: (list, dict), context):
    ensure_type(data, (list, dict))
    if isinstance(data, list):
        method, url, *_data = data
        data = {'method': method, 'url': url}
        if _data:
            [data.update(item) for item in _data if isinstance(item, dict)]

    _session = context._variables.get('_session')
    base_url = context._variables.get('_base_url')
    if not _session:
        _session = requests.Session()
        context.register_variables({'_session': _session})

        _config = context._config
        if _config:
            ensure_type(_config, dict)
            _request_config = _config.get('request')
            if _request_config:
                ensure_type(_request_config, dict)
                if 'base_url' in _request_config:
                    base_url = _request_config.pop('base_url')
                    ensure_type(base_url, str)
                    context.register_variables({'_base_url': base_url})

                for key, value in _request_config.items():
                    try:
                        setattr(_session, key, value)  # todo 异常处理
                    except:
                        logging.warning(f'Session会话不支持设置属性: {key}={value}')

    url = data.get('url', '')
    ensure_type(url, str)
    if base_url and not url.startswith('http'):
        data['url'] = '/'.join((base_url.rstrip('/'), url.lstrip('/')))

    res = _session.request(**data)

    context.register_variables(
        {
            'content': res.json(),  # todo
            'status_code': res.status_code
        }
    )

    logging.info(res.text[:300])
    return res
コード例 #9
0
    def _run_step_with_concurrency(self, step, times: int, concurrency: int,
                                   context):
        """多轮多线程并发运行"""
        ensure_type(times, int)
        ensure_type(concurrency, int)
        results = []
        times = times // concurrency
        for i in range(times):
            logging.info(f'  运行Step {step} 第{i + 1}轮 并发数: {concurrency}')
            results.extend(
                self._run_step_in_threads(step, concurrency, context))

        mod = times % concurrency  # 余数
        if mod:
            logging.info(f'运行Step {step} 第{times + 1}轮 并发数: {mod}')
            results.extend(self._run_step_in_threads(step, mod, context))
        return results
コード例 #10
0
    def run_suite(self, suite, result):
        """基础运行suite方法"""
        log.info('执行测试套件:', suite)
        topLevel = False
        if getattr(result, '_testRunEntered', False) is False:
            result._testRunEntered = topLevel = True

        for index, test in enumerate(suite):
            if isnotsuite(test):
                setup_ok = run_suite_before_case(suite, test, result)
                if not setup_ok:
                    continue
            self.run_test(test, result)
            if suite._cleanup:
                suite._removeTestAtIndex(index)

        if topLevel:
            run_suite_after(suite, result)
            result._testRunEntered = False

        return result
コード例 #11
0
    def run_suite(self, suite, result, run_func=None, interval=None):
        """基础运行suite方法,支持指定运行方法"""
        log.info('执行测试套件:', suite)
        topLevel = False
        if getattr(result, '_testRunEntered', False) is False:
            result._testRunEntered = topLevel = True

        for index, test in enumerate(suite):
            if _isnotsuite(test):
                setup_ok = run_suite_before_case(suite, test, result)
                if not setup_ok:
                    continue
            log.info('执行用例:', test.id())
            run_func(test, result) if run_func else test(result)  # 可能是suite 可能有异常
            log.info('执行结果:', test.status, '执行时间:', test.duration)
            time.sleep(interval) if interval else None

            if suite._cleanup:
                suite._removeTestAtIndex(index)

        if topLevel:
            run_suite_after(suite, result)
            result._testRunEntered = False

        return result
コード例 #12
0
    def run_step(self, step: models.Step, context=None):
        context = context or self._context
        skip, reason = self._should_skip(step, context)
        if skip:
            logging.info(f'  跳过Step {step} {reason}')
            return

        times = step._times
        concurrency = step._concurrency

        # 1. 无times, 只执行一次
        if not times:
            logging.info(f'  运行Step {step}')
            return self._run_step(step, context)

        # 3. 有times, 无concurrency, 顺序执行多轮
        if not concurrency:
            return self._run_step_with_times(step, times, context)

        # 3. 有times和concurrency
        return self._run_step_with_concurrency(step, times, concurrency,
                                               context)
コード例 #13
0
    def wapper(data, context):  # todo
        # tests = parse(tests, context)
        name = data.get(NAME)
        extract = data.get(EXTRACT)
        check = data.get(CHECK)

        if name:
            log.info('执行步骤', name)

        status = 'pass'
        try:
            result = func(data, context)
        except AssertionError as ex:
            log.exception(ex)
            return 'fail', None
        except Exception as ex:
            log.exception(ex)
            return 'error', None
        else:
            if extract:
                do_extract(extract, context)
            if check:
                status = do_check(check, context)
        return status, result
コード例 #14
0
    def _register_suite(self, suite):
        if suite._config:
            logging.info('注册Suite.config')
            self._context.register_config(suite._config)
        if suite._variables:  # 优先级高于config.variales
            logging.info('注册Suite.varaible')
            self._context.register_variables(suite._variables)

        if suite._keywords:
            logging.info('注册Suite.keywords')
            [self._register_keyword(keyword) for keyword in suite._keywords]
コード例 #15
0
def log(data: (str, list, dict), context):
    if isinstance(data, list):
        logging.info(*data)  # todo
    else:
        logging.info(data)
コード例 #16
0
        if suite._keywords:
            logging.info('注册Suite.keywords')
            [self._register_keyword(keyword) for keyword in suite._keywords]

    def run_suite(self, suite):
        self._register_suite(suite)
        logging.info('运行Suite', suite)
        for case in suite._cases:
            self.run_case(case)

    def run_case(self, case, context=None):
        context = context or self._context
        skip, reason = self._should_skip(case, context)
        if skip:
            logging.info(f' 跳过Case {case} {reason}')
            return
        logging.info(f' 运行Case {case}')
        for step in case._steps:
            self.run_step(step)

    def do_extract(self, extract: list):
        """处理提取变量"""
        for line in extract:
            logging.info(f'  提取变量: {line}')
            key, expr = tuple(line.items())[0]
            ensure_type(expr, str)
            ensure_type(key, str)
            value = self._context.dot_get(expr)
            logging.info(f'  注册变量: {key}={value}')
            self._context.register_variables({key: value})
コード例 #17
0
 def run_suite(self, suite):
     self._register_suite(suite)
     logging.info('运行Suite', suite)
     for case in suite._cases:
         self.run_case(case)
コード例 #18
0
 def setUpClass(cls):
     self._register_suite(suite)
     logging.info('运行Suite', suite)