diff --git a/httprunner/loader.py b/httprunner/loader.py index b0e6d7b9..02eb2f3e 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -5,7 +5,7 @@ import json import os import yaml -from httprunner import exceptions, logger, parser, utils, validator +from httprunner import exceptions, logger, parser, validator from httprunner.compat import OrderedDict ############################################################################### @@ -331,7 +331,7 @@ def _get_block_by_name(ref_call, ref_type): args_mapping[item] = call_args[index] if args_mapping: - block = utils.substitute_variables_with_mapping(block, args_mapping) + block = parser.parse_data(block, args_mapping) return block diff --git a/httprunner/parser.py b/httprunner/parser.py index 906f30e1..33efdaa6 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -136,6 +136,63 @@ def parse_validator(validator): } +def parse_data(content, mapping): + """ substitute variables in content with mapping + e.g. + @params + content = { + 'request': { + 'url': '/api/users/$uid', + 'headers': {'token': '$token'} + } + } + mapping = {"$uid": 1000} + @return + { + 'request': { + 'url': '/api/users/1000', + 'headers': {'token': '$token'} + } + } + """ + # TODO: refactor type check + if isinstance(content, bool): + return content + + if isinstance(content, (numeric_types, type)): + return content + + if not content: + return content + + if isinstance(content, (list, set, tuple)): + return [ + parse_data(item, mapping) + for item in content + ] + + if isinstance(content, dict): + substituted_data = {} + for key, value in content.items(): + eval_key = parse_data(key, mapping) + eval_value = parse_data(value, mapping) + substituted_data[eval_key] = eval_value + + return substituted_data + + # content is in string format here + for var, value in mapping.items(): + if content == var: + # content is a variable + content = value + else: + if not isinstance(value, str): + value = builtin_str(value) + content = content.replace(var, value) + + return content + + def parse_parameters(parameters, testset_path=None): """ parse parameters and generate cartesian product @params diff --git a/httprunner/utils.py b/httprunner/utils.py index 21141524..cf4f8356 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -15,8 +15,7 @@ import types from datetime import datetime from httprunner import exceptions, logger -from httprunner.compat import (OrderedDict, basestring, builtin_str, is_py2, - is_py3, numeric_types, str) +from httprunner.compat import OrderedDict, basestring, is_py2, is_py3 from requests.structures import CaseInsensitiveDict SECRET_KEY = "DebugTalk" @@ -87,63 +86,6 @@ def query_json(json_content, query, delimiter='.'): return json_content -def substitute_variables_with_mapping(content, mapping): - """ substitute variables in content with mapping - e.g. - @params - content = { - 'request': { - 'url': '/api/users/$uid', - 'headers': {'token': '$token'} - } - } - mapping = {"$uid": 1000} - @return - { - 'request': { - 'url': '/api/users/1000', - 'headers': {'token': '$token'} - } - } - """ - # TODO: refactor type check - if isinstance(content, bool): - return content - - if isinstance(content, (numeric_types, type)): - return content - - if not content: - return content - - if isinstance(content, (list, set, tuple)): - return [ - substitute_variables_with_mapping(item, mapping) - for item in content - ] - - if isinstance(content, dict): - substituted_data = {} - for key, value in content.items(): - eval_key = substitute_variables_with_mapping(key, mapping) - eval_value = substitute_variables_with_mapping(value, mapping) - substituted_data[eval_key] = eval_value - - return substituted_data - - # content is in string format here - for var, value in mapping.items(): - if content == var: - # content is a variable - content = value - else: - if not isinstance(value, str): - value = builtin_str(value) - content = content.replace(var, value) - - return content - - def get_uniform_comparator(comparator): """ convert comparator alias to uniform name """ diff --git a/tests/test_parser.py b/tests/test_parser.py index 13e1390b..6bd50c5e 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -185,6 +185,33 @@ class TestParser(unittest.TestCase): 3 * 2 * 3 ) + def test_parse_data(self): + content = { + 'request': { + 'url': '/api/users/$uid', + 'method': "$method", + 'headers': {'token': '$token'}, + 'data': { + "null": None, + "true": True, + "false": False, + "empty_str": "" + } + } + } + mapping = { + "$uid": 1000, + "$method": "POST" + } + result = parser.parse_data(content, mapping) + self.assertEqual("/api/users/1000", result["request"]["url"]) + self.assertEqual("$token", result["request"]["headers"]["token"]) + self.assertEqual("POST", result["request"]["method"]) + self.assertIsNone(result["request"]["data"]["null"]) + self.assertTrue(result["request"]["data"]["true"]) + self.assertFalse(result["request"]["data"]["false"]) + self.assertEqual("", result["request"]["data"]["empty_str"]) + class TestTestcaseParser(unittest.TestCase): diff --git a/tests/test_utils.py b/tests/test_utils.py index e59e078f..72bf9506 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -61,33 +61,6 @@ class TestUtils(ApiServerUnittest): result = utils.query_json(json_content, query) self.assertEqual(result, "L") - def test_substitute_variables_with_mapping(self): - content = { - 'request': { - 'url': '/api/users/$uid', - 'method': "$method", - 'headers': {'token': '$token'}, - 'data': { - "null": None, - "true": True, - "false": False, - "empty_str": "" - } - } - } - mapping = { - "$uid": 1000, - "$method": "POST" - } - result = utils.substitute_variables_with_mapping(content, mapping) - self.assertEqual("/api/users/1000", result["request"]["url"]) - self.assertEqual("$token", result["request"]["headers"]["token"]) - self.assertEqual("POST", result["request"]["method"]) - self.assertIsNone(result["request"]["data"]["null"]) - self.assertTrue(result["request"]["data"]["true"]) - self.assertFalse(result["request"]["data"]["false"]) - self.assertEqual("", result["request"]["data"]["empty_str"]) - def test_get_uniform_comparator(self): self.assertEqual(utils.get_uniform_comparator("eq"), "equals") self.assertEqual(utils.get_uniform_comparator("=="), "equals")