From 31f72356dd442f9bb6d0853550a0e8105eb4d4a6 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Wed, 22 Aug 2018 18:35:15 +0800 Subject: [PATCH] parse_parameters: add csv support --- httprunner/context.py | 66 ------------------------------------------- httprunner/loader.py | 10 +++++-- httprunner/parser.py | 10 +++---- tests/test_parser.py | 64 ++++++++++++++++++++++------------------- 4 files changed, 47 insertions(+), 103 deletions(-) diff --git a/httprunner/context.py b/httprunner/context.py index ba3d80b7..b41733a6 100644 --- a/httprunner/context.py +++ b/httprunner/context.py @@ -5,72 +5,6 @@ import copy from httprunner import exceptions, logger, parser, utils from httprunner.compat import OrderedDict -# def parse_parameters(parameters, testset_path=None): -# """ parse parameters and generate cartesian product. - -# Args: -# parameters (list) parameters: parameter name and value in list -# parameter value may be in three types: -# (1) data list, e.g. ["iOS/10.1", "iOS/10.2", "iOS/10.3"] -# (2) call built-in parameterize function, "${parameterize(account.csv)}" -# (3) call custom function in debugtalk.py, "${gen_app_version()}" - -# testset_path (str): testset file path, used for locating csv file and debugtalk.py - -# Returns: -# list: cartesian product list - -# Examples: -# >>> parameters = [ -# {"user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"]}, -# {"username-password": "${parameterize(account.csv)}"}, -# {"app_version": "${gen_app_version()}"} -# ] -# >>> parse_parameters(parameters) - -# """ -# testcase_parser = TestcaseParser(file_path=testset_path) - -# parsed_parameters_list = [] -# for parameter in parameters: -# parameter_name, parameter_content = list(parameter.items())[0] -# parameter_name_list = parameter_name.split("-") - -# if isinstance(parameter_content, list): -# # (1) data list -# # e.g. {"app_version": ["2.8.5", "2.8.6"]} -# # => [{"app_version": "2.8.5", "app_version": "2.8.6"}] -# # e.g. {"username-password": [["user1", "111111"], ["test2", "222222"]} -# # => [{"username": "user1", "password": "111111"}, {"username": "user2", "password": "222222"}] -# parameter_content_list = [] -# for parameter_item in parameter_content: -# if not isinstance(parameter_item, (list, tuple)): -# # "2.8.5" => ["2.8.5"] -# parameter_item = [parameter_item] - -# # ["app_version"], ["2.8.5"] => {"app_version": "2.8.5"} -# # ["username", "password"], ["user1", "111111"] => {"username": "user1", "password": "111111"} -# parameter_content_dict = dict(zip(parameter_name_list, parameter_item)) - -# parameter_content_list.append(parameter_content_dict) -# else: -# # (2) & (3) -# parsed_parameter_content = testcase_parser.eval_content_with_bindings(parameter_content) -# # e.g. [{'app_version': '2.8.5'}, {'app_version': '2.8.6'}] -# # e.g. [{"username": "user1", "password": "111111"}, {"username": "user2", "password": "222222"}] -# if not isinstance(parsed_parameter_content, list): -# raise exceptions.ParamsError("parameters syntax error!") - -# parameter_content_list = [ -# # get subset by parameter name -# {key: parameter_item[key] for key in parameter_name_list} -# for parameter_item in parsed_parameter_content -# ] - -# parsed_parameters_list.append(parameter_content_list) - -# return utils.gen_cartesian_product(*parsed_parameters_list) - class Context(object): """ Manages context functions and variables. diff --git a/httprunner/loader.py b/httprunner/loader.py index 8a118aea..141c2601 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -10,7 +10,10 @@ from httprunner import built_in, exceptions, logger, parser, validator from httprunner.compat import OrderedDict project_mapping = { - "debugtalk": {}, + "debugtalk": { + "variables": {}, + "functions": {} + }, "env": {}, "def-api": {}, "def-testcase": {} @@ -887,7 +890,10 @@ def load_test_folder(test_folder_path=None): def reset_loader(): """ reset project mapping. """ - project_mapping["debugtalk"] = {} + project_mapping["debugtalk"] = { + "variables": {}, + "functions": {} + } project_mapping["env"] = {} project_mapping["def-api"] = {} project_mapping["def-testcase"] = {} diff --git a/httprunner/parser.py b/httprunner/parser.py index c6115769..58827ff8 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -8,8 +8,8 @@ from httprunner import exceptions, utils from httprunner.compat import basestring, builtin_str, numeric_types, str variable_regexp = r"\$([\w_]+)" -function_regexp = r"\$\{([\w_]+\([\$\w\.\-_ =,]*\))\}" -function_regexp_compile = re.compile(r"^([\w_]+)\(([\$\w\.\-_ =,]*)\)$") +function_regexp = r"\$\{([\w_]+\([\$\w\.\-/_ =,]*\))\}" +function_regexp_compile = re.compile(r"^([\w_]+)\(([\$\w\.\-/_ =,]*)\)$") def parse_string_value(str_value): @@ -255,7 +255,6 @@ def substitute_variables(content, variables_mapping): return content - def parse_parameters(parameters, variables_mapping, functions_mapping): """ parse parameters and generate cartesian product. @@ -404,9 +403,8 @@ def parse_string_functions(content, variables_mapping, functions_mapping): kwargs = parse_data(kwargs, variables_mapping, functions_mapping) if func_name in ["parameterize", "P"]: - # TODO: add parameterize - # eval_value = load_csv_list(*args, **kwargs) - pass + from httprunner import loader + eval_value = loader.load_csv_file(*args, **kwargs) else: func = get_mapping_function(func_name, functions_mapping) eval_value = func(*args, **kwargs) diff --git a/tests/test_parser.py b/tests/test_parser.py index c0005284..42c7ebfa 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -384,8 +384,6 @@ class TestParser(unittest.TestCase): os.getcwd(), "tests/data/demo_parameters.yml" ) - variables_mapping = {} - functions_mapping = {} from tests import debugtalk debugtalk_module = loader.load_python_module(debugtalk) cartesian_product_parameters = parser.parse_parameters( @@ -398,32 +396,40 @@ class TestParser(unittest.TestCase): 2 * 2 ) - # def test_parse_parameters_parameterize(self): - # parameters = [ - # {"app_version": "${parameterize(app_version.csv)}"}, - # {"username-password": "${parameterize(account.csv)}"} - # ] + def test_parse_parameters_parameterize(self): + parameters = [ + {"app_version": "${parameterize(tests/data/app_version.csv)}"}, + {"username-password": "${parameterize(tests/data/account.csv)}"} + ] + variables_mapping = {} + functions_mapping = {} - # cartesian_product_parameters = parser.parse_parameters( - # parameters, variables_mapping, functions_mapping) - # self.assertEqual( - # len(cartesian_product_parameters), - # 2 * 3 - # ) + cartesian_product_parameters = parser.parse_parameters( + parameters, variables_mapping, functions_mapping) + self.assertEqual( + len(cartesian_product_parameters), + 2 * 3 + ) - # def test_parse_parameters_mix(self): - # parameters = [ - # {"user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"]}, - # {"app_version": "${gen_app_version()}"}, - # {"username-password": "${parameterize(account.csv)}"} - # ] - # testset_path = os.path.join( - # os.getcwd(), - # "tests/data/demo_parameters.yml" - # ) - # cartesian_product_parameters = parser.parse_parameters( - # parameters, variables_mapping, functions_mapping) - # self.assertEqual( - # len(cartesian_product_parameters), - # 3 * 2 * 3 - # ) + def test_parse_parameters_mix(self): + project_dir = os.path.join(os.getcwd(), "tests") + loader.load_debugtalk_module(project_dir) + project_mapping = loader.project_mapping + + parameters = [ + {"user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"]}, + {"app_version": "${gen_app_version()}"}, + {"username-password": "${parameterize(tests/data/account.csv)}"} + ] + variables_mapping = {} + functions_mapping = project_mapping["debugtalk"]["functions"] + testset_path = os.path.join( + os.getcwd(), + "tests/data/demo_parameters.yml" + ) + cartesian_product_parameters = parser.parse_parameters( + parameters, variables_mapping, functions_mapping) + self.assertEqual( + len(cartesian_product_parameters), + 3 * 2 * 3 + )