async def debug_single_testcase(project_meta: ProjectMeta, testcase: TestCase): resp = {"code": 0, "message": "success", "result": {}} project_meta_json = project_meta.dict(by_alias=True) if project_meta.debugtalk_py: origin_local_keys = list(locals().keys()).copy() exec(project_meta.debugtalk_py, {}, locals()) new_local_keys = list(locals().keys()).copy() new_added_keys = set(new_local_keys) - set(origin_local_keys) new_added_keys.remove("origin_local_keys") project_meta_json["functions"] = {} for func_name in new_added_keys: project_meta_json["functions"][func_name] = locals()[func_name] testcase_json = testcase.dict(by_alias=True) tests_mapping = { "project_mapping": project_meta_json, "testcases": [testcase_json] } summary = runner.run_tests(tests_mapping) if not summary["success"]: resp["code"] = 1 resp["message"] = "fail" resp["result"] = summary return resp
def load_project_meta(test_path: Text, reload: bool = False) -> ProjectMeta: """ load api, testcases, .env, debugtalk.py functions. api/testcases folder is relative to project_working_directory by default, project_meta will be loaded only once, unless set reload to true. Args: test_path (str): test file/folder path, locate pwd from this path. reload: reload project meta if set true, default to false Returns: project loaded api/testcases definitions, environments and debugtalk.py functions. """ global project_meta if project_meta and (not reload): return project_meta project_meta = ProjectMeta() if not test_path: return project_meta debugtalk_path, project_working_directory = locate_project_working_directory( test_path ) # add PWD to sys.path sys.path.insert(0, project_working_directory) # load .env file # NOTICE: # environment variable maybe loaded in debugtalk.py # thus .env file should be loaded before loading debugtalk.py dot_env_path = os.path.join(project_working_directory, ".env") project_meta.env = load_dot_env_file(dot_env_path) if debugtalk_path: # load debugtalk.py functions debugtalk_functions = load_debugtalk_functions() else: debugtalk_functions = {} # locate PWD and load debugtalk.py functions project_meta.PWD = project_working_directory project_meta.functions = debugtalk_functions project_meta.test_path = os.path.abspath(test_path)[ len(project_working_directory) + 1 : ] return project_meta
async def debug_single_testcase(project_meta: ProjectMeta, testcase: TestCase): resp = {"code": 0, "message": "success", "result": {}} if project_meta.debugtalk_py: origin_local_keys = list(locals().keys()).copy() exec(project_meta.debugtalk_py, {}, locals()) new_local_keys = list(locals().keys()).copy() new_added_keys = set(new_local_keys) - set(origin_local_keys) new_added_keys.remove("origin_local_keys") for func_name in new_added_keys: project_meta.functions[func_name] = locals()[func_name] runner.with_project_meta(project_meta).run_testcase(testcase) summary = runner.get_summary() if not summary.success: resp["code"] = 1 resp["message"] = "fail" resp["result"] = summary.dict() return resp
def run(self, testcase: TestCase): """main entrance""" self.config = testcase.config self.teststeps = testcase.teststeps self.config.variables.update(self.__session_variables) if self.config.path: self.__project_meta = load_project_meta(self.config.path) elif not self.__project_meta: self.__project_meta = ProjectMeta() def parse_config(config: TConfig): config.variables = parse_variables_mapping( config.variables, self.__project_meta.functions) config.name = parse_data(config.name, config.variables, self.__project_meta.functions) config.base_url = parse_data(config.base_url, config.variables, self.__project_meta.functions) parse_config(self.config) self.__start_at = time.time() self.__step_datas: List[StepData] = [] self.__session_variables = {} for step in self.teststeps: # update with config variables step.variables.update(self.config.variables) # update with session variables extracted from pre step step.variables.update(self.__session_variables) # parse variables step.variables = parse_variables_mapping( step.variables, self.__project_meta.functions) # run step extract_mapping = self.__run_step(step) # save extracted variables to session variables self.__session_variables.update(extract_mapping) self.__duration = time.time() - self.__start_at return self
def load_project_meta(test_path: Text) -> ProjectMeta: """ load api, testcases, .env, debugtalk.py functions. api/testcases folder is relative to project_working_directory Args: test_path (str): test file/folder path, locate pwd from this path. Returns: project loaded api/testcases definitions, environments and debugtalk.py functions. """ project_meta = ProjectMeta() if not test_path: return project_meta if test_path in project_meta_cached_mapping: return project_meta_cached_mapping[test_path] debugtalk_path, project_working_directory = init_project_working_directory( test_path) # load .env file # NOTICE: # environment variable maybe loaded in debugtalk.py # thus .env file should be loaded before loading debugtalk.py dot_env_path = os.path.join(project_working_directory, ".env") project_meta.env = load_dot_env_file(dot_env_path) if debugtalk_path: # load debugtalk.py functions debugtalk_functions = load_debugtalk_functions() else: debugtalk_functions = {} # locate PWD and load debugtalk.py functions project_meta.PWD = project_working_directory project_meta.functions = debugtalk_functions project_meta.test_path = os.path.abspath( test_path)[len(project_working_directory) + 1:] project_meta_cached_mapping[test_path] = project_meta return project_meta