def test_ensure_testcase_v3(self): testcase_content = { "config": {"name": "xxx", "base_url": "https://httpbin.org"}, "teststeps": [ { "name": "get with params", "request": { "method": "GET", "url": "/get", "params": {"foo1": "bar1", "foo2": "bar2"}, "headers": {"User-Agent": "HttpRunner/3.0"}, }, "extract": [ {"varA": "content.varA"}, {"user_agent": "headers.User-Agent"}, ], "validate": [ {"eq": ["content.varB", 200]}, {"lt": ["json.0.varC", 0]}, ], } ], } self.assertEqual( compat.ensure_testcase_v3(testcase_content), { "config": {"name": "xxx", "base_url": "https://httpbin.org"}, "teststeps": [ { "name": "get with params", "request": { "method": "GET", "url": "/get", "params": {"foo1": "bar1", "foo2": "bar2"}, "headers": {"User-Agent": "HttpRunner/3.0"}, }, "extract": { "varA": "body.varA", "user_agent": 'headers."User-Agent"', }, "validate": [ {"eq": ["body.varB", 200]}, {"lt": ["body[0].varC", 0]}, ], } ], }, )
def make_testcase(testcase: Dict, dir_path: Text = None) -> Text: """convert valid testcase dict to pytest file path""" # ensure compatibility with testcase format v2 testcase = ensure_testcase_v3(testcase) # validate testcase format load_testcase(testcase) testcase_abs_path = __ensure_absolute(testcase["config"]["path"]) logger.info(f"start to make testcase: {testcase_abs_path}") testcase_python_abs_path, testcase_cls_name = convert_testcase_path( testcase_abs_path) if dir_path: testcase_python_abs_path = os.path.join( dir_path, os.path.basename(testcase_python_abs_path)) global pytest_files_made_cache_mapping if testcase_python_abs_path in pytest_files_made_cache_mapping: return testcase_python_abs_path config = testcase["config"] config["path"] = convert_relative_project_root_dir( testcase_python_abs_path) config["variables"] = convert_variables(config.get("variables", {}), testcase_abs_path) # prepare reference testcase imports_list = [] teststeps = testcase["teststeps"] for teststep in teststeps: if not teststep.get("testcase"): continue # make ref testcase pytest file ref_testcase_path = __ensure_absolute(teststep["testcase"]) test_content = load_test_file(ref_testcase_path) # api in v2 format, convert to v3 testcase if "request" in test_content and "name" in test_content: test_content = ensure_testcase_v3_api(test_content) test_content.setdefault("config", {})["path"] = ref_testcase_path ref_testcase_python_abs_path = make_testcase(test_content) # override testcase export ref_testcase_export: List = test_content["config"].get("export", []) if ref_testcase_export: step_export: List = teststep.setdefault("export", []) step_export.extend(ref_testcase_export) teststep["export"] = list(set(step_export)) # prepare ref testcase class name ref_testcase_cls_name = pytest_files_made_cache_mapping[ ref_testcase_python_abs_path] teststep["testcase"] = ref_testcase_cls_name # prepare import ref testcase ref_testcase_python_relative_path = convert_relative_project_root_dir( ref_testcase_python_abs_path) ref_module_name, _ = os.path.splitext( ref_testcase_python_relative_path) ref_module_name = ref_module_name.replace(os.sep, ".") import_expr = f"from {ref_module_name} import TestCase{ref_testcase_cls_name} as {ref_testcase_cls_name}" if import_expr not in imports_list: imports_list.append(import_expr) testcase_path = convert_relative_project_root_dir(testcase_abs_path) # current file compared to ProjectRootDir diff_levels = len(testcase_path.split(os.sep)) data = { "version": __version__, "testcase_path": testcase_path, "diff_levels": diff_levels, "class_name": f"TestCase{testcase_cls_name}", "imports_list": imports_list, "config_chain_style": make_config_chain_style(config), "customization_test_start": make_test_start_style(config), "teststeps_chain_style": [make_teststep_chain_style(step) for step in teststeps], } content = __TEMPLATE__.render(data) # ensure new file's directory exists dir_path = os.path.dirname(testcase_python_abs_path) if not os.path.exists(dir_path): os.makedirs(dir_path) with open(testcase_python_abs_path, "w", encoding="utf-8") as f: f.write(content) pytest_files_made_cache_mapping[ testcase_python_abs_path] = testcase_cls_name __ensure_testcase_module(testcase_python_abs_path) logger.info(f"generated testcase: {testcase_python_abs_path}") return testcase_python_abs_path
def __make_testcase(testcase: Dict, dir_path: Text = None) -> NoReturn: """convert valid testcase dict to pytest file path""" # ensure compatibility with testcase format v2 testcase = ensure_testcase_v3(testcase) # validate testcase format load_testcase(testcase) testcase_path = __ensure_absolute(testcase["config"]["path"]) logger.info(f"start to make testcase: {testcase_path}") testcase_python_path, testcase_cls_name = convert_testcase_path( testcase_path) if dir_path: testcase_python_path = os.path.join( dir_path, os.path.basename(testcase_python_path)) global make_files_cache_set if testcase_python_path in make_files_cache_set: return config = testcase["config"] config["path"] = __ensure_cwd_relative(testcase_python_path) # parse config variables config.setdefault("variables", {}) if isinstance(config["variables"], Text): # get variables by function, e.g. ${get_variables()} project_meta = load_project_meta(testcase_path) config["variables"] = parse_data(config["variables"], {}, project_meta.functions) # prepare reference testcase imports_list = [] teststeps = testcase["teststeps"] for teststep in teststeps: if not teststep.get("testcase"): continue # make ref testcase pytest file ref_testcase_path = __ensure_absolute(teststep["testcase"]) __make(ref_testcase_path) # prepare ref testcase class name ref_testcase_python_path, ref_testcase_cls_name = convert_testcase_path( ref_testcase_path) teststep["testcase"] = f"CLS_LB({ref_testcase_cls_name})CLS_RB" # prepare import ref testcase ref_testcase_python_path = ref_testcase_python_path[len(os.getcwd()) + 1:] ref_module_name, _ = os.path.splitext(ref_testcase_python_path) ref_module_name = ref_module_name.replace(os.sep, ".") imports_list.append( f"from {ref_module_name} import TestCase{ref_testcase_cls_name} as {ref_testcase_cls_name}" ) data = { "testcase_path": __ensure_cwd_relative(testcase_path), "class_name": f"TestCase{testcase_cls_name}", "config": config, "teststeps": teststeps, "imports_list": imports_list, } content = __TEMPLATE__.render(data) content = content.replace("'CLS_LB(", "").replace(")CLS_RB'", "") with open(testcase_python_path, "w", encoding="utf-8") as f: f.write(content) __ensure_testcase_module(testcase_python_path) logger.info(f"generated testcase: {testcase_python_path}") make_files_cache_set.add(__ensure_cwd_relative(testcase_python_path))
def make_testcase(testcase: Dict, dir_path: Text = None) -> Text: """convert valid testcase dict to pytest file path""" # ensure compatibility with testcase format v2 testcase = ensure_testcase_v3(testcase) # validate testcase format load_testcase(testcase) testcase_abs_path = __ensure_absolute(testcase["config"]["path"]) logger.info(f"start to make testcase: {testcase_abs_path}") testcase_python_path, testcase_cls_name = convert_testcase_path( testcase_abs_path) if dir_path: testcase_python_path = os.path.join( dir_path, os.path.basename(testcase_python_path)) global pytest_files_made_cache_mapping if testcase_python_path in pytest_files_made_cache_mapping: return testcase_python_path config = testcase["config"] config["path"] = __ensure_cwd_relative(testcase_python_path) config["variables"] = convert_variables(config.get("variables", {}), testcase_abs_path) # prepare reference testcase imports_list = [] teststeps = testcase["teststeps"] for teststep in teststeps: if not teststep.get("testcase"): continue # make ref testcase pytest file ref_testcase_path = __ensure_absolute(teststep["testcase"]) test_content = load_test_file(ref_testcase_path) test_content.setdefault("config", {})["path"] = ref_testcase_path ref_testcase_python_path = make_testcase(test_content) # prepare ref testcase class name ref_testcase_cls_name = pytest_files_made_cache_mapping[ ref_testcase_python_path] teststep["testcase"] = ref_testcase_cls_name # prepare import ref testcase ref_testcase_python_path = ref_testcase_python_path[len(os.getcwd()) + 1:] ref_module_name, _ = os.path.splitext(ref_testcase_python_path) ref_module_name = ref_module_name.replace(os.sep, ".") imports_list.append( f"from {ref_module_name} import TestCase{ref_testcase_cls_name} as {ref_testcase_cls_name}" ) data = { "version": __version__, "testcase_path": __ensure_cwd_relative(testcase_abs_path), "class_name": f"TestCase{testcase_cls_name}", "imports_list": imports_list, "config_chain_style": make_config_chain_style(config), "teststeps_chain_style": [make_teststep_chain_style(step) for step in teststeps], } content = __TEMPLATE__.render(data) # ensure new file's directory exists dir_path = os.path.dirname(testcase_python_path) if not os.path.exists(dir_path): os.makedirs(dir_path) with open(testcase_python_path, "w", encoding="utf-8") as f: f.write(content) pytest_files_made_cache_mapping[testcase_python_path] = testcase_cls_name __ensure_testcase_module(testcase_python_path) logger.info(f"generated testcase: {testcase_python_path}") return testcase_python_path