refactor: use step export to export session variables from referenced testcase

This commit is contained in:
debugtalk
2020-06-05 11:31:51 +08:00
parent 992f17dc92
commit d2088c661b
7 changed files with 39 additions and 35 deletions
@@ -11,7 +11,7 @@ teststeps:
variables: variables:
foo1: override_bar1 foo1: override_bar1
testcase: request_methods/request_with_functions.yml testcase: request_methods/request_with_functions.yml
extract: export:
- session_foo2 - session_foo2
- -
name: post form data name: post form data
@@ -26,7 +26,7 @@ class TestCaseRequestWithTestcaseReference(HttpRunner):
RunTestCase("request with functions") RunTestCase("request with functions")
.with_variables(**{"foo1": "override_bar1"}) .with_variables(**{"foo1": "override_bar1"})
.call(RequestWithFunctions) .call(RequestWithFunctions)
.extract(*["session_foo2"]) .export(*["session_foo2"])
), ),
Step( Step(
RunRequest("post form data") RunRequest("post form data")
+6 -6
View File
@@ -133,10 +133,10 @@ def ensure_step_attachment(step: Dict) -> Dict:
test_dict["teardown_hooks"] = step["teardown_hooks"] test_dict["teardown_hooks"] = step["teardown_hooks"]
if "extract" in step: if "extract" in step:
if step.get("request"): test_dict["extract"] = convert_extractors(step["extract"])
test_dict["extract"] = convert_extractors(step["extract"])
elif step.get("testcase"): if "export" in step:
test_dict["extract"] = step["extract"] test_dict["export"] = step["export"]
if "validate" in step: if "validate" in step:
test_dict["validate"] = convert_validators(step["validate"]) test_dict["validate"] = convert_validators(step["validate"])
@@ -167,8 +167,6 @@ def ensure_testcase_v3(test_content: Dict) -> Dict:
for step in test_content["teststeps"]: for step in test_content["teststeps"]:
teststep = {} teststep = {}
teststep.update(ensure_step_attachment(step))
if "request" in step: if "request" in step:
teststep["request"] = step.pop("request") teststep["request"] = step.pop("request")
elif "api" in step: elif "api" in step:
@@ -176,6 +174,8 @@ def ensure_testcase_v3(test_content: Dict) -> Dict:
elif "testcase" in step: elif "testcase" in step:
teststep["testcase"] = step.pop("testcase") teststep["testcase"] = step.pop("testcase")
teststep.update(ensure_step_attachment(step))
teststep = sort_step_by_custom_order(teststep) teststep = sort_step_by_custom_order(teststep)
v3_content["teststeps"].append(teststep) v3_content["teststeps"].append(teststep)
+11 -12
View File
@@ -220,18 +220,16 @@ def make_teststep_chain_style(teststep: Dict) -> Text:
call_ref_testcase = f".call({testcase})" call_ref_testcase = f".call({testcase})"
step_info += call_ref_testcase step_info += call_ref_testcase
extract_info = teststep.get("extract") if "extract" in teststep:
if extract_info: # request step
if isinstance(extract_info, Dict): step_info += ".extract()"
# request step for extract_name, extract_path in teststep["extract"].items():
step_info += ".extract()" step_info += f'.with_jmespath("{extract_path}", "{extract_name}")'
for extract_name, extract_path in extract_info.items():
step_info += f'.with_jmespath("{extract_path}", "{extract_name}")' if "export" in teststep:
elif isinstance(extract_info, List): # reference testcase step
# reference testcase step export: List[Text] = teststep["export"]
step_info += f".extract(*{extract_info})" step_info += f".export(*{export})"
else:
raise exceptions.TestCaseFormatError(f"Invalid extract: {extract_info}")
if "validate" in teststep: if "validate" in teststep:
step_info += ".validate()" step_info += ".validate()"
@@ -455,6 +453,7 @@ def main_make(tests_paths: List[Text]) -> List[Text]:
pytest_files_set.update(make_files_cache_set) pytest_files_set.update(make_files_cache_set)
pytest_files_list = list(pytest_files_set) pytest_files_list = list(pytest_files_set)
# TODO: format referenced testcase
format_pytest_with_black(*pytest_files_list) format_pytest_with_black(*pytest_files_list)
return pytest_files_list return pytest_files_list
+4 -1
View File
@@ -66,7 +66,10 @@ class TStep(BaseModel):
variables: VariablesMapping = {} variables: VariablesMapping = {}
setup_hooks: Hook = [] setup_hooks: Hook = []
teardown_hooks: Hook = [] teardown_hooks: Hook = []
extract: Union[Dict[Text, Text], List[Text]] = {} # used to extract request's response field
extract: Dict[Text, Text] = {}
# used to export session variables from referenced testcase
export: List[Text] = []
validators: Validators = Field([], alias="validate") validators: Validators = Field([], alias="validate")
validate_script: List[Text] = [] validate_script: List[Text] = []
+14 -11
View File
@@ -43,10 +43,10 @@ class HttpRunner(object):
__teststeps: List[TStep] __teststeps: List[TStep]
__project_meta: ProjectMeta = None __project_meta: ProjectMeta = None
__case_id: Text = "" __case_id: Text = ""
__export: List[Text] = []
__step_datas: List[StepData] = None __step_datas: List[StepData] = None
__session: HttpSession = None __session: HttpSession = None
__session_variables: VariablesMapping = {} __session_variables: VariablesMapping = {}
__export_variables: VariablesMapping = {}
# time # time
__start_at: float = 0 __start_at: float = 0
__duration: float = 0 __duration: float = 0
@@ -82,6 +82,10 @@ class HttpRunner(object):
self.__session_variables = variables self.__session_variables = variables
return self return self
def with_export(self, export: List[Text]) -> "HttpRunner":
self.__export = export
return self
def __run_step_request(self, step: TStep) -> StepData: def __run_step_request(self, step: TStep) -> StepData:
"""run teststep: request""" """run teststep: request"""
step_data = StepData(name=step.name) step_data = StepData(name=step.name)
@@ -166,6 +170,7 @@ class HttpRunner(object):
"""run teststep: referenced testcase""" """run teststep: referenced testcase"""
step_data = StepData(name=step.name) step_data = StepData(name=step.name)
step_variables = step.variables step_variables = step.variables
step_export = step.export
if hasattr(step.testcase, "config") and hasattr(step.testcase, "teststeps"): if hasattr(step.testcase, "config") and hasattr(step.testcase, "teststeps"):
testcase_cls = step.testcase testcase_cls = step.testcase
@@ -174,6 +179,7 @@ class HttpRunner(object):
.with_session(self.__session) .with_session(self.__session)
.with_case_id(self.__case_id) .with_case_id(self.__case_id)
.with_variables(step_variables) .with_variables(step_variables)
.with_export(step_export)
.run() .run()
) )
@@ -188,6 +194,7 @@ class HttpRunner(object):
.with_session(self.__session) .with_session(self.__session)
.with_case_id(self.__case_id) .with_case_id(self.__case_id)
.with_variables(step_variables) .with_variables(step_variables)
.with_export(step_export)
.run_path(ref_testcase_path) .run_path(ref_testcase_path)
) )
@@ -201,6 +208,9 @@ class HttpRunner(object):
step_data.success = case_result.success step_data.success = case_result.success
self.success &= case_result.success self.success &= case_result.success
if step_data.export:
logger.info(f"export variables: {step_data.export}")
return step_data return step_data
def __run_step(self, step: TStep) -> Dict: def __run_step(self, step: TStep) -> Dict:
@@ -252,7 +262,6 @@ class HttpRunner(object):
self.__step_datas: List[StepData] = [] self.__step_datas: List[StepData] = []
self.__session = self.__session or HttpSession() self.__session = self.__session or HttpSession()
self.__session_variables = {} self.__session_variables = {}
self.__export_variables = {}
# run teststeps # run teststeps
for step in self.__teststeps: for step in self.__teststeps:
@@ -274,11 +283,6 @@ class HttpRunner(object):
self.__session_variables.update(extract_mapping) self.__session_variables.update(extract_mapping)
self.__duration = time.time() - self.__start_at self.__duration = time.time() - self.__start_at
self.__export_variables = self.get_export_variables()
if self.__export_variables:
logger.info(f"export variables: {self.__export_variables}")
return self return self
def run_path(self, path: Text) -> "HttpRunner": def run_path(self, path: Text) -> "HttpRunner":
@@ -303,11 +307,10 @@ class HttpRunner(object):
return self.__step_datas return self.__step_datas
def get_export_variables(self) -> Dict: def get_export_variables(self) -> Dict:
if self.__export_variables: # override testcase export vars with step export
return self.__export_variables export_var_names = self.__export or self.__config.export
export_vars_mapping = {} export_vars_mapping = {}
for var_name in self.__config.export: for var_name in export_var_names:
if var_name not in self.__session_variables: if var_name not in self.__session_variables:
raise ParamsError( raise ParamsError(
f"failed to export variable {var_name} from session variables {self.__session_variables}" f"failed to export variable {var_name} from session variables {self.__session_variables}"
+2 -3
View File
@@ -298,10 +298,9 @@ class RunRequest(object):
class StepRefCase(object): class StepRefCase(object):
def __init__(self, step: TStep): def __init__(self, step: TStep):
self.__t_step = step self.__t_step = step
self.__t_step.extract = []
def extract(self, *var_name: Text) -> "StepRefCase": def export(self, *var_name: Text) -> "StepRefCase":
self.__t_step.extract.extend(var_name) self.__t_step.export.extend(var_name)
return self return self
def perform(self) -> TStep: def perform(self) -> TStep: