feat: implement step setup/teardown hooks

This commit is contained in:
debugtalk
2020-06-07 16:38:59 +08:00
parent e855b46976
commit 155ea7dad8
3 changed files with 67 additions and 6 deletions

View File

@@ -1,5 +1,11 @@
# Release History
## 3.0.10 (2020-06-07)
**Added**
- feat: implement step setup/teardown hooks
## 3.0.9 (2020-06-07)
**Fixed**

View File

@@ -15,7 +15,7 @@ FunctionsMapping = Dict[Text, Callable]
Headers = Dict[Text, Text]
Cookies = Dict[Text, Text]
Verify = bool
Hook = List[Text]
Hooks = Union[List[Text], Dict[Text, Text]]
Export = List[Text]
Validators = List[Dict]
Env = Dict[Text, Any]
@@ -37,8 +37,8 @@ class TConfig(BaseModel):
base_url: BaseUrl = ""
# Text: prepare variables in debugtalk.py, ${gen_variables()}
variables: Union[VariablesMapping, Text] = {}
setup_hooks: Hook = []
teardown_hooks: Hook = []
# setup_hooks: Hooks = []
# teardown_hooks: Hooks = []
export: Export = []
path: Text = None
@@ -64,8 +64,8 @@ class TStep(BaseModel):
request: Union[TRequest, None] = None
testcase: Union[Text, Callable, None] = None
variables: VariablesMapping = {}
setup_hooks: Hook = []
teardown_hooks: Hook = []
setup_hooks: Hooks = []
teardown_hooks: Hooks = []
# used to extract request's response field
extract: VariablesMapping = {}
# used to export session variables from referenced testcase

View File

@@ -2,7 +2,7 @@ import os
import time
import uuid
from datetime import datetime
from typing import List, Dict, Text, NoReturn
from typing import List, Dict, Text, NoReturn, Union
try:
import allure
@@ -31,6 +31,7 @@ from httprunner.models import (
TestCaseInOut,
ProjectMeta,
TestCase,
Hooks,
)
@@ -86,6 +87,50 @@ class HttpRunner(object):
self.__export = export
return self
def __call_hooks(
self, hooks: Hooks, step_variables: VariablesMapping, hook_type: Text,
) -> NoReturn:
""" call hook actions.
Args:
hooks: each action in actions list maybe in two format.
format1 (dict): assignment, the value returned by hook function will be assigned to variable.
{"var": "${func()}"}
format2 (str): only call hook functions.
${func()}
step_variables: current step variables to call hook, include two special variables
request: parsed request dict
response: ResponseObject for current response
hook_type: setup/teardown
"""
logger.debug(f"call {hook_type} hook actions.")
if isinstance(hooks, Dict):
# format 1: {"var": "${func()}"}
for var_name, hook_content in hooks.items():
hook_content_eval = parse_data(
hook_content, step_variables, self.__project_meta.functions
)
logger.debug(
f"call hook function: {hook_content}, got value: {hook_content_eval}"
)
logger.debug(f"assign variable: {var_name} = {hook_content_eval}")
step_variables[var_name] = hook_content_eval
elif isinstance(hooks, List):
# format 2: ["${func()}"]
for hook in hooks:
logger.debug(f"call hook function: {hook}")
parse_data(hook, step_variables, self.__project_meta.functions)
else:
logger.warning(f"Invalid hooks format: {hooks}")
def __run_step_request(self, step: TStep) -> StepData:
"""run teststep: request"""
step_data = StepData(name=step.name)
@@ -101,6 +146,11 @@ class HttpRunner(object):
"HRUN-Request-ID",
f"HRUN-{self.__case_id}-{str(int(time.time() * 1000))[-6:]}",
)
step.variables["request"] = parsed_request_dict
# setup hooks
if step.setup_hooks:
self.__call_hooks(step.setup_hooks, step.variables, "setup")
# prepare arguments
method = parsed_request_dict.pop("method")
@@ -112,6 +162,11 @@ class HttpRunner(object):
# request
resp = self.__session.request(method, url, **parsed_request_dict)
resp_obj = ResponseObject(resp)
step.variables["response"] = resp_obj
# teardown hooks
if step.teardown_hooks:
self.__call_hooks(step.teardown_hooks, step.variables, "teardown")
def log_req_resp_details():
err_msg = "\n{} DETAILED REQUEST & RESPONSE {}\n".format("*" * 32, "*" * 32)