diff --git a/httprunner/context.py b/httprunner/context.py index 5e134605..1b46b3e2 100644 --- a/httprunner/context.py +++ b/httprunner/context.py @@ -110,12 +110,12 @@ class Context(object): variables = utils.convert_to_order_dict(variables) for variable_name, value in variables.items(): - variable_evale_value = self.testcase_parser.parse_content_with_bindings(value) + variable_eval_value = self.eval_content(value) if level == "testset": - self.testset_shared_variables_mapping[variable_name] = variable_evale_value + self.testset_shared_variables_mapping[variable_name] = variable_eval_value - self.testcase_variables_mapping[variable_name] = variable_evale_value + self.testcase_variables_mapping[variable_name] = variable_eval_value self.testcase_parser.update_binded_variables(self.testcase_variables_mapping) def bind_extracted_variables(self, variables): @@ -140,13 +140,19 @@ class Context(object): self.testcase_functions_config.update(config_mapping) self.testcase_parser.bind_functions(self.testcase_functions_config) + def eval_content(self, content): + """ evaluate content recursively, take effect on each variable and function in content. + content may be in any data structure, include dict, list, tuple, number, string, etc. + """ + return self.testcase_parser.eval_content_with_bindings(content) + def get_parsed_request(self, request_dict, level="testcase"): """ get parsed request with bind variables and functions. @param request_dict: request config mapping @param level: testset or testcase """ if level == "testset": - request_dict = self.testcase_parser.parse_content_with_bindings( + request_dict = self.eval_content( request_dict ) self.testset_request_config.update(request_dict) @@ -155,20 +161,12 @@ class Context(object): copy.deepcopy(self.testset_request_config), request_dict ) - parsed_request = self.testcase_parser.parse_content_with_bindings( + parsed_request = self.eval_content( testcase_request_config ) return parsed_request - def get_testcase_variables_mapping(self): - return self.testcase_variables_mapping - - def exec_content_functions(self, content): - """ execute functions in content. - """ - return self.testcase_parser.eval_content_functions(content) - def eval_check_item(self, validator, resp_obj): """ evaluate check item in validator @param (dict) validator @@ -190,7 +188,7 @@ class Context(object): # 3, regex string, e.g. "LB[\d]*(.*)RB[\d]*" if testcase.extract_variables(check_item): # type 1 - check_value = self.testcase_parser.eval_content_variables(check_item) + check_value = self.eval_content(check_item) else: try: # type 2 or type 3 @@ -203,7 +201,7 @@ class Context(object): # expect_value should only be in 2 types: # 1, variable reference, e.g. $expect_status_code # 2, actual value, e.g. 200 - expect_value = self.testcase_parser.eval_content_variables(validator["expect"]) + expect_value = self.eval_content(validator["expect"]) validator["expect"] = expect_value return validator diff --git a/httprunner/runner.py b/httprunner/runner.py index d3b5178c..47f54829 100644 --- a/httprunner/runner.py +++ b/httprunner/runner.py @@ -82,12 +82,12 @@ class Runner(object): elif "skipIf" in testcase_dict: skip_if_condition = testcase_dict["skipIf"] - if self.context.exec_content_functions(skip_if_condition): + if self.context.eval_content(skip_if_condition): skip_reason = "{} evaluate to True".format(skip_if_condition) elif "skipUnless" in testcase_dict: skip_unless_condition = testcase_dict["skipUnless"] - if not self.context.exec_content_functions(skip_unless_condition): + if not self.context.eval_content(skip_unless_condition): skip_reason = "{} evaluate to False".format(skip_unless_condition) if skip_reason: @@ -138,7 +138,7 @@ class Runner(object): def setup_teardown(actions): for action in actions: - self.context.exec_content_functions(action) + self.context.eval_content(action) setup_teardown(setup_actions) @@ -168,15 +168,10 @@ class Runner(object): return True - def get_eval_content(self, content): - """ evaluate content with variable bindings - """ - return self.context.testcase_parser.parse_content_with_bindings(content) - def extract_output(self, output_variables_list): """ extract output variables """ - variables_mapping = self.context.get_testcase_variables_mapping() + variables_mapping = self.context.testcase_variables_mapping output = {} for variable in output_variables_list: diff --git a/httprunner/task.py b/httprunner/task.py index c30ea06b..0e043276 100644 --- a/httprunner/task.py +++ b/httprunner/task.py @@ -72,7 +72,7 @@ class ApiTestSuite(unittest.TestSuite): def _add_tests_to_suite(self, testcases): for testcase_dict in testcases: - testcase_name = self.test_runner.get_eval_content(testcase_dict["name"]) + testcase_name = self.test_runner.context.eval_content(testcase_dict["name"]) if utils.PYTHON_VERSION == 3: ApiTestCase.runTest.__doc__ = testcase_name else: diff --git a/httprunner/testcase.py b/httprunner/testcase.py index cde17f12..9c237f47 100644 --- a/httprunner/testcase.py +++ b/httprunner/testcase.py @@ -717,7 +717,7 @@ class TestcaseParser(object): raise exception.ParamsError( "{} is not defined in bind {}s!".format(item_name, item_type)) - def eval_content_functions(self, content): + def _eval_content_functions(self, content): functions_list = extract_functions(content) for func_content in functions_list: function_meta = parse_function(func_content) @@ -727,8 +727,8 @@ class TestcaseParser(object): args = function_meta.get('args', []) kwargs = function_meta.get('kwargs', {}) - args = self.parse_content_with_bindings(args) - kwargs = self.parse_content_with_bindings(kwargs) + args = self.eval_content_with_bindings(args) + kwargs = self.eval_content_with_bindings(kwargs) eval_value = func(*args, **kwargs) func_content = "${" + func_content + "}" @@ -744,7 +744,7 @@ class TestcaseParser(object): return content - def eval_content_variables(self, content): + def _eval_content_variables(self, content): """ replace all variables of string content with mapping value. @param (str) content @return (str) parsed content @@ -775,7 +775,7 @@ class TestcaseParser(object): return content - def parse_content_with_bindings(self, content): + def eval_content_with_bindings(self, content): """ parse content recursively, each variable and function in content will be evaluated. @param (dict) content in any data structure @@ -806,15 +806,15 @@ class TestcaseParser(object): if isinstance(content, (list, tuple)): return [ - self.parse_content_with_bindings(item) + self.eval_content_with_bindings(item) for item in content ] if isinstance(content, dict): evaluated_data = {} for key, value in content.items(): - eval_key = self.parse_content_with_bindings(key) - eval_value = self.parse_content_with_bindings(value) + eval_key = self.eval_content_with_bindings(key) + eval_value = self.eval_content_with_bindings(value) evaluated_data[eval_key] = eval_value return evaluated_data @@ -826,10 +826,10 @@ class TestcaseParser(object): content = "" if content is None else content.strip() # replace functions with evaluated value - # Notice: eval_content_functions must be called before eval_content_variables - content = self.eval_content_functions(content) + # Notice: _eval_content_functions must be called before _eval_content_variables + content = self._eval_content_functions(content) # replace variables with binding value - content = self.eval_content_variables(content) + content = self._eval_content_variables(content) return content diff --git a/tests/test_context.py b/tests/test_context.py index a7e5a7a5..742076b0 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -23,7 +23,7 @@ class VariableBindsUnittest(ApiServerUnittest): {"timestamp10": "${get_timestamp(10)}"} ] self.context.bind_variables(variables) - context_variables = self.context.get_testcase_variables_mapping() + context_variables = self.context.testcase_variables_mapping self.assertEqual(len(context_variables["random"]), 5) self.assertEqual(len(context_variables["timestamp10"]), 10) @@ -44,7 +44,7 @@ class VariableBindsUnittest(ApiServerUnittest): self.context.bind_variables(variables, level="testset") testset_variables = self.context.testset_shared_variables_mapping - testcase_variables = self.context.get_testcase_variables_mapping() + testcase_variables = self.context.testcase_variables_mapping self.assertIn("GLOBAL_TOKEN", testset_variables) self.assertIn("GLOBAL_TOKEN", testcase_variables) self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk") @@ -66,7 +66,7 @@ class VariableBindsUnittest(ApiServerUnittest): self.context.bind_variables(variables) testset_variables = self.context.testset_shared_variables_mapping - testcase_variables = self.context.get_testcase_variables_mapping() + testcase_variables = self.context.testcase_variables_mapping self.assertNotIn("GLOBAL_TOKEN", testset_variables) self.assertIn("GLOBAL_TOKEN", testcase_variables) self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk") @@ -94,7 +94,7 @@ class VariableBindsUnittest(ApiServerUnittest): variables = testcase['variables'] self.context.bind_variables(variables) - context_variables = self.context.get_testcase_variables_mapping() + context_variables = self.context.testcase_variables_mapping self.assertIn("add1", context_variables) self.assertEqual(context_variables["add1"], 3) self.assertIn("sum2nums", context_variables) @@ -125,7 +125,7 @@ class VariableBindsUnittest(ApiServerUnittest): variables = testcase['variables'] self.context.bind_variables(variables) - context_variables = self.context.get_testcase_variables_mapping() + context_variables = self.context.testcase_variables_mapping self.assertIn("TOKEN", context_variables) TOKEN = context_variables["TOKEN"] @@ -159,7 +159,7 @@ class VariableBindsUnittest(ApiServerUnittest): variables = testcase['variables'] self.context.bind_variables(variables) - context_variables = self.context.get_testcase_variables_mapping() + context_variables = self.context.testcase_variables_mapping self.assertIn("TOKEN", context_variables) TOKEN = context_variables["TOKEN"] @@ -213,7 +213,7 @@ class VariableBindsUnittest(ApiServerUnittest): test_runner = runner.Runner() content = "${sleep(1)}" start_time = time.time() - test_runner.context.exec_content_functions(content) + test_runner.context.eval_content(content) end_time = time.time() elapsed_time = end_time - start_time self.assertGreater(elapsed_time, 1) diff --git a/tests/test_testcase.py b/tests/test_testcase.py index 4f5c907a..f9b7453c 100644 --- a/tests/test_testcase.py +++ b/tests/test_testcase.py @@ -247,51 +247,51 @@ class TestcaseParserUnittest(unittest.TestCase): } testcase_parser = testcase.TestcaseParser(variables=variables) self.assertEqual( - testcase_parser.eval_content_variables("$var_1"), + testcase_parser._eval_content_variables("$var_1"), "abc" ) self.assertEqual( - testcase_parser.eval_content_variables("var_1"), + testcase_parser._eval_content_variables("var_1"), "var_1" ) self.assertEqual( - testcase_parser.eval_content_variables("$var_1#XYZ"), + testcase_parser._eval_content_variables("$var_1#XYZ"), "abc#XYZ" ) self.assertEqual( - testcase_parser.eval_content_variables("/$var_1/$var_2/var3"), + testcase_parser._eval_content_variables("/$var_1/$var_2/var3"), "/abc/def/var3" ) self.assertEqual( - testcase_parser.eval_content_variables("/$var_1/$var_2/$var_1"), + testcase_parser._eval_content_variables("/$var_1/$var_2/$var_1"), "/abc/def/abc" ) self.assertEqual( - testcase_parser.eval_content_variables("${func($var_1, $var_2, xyz)}"), + testcase_parser._eval_content_variables("${func($var_1, $var_2, xyz)}"), "${func(abc, def, xyz)}" ) self.assertEqual( - testcase_parser.eval_content_variables("$var_3"), + testcase_parser._eval_content_variables("$var_3"), 123 ) self.assertEqual( - testcase_parser.eval_content_variables("$var_4"), + testcase_parser._eval_content_variables("$var_4"), {"a": 1} ) self.assertEqual( - testcase_parser.eval_content_variables("$var_5"), + testcase_parser._eval_content_variables("$var_5"), True ) self.assertEqual( - testcase_parser.eval_content_variables("abc$var_5"), + testcase_parser._eval_content_variables("abc$var_5"), "abcTrue" ) self.assertEqual( - testcase_parser.eval_content_variables("abc$var_4"), + testcase_parser._eval_content_variables("abc$var_4"), "abc{'a': 1}" ) self.assertEqual( - testcase_parser.eval_content_variables("$var_6"), + testcase_parser._eval_content_variables("$var_6"), None ) @@ -299,10 +299,10 @@ class TestcaseParserUnittest(unittest.TestCase): testcase_parser = testcase.TestcaseParser() with self.assertRaises(ParamsError): - testcase_parser.eval_content_variables("/api/$SECRET_KEY") + testcase_parser._eval_content_variables("/api/$SECRET_KEY") testcase_parser.file_path = "tests/data/demo_testset_hardcode.yml" - content = testcase_parser.eval_content_variables("/api/$SECRET_KEY") + content = testcase_parser._eval_content_variables("/api/$SECRET_KEY") self.assertEqual(content, "/api/DebugTalk") def test_parse_string_value(self): @@ -345,23 +345,23 @@ class TestcaseParserUnittest(unittest.TestCase): } testcase_parser = testcase.TestcaseParser(variables=variables) self.assertEqual( - testcase_parser.parse_content_with_bindings("$str_1"), + testcase_parser.eval_content_with_bindings("$str_1"), "str_value1" ) self.assertEqual( - testcase_parser.parse_content_with_bindings("123$str_1/456"), + testcase_parser.eval_content_with_bindings("123$str_1/456"), "123str_value1/456" ) with self.assertRaises(ParamsError): - testcase_parser.parse_content_with_bindings("$str_3") + testcase_parser.eval_content_with_bindings("$str_3") self.assertEqual( - testcase_parser.parse_content_with_bindings(["$str_1", "str3"]), + testcase_parser.eval_content_with_bindings(["$str_1", "str3"]), ["str_value1", "str3"] ) self.assertEqual( - testcase_parser.parse_content_with_bindings({"key": "$str_1"}), + testcase_parser.eval_content_with_bindings({"key": "$str_1"}), {"key": "str_value1"} ) @@ -373,7 +373,7 @@ class TestcaseParserUnittest(unittest.TestCase): testcase_parser = testcase.TestcaseParser(variables=variables) content = "/users/$userid/training/$data?userId=$userid&data=$data" self.assertEqual( - testcase_parser.parse_content_with_bindings(content), + testcase_parser.eval_content_with_bindings(content), "/users/100/training/1498?userId=100&data=1498" ) @@ -386,7 +386,7 @@ class TestcaseParserUnittest(unittest.TestCase): testcase_parser = testcase.TestcaseParser(variables=variables) content = "/users/$user/$userid/$data?userId=$userid&data=$data" self.assertEqual( - testcase_parser.parse_content_with_bindings(content), + testcase_parser.eval_content_with_bindings(content), "/users/100/1000/1498?userId=1000&data=1498" ) @@ -398,17 +398,17 @@ class TestcaseParserUnittest(unittest.TestCase): } testcase_parser = testcase.TestcaseParser(functions=functions) - result = testcase_parser.parse_content_with_bindings("${gen_random_string(5)}") + result = testcase_parser.eval_content_with_bindings("${gen_random_string(5)}") self.assertEqual(len(result), 5) add_two_nums = lambda a, b=1: a + b functions["add_two_nums"] = add_two_nums self.assertEqual( - testcase_parser.parse_content_with_bindings("${add_two_nums(1)}"), + testcase_parser.eval_content_with_bindings("${add_two_nums(1)}"), 2 ) self.assertEqual( - testcase_parser.parse_content_with_bindings("${add_two_nums(1, 2)}"), + testcase_parser.eval_content_with_bindings("${add_two_nums(1, 2)}"), 3 ) @@ -452,11 +452,11 @@ class TestcaseParserUnittest(unittest.TestCase): } testcase_parser = testcase.TestcaseParser(functions=functions) self.assertEqual( - testcase_parser.eval_content_functions("${add_two_nums(1, 2)}"), + testcase_parser._eval_content_functions("${add_two_nums(1, 2)}"), 3 ) self.assertEqual( - testcase_parser.eval_content_functions("/api/${add_two_nums(1, 2)}"), + testcase_parser._eval_content_functions("/api/${add_two_nums(1, 2)}"), "/api/3" ) @@ -464,10 +464,10 @@ class TestcaseParserUnittest(unittest.TestCase): testcase_parser = testcase.TestcaseParser() with self.assertRaises(ParamsError): - testcase_parser.eval_content_functions("/api/${gen_md5(abc)}") + testcase_parser._eval_content_functions("/api/${gen_md5(abc)}") testcase_parser.file_path = "tests/data/demo_testset_hardcode.yml" - content = testcase_parser.eval_content_functions("/api/${gen_md5(abc)}") + content = testcase_parser._eval_content_functions("/api/${gen_md5(abc)}") self.assertEqual(content, "/api/900150983cd24fb0d6963f7d28e17f72") def test_parse_content_with_bindings_testcase(self): @@ -493,7 +493,7 @@ class TestcaseParserUnittest(unittest.TestCase): "body": "$data" } parsed_testcase = testcase.TestcaseParser(variables, functions)\ - .parse_content_with_bindings(testcase_template) + .eval_content_with_bindings(testcase_template) self.assertEqual( parsed_testcase["url"],