refactor: reformat all code with black

This commit is contained in:
debugtalk
2022-04-23 15:05:21 +08:00
parent 7eaa8a4ac0
commit 418a16fcee
27 changed files with 169 additions and 213 deletions

View File

@@ -59,7 +59,7 @@ def teardown_hook_example(name):
return f"teardown_hook_example: {name}"
if __name__ == '__main__':
if __name__ == "__main__":
funppy.register("get_httprunner_version", get_httprunner_version)
funppy.register("sum", sum)
funppy.register("sum_ints", sum_ints)

View File

@@ -36,8 +36,8 @@ def sum_two(m, n):
def sum_status_code(status_code, expect_sum):
""" sum status code digits
e.g. 400 => 4, 201 => 3
"""sum status code digits
e.g. 400 => 4, 201 => 3
"""
sum_value = 0
for digit in str(status_code):
@@ -54,8 +54,7 @@ os.environ["TEST_ENV"] = "PRODUCTION"
def skip_test_in_production_env():
""" skip this test in production environment
"""
"""skip this test in production environment"""
return os.environ["TEST_ENV"] == "PRODUCTION"
@@ -97,8 +96,7 @@ def setup_hook_remove_kwargs(request):
def teardown_hook_sleep_N_secs(response, n_secs):
""" sleep n seconds after request
"""
"""sleep n seconds after request"""
if response.status_code == 200:
time.sleep(0.1)
else:

View File

@@ -54,8 +54,7 @@ def session_fixture(request):
summary["details"].append(testcase_summary_json)
summary_path = os.path.join(
os.getcwd(),
"examples/postman_echo/logs/request_methods/hardcode.summary.json"
os.getcwd(), "examples/postman_echo/logs/request_methods/hardcode.summary.json"
)
summary_dir = os.path.dirname(summary_path)
os.makedirs(summary_dir, exist_ok=True)

View File

@@ -1,22 +0,0 @@
config:
name: "demo testsuite"
variables: ${get_testsuite_config_variables()}
testcases:
-
name: request with functions
testcase: request_methods/request_with_functions.yml
weight: 2
variables:
foo1: testcase_ref_bar11
expect_foo1: testcase_ref_bar11
expect_foo2: testsuite_config_bar2
-
name: request with referenced testcase
testcase: request_methods/request_with_testcase_reference.yml
weight: 3
variables:
foo1: testcase_ref_bar12
expect_foo1: testcase_ref_bar12
foo2: testcase_ref_bar22
expect_foo2: testcase_ref_bar22

View File

@@ -59,7 +59,7 @@ def teardown_hook_example(name):
return f"teardown_hook_example: {name}"
if __name__ == '__main__':
if __name__ == "__main__":
funppy.register("get_httprunner_version", get_httprunner_version)
funppy.register("sum", sum)
funppy.register("sum_ints", sum_ints)

View File

@@ -11,16 +11,14 @@ from httprunner.exceptions import ParamsError
def gen_random_string(str_len):
""" generate random string with specified length
"""
"""generate random string with specified length"""
return "".join(
random.choice(string.ascii_letters + string.digits) for _ in range(str_len)
)
def get_timestamp(str_len=13):
""" get timestamp string, length can only between 0 and 16
"""
"""get timestamp string, length can only between 0 and 16"""
if isinstance(str_len, int) and 0 < str_len < 17:
return str(time.time()).replace(".", "")[:str_len]
@@ -28,12 +26,10 @@ def get_timestamp(str_len=13):
def get_current_date(fmt="%Y-%m-%d"):
""" get current date, default format is %Y-%m-%d
"""
"""get current date, default format is %Y-%m-%d"""
return datetime.datetime.now().strftime(fmt)
def sleep(n_secs):
""" sleep n seconds
"""
"""sleep n seconds"""
time.sleep(n_secs)

View File

@@ -55,8 +55,7 @@ def main_run(extra_args) -> enum.IntEnum:
def main():
""" API test: parse command line options and run commands.
"""
"""API test: parse command line options and run commands."""
init_logger()
parser = argparse.ArgumentParser(description=__description__)
@@ -111,8 +110,8 @@ def main():
def main_hrun_alias():
""" command alias
hrun = httprunner run
"""command alias
hrun = httprunner run
"""
if len(sys.argv) == 2:
if sys.argv[1] in ["-V", "--version"]:
@@ -131,8 +130,8 @@ def main_hrun_alias():
def main_make_alias():
""" command alias
hmake = httprunner make
"""command alias
hmake = httprunner make
"""
sys.argv.insert(1, "make")
main()

View File

@@ -27,8 +27,7 @@ class ApiResponse(Response):
def get_req_resp_record(resp_obj: Response) -> ReqRespData:
""" get request and response info from Response() object.
"""
"""get request and response info from Response() object."""
def log_print(req_or_resp, r_type):
msg = f"\n================== {r_type} details ==================\n"

View File

@@ -27,7 +27,8 @@ class TestHttpSession(unittest.TestCase):
self.session.request(
"get",
"http://httpbin.org/redirect-to?url=https%3A%2F%2Fgithub.com",
allow_redirects=True)
allow_redirects=True,
)
address = self.session.data.address
self.assertNotEqual(address.server_ip, "N/A")
self.assertEqual(address.server_port, 443)
@@ -38,7 +39,8 @@ class TestHttpSession(unittest.TestCase):
self.session.request(
"get",
"https://httpbin.org/redirect-to?url=https%3A%2F%2Fgithub.com",
allow_redirects=True)
allow_redirects=True,
)
address = self.session.data.address
self.assertNotEqual(address.server_ip, "N/A")
self.assertEqual(address.server_port, 443)
@@ -49,7 +51,8 @@ class TestHttpSession(unittest.TestCase):
self.session.request(
"get",
"http://httpbin.org/redirect-to?url=https%3A%2F%2Fgithub.com",
allow_redirects=False)
allow_redirects=False,
)
address = self.session.data.address
self.assertEqual(address.server_ip, "N/A")
self.assertEqual(address.server_port, 0)
@@ -60,7 +63,8 @@ class TestHttpSession(unittest.TestCase):
self.session.request(
"get",
"https://httpbin.org/redirect-to?url=https%3A%2F%2Fgithub.com",
allow_redirects=False)
allow_redirects=False,
)
address = self.session.data.address
self.assertEqual(address.server_ip, "N/A")
self.assertEqual(address.server_port, 0)

View File

@@ -14,25 +14,12 @@ from httprunner.utils import sort_dict_by_custom_order
def convert_variables(
raw_variables: Union[Dict, List, Text], test_path: Text
raw_variables: Union[Dict, Text], test_path: Text
) -> Dict[Text, Any]:
if isinstance(raw_variables, Dict):
return raw_variables
if isinstance(raw_variables, List):
# [{"var1": 1}, {"var2": 2}]
variables: Dict[Text, Any] = {}
for var_item in raw_variables:
if not isinstance(var_item, Dict) or len(var_item) != 1:
raise exceptions.TestCaseFormatError(
f"Invalid variables format: {raw_variables}"
)
variables.update(var_item)
return variables
elif isinstance(raw_variables, Text):
# get variables by function, e.g. ${get_variables()}
project_meta = load_project_meta(test_path)
@@ -79,7 +66,7 @@ def _convert_jmespath(raw: Text) -> Text:
def _convert_extractors(extractors: Union[List, Dict]) -> Dict:
""" convert extract list(v2) to dict(v3)
"""convert extract list(v2) to dict(v3)
Args:
extractors: [{"varA": "content.varA"}, {"varB": "json.varB"}]
@@ -251,8 +238,7 @@ def ensure_testcase_v3(test_content: Dict) -> Dict:
def ensure_cli_args(args: List) -> List:
""" ensure compatibility with deprecated cli args in v2
"""
"""ensure compatibility with deprecated cli args in v2"""
# remove deprecated --failfast
if "--failfast" in args:
logger.warning("remove deprecated argument: --failfast")
@@ -386,8 +372,7 @@ def session_fixture(request):
def ensure_path_sep(path: Text) -> Text:
""" ensure compatibility with different path separators of Linux and Windows
"""
"""ensure compatibility with different path separators of Linux and Windows"""
if "/" in path:
path = os.sep.join(path.split("/"))

View File

@@ -9,11 +9,6 @@ class TestCompat(unittest.TestCase):
loader.project_meta = None
def test_convert_variables(self):
raw_variables = [{"var1": 1}, {"var2": "val2"}]
self.assertEqual(
compat.convert_variables(raw_variables, "examples/data/a-b.c/1.yml"),
{"var1": 1, "var2": "val2"},
)
raw_variables = {"var1": 1, "var2": "val2"}
self.assertEqual(
compat.convert_variables(raw_variables, "examples/data/a-b.c/1.yml"),
@@ -38,7 +33,7 @@ class TestCompat(unittest.TestCase):
compat._convert_jmespath("headers.Content-Type"), 'headers."Content-Type"'
)
self.assertEqual(
compat._convert_jmespath('headers.User-Agent'), 'headers."User-Agent"'
compat._convert_jmespath("headers.User-Agent"), 'headers."User-Agent"'
)
self.assertEqual(
compat._convert_jmespath('headers."Content-Type"'), 'headers."Content-Type"'

View File

@@ -5,7 +5,6 @@ from httprunner.models import TConfig, TConfigThrift
class ConfigThrift(object):
def __init__(self, config: TConfig) -> None:
self.__config = config
self.__config.thrift = TConfigThrift()
@@ -31,13 +30,9 @@ class ConfigThrift(object):
class Config(object):
def __init__(self, name: Text) -> None:
caller_frame = inspect.stack()[1]
self.__config = TConfig(
name=name,
path=caller_frame.filename
)
self.__config = TConfig(name=name, path=caller_frame.filename)
@property
def name(self) -> Text:

View File

@@ -85,5 +85,4 @@ class TestcaseNotFound(NotFoundError):
class SummaryEmpty(MyBaseError):
""" test result summary data is empty
"""
"""test result summary data is empty"""

View File

@@ -76,7 +76,7 @@ def ensure_upload_ready():
def prepare_upload_step(step: TStep, functions: FunctionsMapping):
""" preprocess for upload test
"""preprocess for upload test
replace `upload` info with MultipartEncoder
Args:
@@ -102,9 +102,7 @@ def prepare_upload_step(step: TStep, functions: FunctionsMapping):
return
# parse upload info
step.request.upload = parse_data(
step.request.upload, step.variables, functions
)
step.request.upload = parse_data(step.request.upload, step.variables, functions)
ensure_upload_ready()
params_list = []
@@ -124,7 +122,7 @@ def prepare_upload_step(step: TStep, functions: FunctionsMapping):
def multipart_encoder(**kwargs):
""" initialize MultipartEncoder with uploading fields.
"""initialize MultipartEncoder with uploading fields.
Returns:
MultipartEncoder: initialized MultipartEncoder object
@@ -169,7 +167,7 @@ def multipart_encoder(**kwargs):
def multipart_content_type(m_encoder) -> Text:
""" prepare Content-Type for request headers
"""prepare Content-Type for request headers
Args:
m_encoder: MultipartEncoder object

View File

@@ -97,7 +97,11 @@ class TestLoader(unittest.TestCase):
)
def test_load_env_path_not_exist(self):
dot_env_path = os.path.join(os.getcwd(), "tests", "data",)
dot_env_path = os.path.join(
os.getcwd(),
"tests",
"data",
)
env_variables_mapping = loader.load_dot_env_file(dot_env_path)
self.assertEqual(env_variables_mapping, {})

View File

@@ -78,10 +78,10 @@ if __name__ == "__main__":
def __ensure_absolute(path: Text) -> Text:
if path.startswith("./"):
# Linux/Darwin, hrun ./test.yml
path = path[len("./") :]
path = path[2:]
elif path.startswith(".\\"):
# Windows, hrun .\\test.yml
path = path[len(".\\") :]
path = path[3:]
path = ensure_path_sep(path)
project_meta = load_project_meta(path)
@@ -479,8 +479,7 @@ def __make(tests_path: Text):
if "config" not in test_content:
logger.warning(
f"Invalid testcase file: {test_file}\n"
f"reason: missing config part."
f"Invalid testcase file: {test_file}\nreason: missing config part."
)
continue
elif not isinstance(test_content["config"], Dict):

View File

@@ -20,7 +20,7 @@ function_regex_compile = re.compile(r"\$\{([a-zA-Z_]\w*)\(([\$\w\.\-/\s=,]*)\)\}
def parse_string_value(str_value: Text) -> Any:
""" parse string to number if possible
"""parse string to number if possible
e.g. "123" => 123
"12.2" => 12.3
"abc" => "abc"
@@ -36,7 +36,7 @@ def parse_string_value(str_value: Text) -> Any:
def build_url(base_url, step_url):
""" prepend url with base_url unless it's already an absolute URL """
"""prepend url with base_url unless it's already an absolute URL"""
o_step_url = urlparse(step_url)
if o_step_url.netloc != "":
# step url is absolute url
@@ -49,14 +49,16 @@ def build_url(base_url, step_url):
raise exceptions.ParamsError("base url missed!")
path = o_base_url.path.rstrip("/") + "/" + o_step_url.path.lstrip("/")
o_step_url = o_step_url._replace(scheme=o_base_url.scheme) \
._replace(netloc=o_base_url.netloc) \
o_step_url = (
o_step_url._replace(scheme=o_base_url.scheme)
._replace(netloc=o_base_url.netloc)
._replace(path=path)
)
return o_step_url.geturl()
def regex_findall_variables(raw_string: Text) -> List[Text]:
""" extract all variable names from content, which is in format $variable
"""extract all variable names from content, which is in format $variable
Args:
raw_string (str): string content
@@ -115,7 +117,7 @@ def regex_findall_variables(raw_string: Text) -> List[Text]:
def regex_findall_functions(content: Text) -> List[Text]:
""" extract all functions from string content, which are in format ${fun()}
"""extract all functions from string content, which are in format ${fun()}
Args:
content (str): string content
@@ -148,8 +150,7 @@ def regex_findall_functions(content: Text) -> List[Text]:
def extract_variables(content: Any) -> Set:
""" extract all variables in content recursively.
"""
"""extract all variables in content recursively."""
if isinstance(content, (list, set, tuple)):
variables = set()
for item in content:
@@ -169,7 +170,7 @@ def extract_variables(content: Any) -> Set:
def parse_function_params(params: Text) -> Dict:
""" parse function params to args and kwargs.
"""parse function params to args and kwargs.
Args:
params (str): function param in string
@@ -220,7 +221,7 @@ def parse_function_params(params: Text) -> Dict:
def get_mapping_variable(
variable_name: Text, variables_mapping: VariablesMapping
) -> Any:
""" get variable from variables_mapping.
"""get variable from variables_mapping.
Args:
variable_name (str): variable name
@@ -245,7 +246,7 @@ def get_mapping_variable(
def get_mapping_function(
function_name: Text, functions_mapping: FunctionsMapping
) -> Callable:
""" get function from functions_mapping,
"""get function from functions_mapping,
if not found, then try to check if builtin function.
Args:
@@ -295,7 +296,7 @@ def parse_string(
variables_mapping: VariablesMapping,
functions_mapping: FunctionsMapping,
) -> Any:
""" parse string content with variables and functions mapping.
"""parse string content with variables and functions mapping.
Args:
raw_string: raw string content to be parsed.
@@ -402,8 +403,8 @@ def parse_data(
variables_mapping: VariablesMapping = None,
functions_mapping: FunctionsMapping = None,
) -> Any:
""" parse raw data with evaluated variables mapping.
Notice: variables_mapping should not contain any variable or function.
"""parse raw data with evaluated variables mapping.
Notice: variables_mapping should not contain any variable or function.
"""
if isinstance(raw_data, str):
# content in string format may contains variables and functions
@@ -475,8 +476,10 @@ def parse_variables_mapping(
return parsed_variables
def parse_parameters(parameters: Dict,) -> List[Dict]:
""" parse parameters and generate cartesian product.
def parse_parameters(
parameters: Dict,
) -> List[Dict]:
"""parse parameters and generate cartesian product.
Args:
parameters (Dict) parameters: parameter name and value mapping
@@ -583,17 +586,20 @@ def parse_parameters(parameters: Dict,) -> List[Dict]:
class Parser(object):
def __init__(self, functions_mapping: FunctionsMapping = None) -> None:
self.functions_mapping = functions_mapping
def parse_string(self, raw_string: Text, variables_mapping: VariablesMapping) -> Any:
def parse_string(
self, raw_string: Text, variables_mapping: VariablesMapping
) -> Any:
return parse_string(raw_string, variables_mapping, self.functions_mapping)
def parse_variables(self, variables_mapping: VariablesMapping) -> VariablesMapping:
return parse_variables_mapping(variables_mapping, self.functions_mapping)
def parse_data(self, raw_data: Any, variables_mapping: VariablesMapping = None) -> Any:
def parse_data(
self, raw_data: Any, variables_mapping: VariablesMapping = None
) -> Any:
return parse_data(raw_data, variables_mapping, self.functions_mapping)
def get_mapping_function(self, func_name: Text) -> Callable:

View File

@@ -8,7 +8,6 @@ from httprunner.loader import load_project_meta
class TestParserBasic(unittest.TestCase):
def test_build_url(self):
url = parser.build_url("https://postman-echo.com", "/get")
self.assertEqual(url, "https://postman-echo.com/get")

View File

@@ -12,8 +12,7 @@ from httprunner.parser import Parser, parse_string_value
def get_uniform_comparator(comparator: Text):
""" convert comparator alias to uniform name
"""
"""convert comparator alias to uniform name"""
if comparator in ["eq", "equals", "equal"]:
return "equal"
elif comparator in ["lt", "less_than"]:
@@ -52,7 +51,7 @@ def get_uniform_comparator(comparator: Text):
def uniform_validator(validator):
""" unify validator
"""unify validator
Args:
validator (dict): validator maybe in two formats:
@@ -116,7 +115,7 @@ def uniform_validator(validator):
class ResponseObject(object):
def __init__(self, resp_obj: requests.Response, parser: Parser):
""" initialize with a requests.Response object
"""initialize with a requests.Response object
Args:
resp_obj (instance): requests.Response instance
@@ -168,20 +167,19 @@ class ResponseObject(object):
return check_value
def extract(self,
extractors: Dict[Text, Text],
variables_mapping: VariablesMapping = None,
) -> Dict[Text, Any]:
def extract(
self,
extractors: Dict[Text, Text],
variables_mapping: VariablesMapping = None,
) -> Dict[Text, Any]:
if not extractors:
return {}
extract_mapping = {}
for key, field in extractors.items():
if '$' in field:
if "$" in field:
# field contains variable or function
field = self.parser.parse_data(
field, variables_mapping
)
field = self.parser.parse_data(field, variables_mapping)
field_value = self._search_jmespath(field)
extract_mapping[key] = field_value
@@ -214,9 +212,7 @@ class ResponseObject(object):
check_item = u_validator["check"]
if "$" in check_item:
# check_item is variable or function
check_item = self.parser.parse_data(
check_item, variables_mapping
)
check_item = self.parser.parse_data(check_item, variables_mapping)
check_item = parse_string_value(check_item)
if check_item and isinstance(check_item, Text):

View File

@@ -19,16 +19,13 @@ class TestResponse(unittest.TestCase):
]
},
)
parser = Parser(functions_mapping={
'get_name': lambda: 'name',
"get_num": lambda x: x
})
parser = Parser(
functions_mapping={"get_name": lambda: "name", "get_num": lambda x: x}
)
self.resp_obj = ResponseObject(resp, parser)
def test_extract(self):
variables_mapping = {
'body': 'body'
}
variables_mapping = {"body": "body"}
extract_mapping = self.resp_obj.extract(
{
"var_1": "body.json.locations[0]",
@@ -64,6 +61,9 @@ class TestResponse(unittest.TestCase):
def test_validate_functions(self):
variables_mapping = {"index": 1}
self.resp_obj.validate(
[{"eq": ["${get_num(0)}", 0]}, {"eq": ["${get_num($index)}", 1]},],
[
{"eq": ["${get_num(0)}", 0]},
{"eq": ["${get_num($index)}", 1]},
],
variables_mapping=variables_mapping,
)

View File

@@ -17,8 +17,15 @@ from httprunner.client import HttpSession
from httprunner.config import Config
from httprunner.exceptions import ParamsError, ValidationFailure
from httprunner.loader import load_project_meta
from httprunner.models import (ProjectMeta, StepResult, TConfig, TestCaseInOut,
TestCaseSummary, TestCaseTime, VariablesMapping)
from httprunner.models import (
ProjectMeta,
StepResult,
TConfig,
TestCaseInOut,
TestCaseSummary,
TestCaseTime,
VariablesMapping,
)
from httprunner.parser import Parser
from httprunner.utils import LOGGER_FORMAT, init_logger, merge_variables
@@ -55,9 +62,7 @@ class SessionRunner(object):
)
self.case_id = self.case_id or str(uuid.uuid4())
self.root_dir = self.root_dir or self.__project_meta.RootDir
self.__log_path = os.path.join(
self.root_dir, "logs", f"{self.case_id}.run.log"
)
self.__log_path = os.path.join(self.root_dir, "logs", f"{self.case_id}.run.log")
self.__step_results.clear()
self.session = self.session or HttpSession()
@@ -87,9 +92,7 @@ class SessionRunner(object):
self.__config.variables.update(self.__session_variables)
if param:
self.__config.variables.update(param)
self.__config.variables = self.parser.parse_variables(
self.__config.variables
)
self.__config.variables = self.parser.parse_variables(self.__config.variables)
# parse config name
self.__config.name = self.parser.parse_data(
@@ -176,10 +179,12 @@ class SessionRunner(object):
raise
else:
logger.warning(
f"run step {step.name()} validation failed,wait {step.retry_interval} sec and try again")
f"run step {step.name()} validation failed,wait {step.retry_interval} sec and try again"
)
time.sleep(step.retry_interval)
logger.info(
f"run step retry ({i+1}/{step.retry_times} time): {step.name()} >>>>>>")
f"run step retry ({i+1}/{step.retry_times} time): {step.name()} >>>>>>"
)
# save extracted variables to session variables
self.__session_variables.update(step_result.export_vars)

View File

@@ -2,12 +2,15 @@ from typing import Union
from httprunner.models import StepResult, TRequest, TStep, TestCase
from httprunner.runner import HttpRunner
from httprunner.step_request import RequestWithOptionalArgs, StepRequestExtraction, StepRequestValidation
from httprunner.step_request import (
RequestWithOptionalArgs,
StepRequestExtraction,
StepRequestValidation,
)
from httprunner.step_testcase import StepRefCase
class Step(object):
def __init__(
self,
step: Union[

View File

@@ -6,15 +6,24 @@ from loguru import logger
from httprunner import utils
from httprunner.exceptions import ValidationFailure
from httprunner.ext.uploader import prepare_upload_step
from httprunner.models import (Hooks, IStep, MethodEnum, StepResult, TRequest,
TStep, VariablesMapping)
from httprunner.models import (
Hooks,
IStep,
MethodEnum,
StepResult,
TRequest,
TStep,
VariablesMapping,
)
from httprunner.parser import build_url
from httprunner.response import ResponseObject
from httprunner.runner import HttpRunner
def call_hooks(runner: HttpRunner, hooks: Hooks, step_variables: VariablesMapping, hook_msg: Text):
""" call hook actions.
def call_hooks(
runner: HttpRunner, hooks: Hooks, step_variables: VariablesMapping, hook_msg: Text
):
"""call hook actions.
Args:
hooks (list): each hook in hooks list maybe in two format.
@@ -46,9 +55,7 @@ def call_hooks(runner: HttpRunner, hooks: Hooks, step_variables: VariablesMappin
elif isinstance(hook, Dict) and len(hook) == 1:
# format 2: {"var": "${func()}"}
var_name, hook_content = list(hook.items())[0]
hook_content_eval = runner.parser.parse_data(
hook_content, step_variables
)
hook_content_eval = runner.parser.parse_data(hook_content, step_variables)
logger.debug(
f"call hook function: {hook_content}, got value: {hook_content_eval}"
)
@@ -73,9 +80,7 @@ def run_step_request(runner: HttpRunner, step: TStep) -> StepResult:
prepare_upload_step(step, functions)
request_dict = step.request.dict()
request_dict.pop("upload", None)
parsed_request_dict = runner.parser.parse_data(
request_dict, step.variables
)
parsed_request_dict = runner.parser.parse_data(request_dict, step.variables)
parsed_request_dict["headers"].setdefault(
"HRUN-Request-ID",
f"HRUN-{runner.case_id}-{str(int(time.time() * 1000))[-6:]}",
@@ -136,9 +141,7 @@ def run_step_request(runner: HttpRunner, step: TStep) -> StepResult:
# validate
validators = step.validators
try:
resp_obj.validate(
validators, variables_mapping
)
resp_obj.validate(validators, variables_mapping)
step_result.success = True
except ValidationFailure:
log_req_resp_details()
@@ -162,9 +165,7 @@ class StepRequestValidation(IStep):
def assert_equal(
self, jmes_path: Text, expected_value: Any, message: Text = ""
) -> "StepRequestValidation":
self.__step.validators.append(
{"equal": [jmes_path, expected_value, message]}
)
self.__step.validators.append({"equal": [jmes_path, expected_value, message]})
return self
def assert_not_equal(
@@ -418,7 +419,6 @@ class RequestWithOptionalArgs(IStep):
class RunRequest(object):
def __init__(self, name: Text):
self.__step = TStep(name=name)

View File

@@ -1,10 +1,11 @@
import unittest
from examples.postman_echo.request_methods.request_with_functions_test import TestCaseRequestWithFunctions
from examples.postman_echo.request_methods.request_with_functions_test import (
TestCaseRequestWithFunctions,
)
class TestRunRequest(unittest.TestCase):
def test_run_request(self):
runner = TestCaseRequestWithFunctions().test_start()
summary = runner.get_summary()

View File

@@ -22,11 +22,9 @@ def run_step_testcase(runner: HttpRunner, step: TStep) -> StepResult:
# step.testcase is a referenced testcase, e.g. RequestWithFunctions
ref_case_runner = step.testcase()
ref_case_runner.with_session(runner.session) \
.with_case_id(runner.case_id) \
.with_variables(step_variables) \
.with_export(step_export) \
.test_start()
ref_case_runner.with_session(runner.session).with_case_id(
runner.case_id
).with_variables(step_variables).with_export(step_export).test_start()
# teardown hooks
if step.teardown_hooks:

View File

@@ -2,19 +2,22 @@ import unittest
from httprunner.runner import HttpRunner
from httprunner.step_testcase import RunTestCase
from examples.postman_echo.request_methods.request_with_functions_test import TestCaseRequestWithFunctions
from examples.postman_echo.request_methods.request_with_functions_test import (
TestCaseRequestWithFunctions,
)
class TestRunTestCase(unittest.TestCase):
def setUp(self):
self.runner = HttpRunner()
def test_run_testcase_by_path(self):
step_result = RunTestCase("run referenced testcase").call(
TestCaseRequestWithFunctions
).run(self.runner)
step_result = (
RunTestCase("run referenced testcase")
.call(TestCaseRequestWithFunctions)
.run(self.runner)
)
self.assertTrue(step_result.success)
self.assertEqual(step_result.name, "run referenced testcase")
self.assertEqual(len(step_result.data), 3)

View File

@@ -32,18 +32,20 @@ def init_sentry_sdk():
class GAClient(object):
version = '1' # GA API Version
report_url = 'https://www.google-analytics.com/collect'
report_debug_url = 'https://www.google-analytics.com/debug/collect' # used for debug
version = "1" # GA API Version
report_url = "https://www.google-analytics.com/collect"
report_debug_url = (
"https://www.google-analytics.com/debug/collect" # used for debug
)
def __init__(self, tracking_id: Text):
self.http_client = requests.Session()
self.label = f"v{__version__}"
self.common_params = {
'v': self.version,
'tid': tracking_id, # Tracking ID / Property ID, XX-XXXXXXX-X
'cid': uuid.getnode(), # Anonymous Client ID
'ua': f'HttpRunner/{__version__}',
"v": self.version,
"tid": tracking_id, # Tracking ID / Property ID, XX-XXXXXXX-X
"cid": uuid.getnode(), # Anonymous Client ID
"ua": f"HttpRunner/{__version__}",
}
# do not send GA events in CI environment
self.__is_ci = os.getenv("DISABLE_GA") == "true"
@@ -53,16 +55,16 @@ class GAClient(object):
return
data = {
't': 'event', # Event hit type = event
'ec': category, # Required. Event Category.
'ea': action, # Required. Event Action.
'el': self.label, # Optional. Event label, used as version.
'ev': value, # Optional. Event value, must be non-negative integer
"t": "event", # Event hit type = event
"ec": category, # Required. Event Category.
"ea": action, # Required. Event Action.
"el": self.label, # Optional. Event label, used as version.
"ev": value, # Optional. Event value, must be non-negative integer
}
data.update(self.common_params)
try:
self.http_client.post(self.report_url, data=data, timeout=5)
except Exception: # ProxyError, SSLError, ConnectionError
except Exception: # ProxyError, SSLError, ConnectionError
pass
def track_user_timing(self, category: Text, variable: Text, duration: int):
@@ -70,16 +72,16 @@ class GAClient(object):
return
data = {
't': 'timing', # Event hit type = timing
'utc': category, # Required. user timing category. e.g. jsonLoader
'utv': variable, # Required. timing variable. e.g. load
'utt': duration, # Required. time took duration.
'utl': self.label, # Optional. user timing label, used as version.
"t": "timing", # Event hit type = timing
"utc": category, # Required. user timing category. e.g. jsonLoader
"utv": variable, # Required. timing variable. e.g. load
"utt": duration, # Required. time took duration.
"utl": self.label, # Optional. user timing label, used as version.
}
data.update(self.common_params)
try:
self.http_client.post(self.report_url, data=data, timeout=5)
except Exception: # ProxyError, SSLError, ConnectionError
except Exception: # ProxyError, SSLError, ConnectionError
pass
@@ -87,23 +89,21 @@ ga_client = GAClient("UA-114587036-1")
def set_os_environ(variables_mapping):
""" set variables mapping to os.environ
"""
"""set variables mapping to os.environ"""
for variable in variables_mapping:
os.environ[variable] = variables_mapping[variable]
logger.debug(f"Set OS environment variable: {variable}")
def unset_os_environ(variables_mapping):
""" unset variables mapping to os.environ
"""
"""unset variables mapping to os.environ"""
for variable in variables_mapping:
os.environ.pop(variable)
logger.debug(f"Unset OS environment variable: {variable}")
def get_os_environ(variable_name):
""" get value of environment variable.
"""get value of environment variable.
Args:
variable_name(str): variable name
@@ -122,7 +122,7 @@ def get_os_environ(variable_name):
def lower_dict_keys(origin_dict):
""" convert keys in dict to lower case
"""convert keys in dict to lower case
Args:
origin_dict (dict): mapping data structure
@@ -157,7 +157,7 @@ def lower_dict_keys(origin_dict):
def print_info(info_mapping):
""" print info in mapping.
"""print info in mapping.
Args:
info_mapping (dict): input(variables) or output mapping.
@@ -202,8 +202,7 @@ def print_info(info_mapping):
def omit_long_data(body, omit_len=512):
""" omit too long str/bytes
"""
"""omit too long str/bytes"""
if not isinstance(body, (str, bytes)):
return body
@@ -244,8 +243,7 @@ def sort_dict_by_custom_order(raw_dict: Dict, custom_order: List):
class ExtendJSONEncoder(json.JSONEncoder):
""" especially used to safely dump json data with python object, such as MultipartEncoder
"""
"""especially used to safely dump json data with python object, such as MultipartEncoder"""
def default(self, obj):
try:
@@ -257,8 +255,7 @@ class ExtendJSONEncoder(json.JSONEncoder):
def merge_variables(
variables: VariablesMapping, variables_to_be_overridden: VariablesMapping
) -> VariablesMapping:
""" merge two variables mapping, the first variables have higher priority
"""
"""merge two variables mapping, the first variables have higher priority"""
step_new_variables = {}
for key, value in variables.items():
if f"${key}" == value or "${" + key + "}" == value:
@@ -283,7 +280,7 @@ def is_support_multiprocessing() -> bool:
def gen_cartesian_product(*args: List[Dict]) -> List[Dict]:
""" generate cartesian product for lists
"""generate cartesian product for lists
Args:
args (list of list): lists to be generated with cartesian product