def _format_data(data: (str, dict)) -> dict: ensure_type(data, (str, dict)) if isinstance(data, dict): return data key = None func_name, *args = data.split() if '=' in func_name: key, func_name = split_and_strip(func_name, '=') _kwargs = { item.split('=', 1)[0]: item.split('=', 1)[1] for item in args if '=' in item } _args = [item for item in args if '=' not in item] if _args and _kwargs: _args.append(_kwargs) kwargs = _args else: kwargs = _kwargs or _args print('kwargs', kwargs) _data = {func_name: kwargs} if key: _data['extract'] = [{key: '$result'}] return _data
def register_config(self, config: dict): ensure_type(config, dict) if 'variables' in config: _variables = config.pop('variables') ensure_type(_variables, dict) self.register_variables(_variables) self._config.update(config)
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
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})
def dubbo(data: dict, context): ensure_type(data, dict) host = data.get('host') port = data.get('port') service = data.get('service') method = data.get('method') params = data.get('params') client = Dubbo(host=host, port=port) result = client.invoke(service, method, params) return result
def __init__(self, data: dict, parent=None): ensure_type(data, dict) self._raw = data self._parent = parent self._name = data.get('name') self._skip = data.get('skip') self._tags = data.get('tags') self._level = data.get('level') self._parameters = data.get('parameters') self._steps = [] self.build_steps()
def __init__(self, data: dict, path=None): ensure_type(data, dict) self._raw = data self._path = path self._name = data.get('name') self._config = self._raw.get('config') self._variables = self._raw.get('variables') self._cases = [] self._keywords = [] self.build_cases() self.build_keywords()
def __init__(self, key: str, data: dict, parent=None): ensure_type(key, str) ensure_type(data, dict) self._key = key self._raw = data self._parent = parent self._docs = data.get('docs') self._args = data.get('args') self._skip = data.get('skip') self._steps = [] self._return = data.get('return') self.build_steps()
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
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
def _guess_steps(data: dict): ensure_type(data, dict) extra_keys = data.keys() - CASE_BUILD_INS if extra_keys: steps = [{key: data.get(key) for key in extra_keys}] return steps
def register_variables(self, variables: dict): ensure_type(variables, dict) self._variables.update(variables)
def dot_get(self, expr: str): """解析并获取变量值, expr: $a""" ensure_type(expr, str) return parser.dot_get(expr, self._variables)
def build_cases(self): _cases = self._raw.get('tests') or self._raw.get('testcases') if _cases: ensure_type(_cases, list) for _case in _cases: self._cases.append(Case(_case, parent=self))
def _get_step_target_function(self, step): _target = step._target ensure_type(_target, str) function = self._context.get_function(_target) kwargs = self._context.parse(step._kwargs) return function, kwargs
def build_keywords(self): _keywords = self._raw.get('keywords') if _keywords: ensure_type(_keywords, dict) for key, value in _keywords.items(): self._keywords.append(Keyword(key, value, parent=self))
def build_steps(self): # todo remove _steps = self._raw.get('steps') or _guess_steps(self._raw) if _steps: ensure_type(_steps, list) for _step in _steps: self._steps.append(Step(_step, parent=self))