diff --git a/httprunner/api.py b/httprunner/api.py index abbd1bdd..0990dd6d 100644 --- a/httprunner/api.py +++ b/httprunner/api.py @@ -1,6 +1,5 @@ # encoding: utf-8 -import copy import os import unittest @@ -8,121 +7,6 @@ from httprunner import (exceptions, loader, logger, parser, report, runner, utils, validator) -def parse_tests(testcases, variables_mapping=None): - """ parse testcases configs, including variables/parameters/name/request. - - Args: - testcases (list): testcase list, with config unparsed. - [ - { # testcase data structure - "config": { - "name": "desc1", - "path": "testcase1_path", - "variables": [], # optional - "request": {} # optional - "refs": { - "debugtalk": { - "variables": {}, - "functions": {} - }, - "env": {}, - "def-api": {}, - "def-testcase": {} - } - }, - "teststeps": [ - # teststep data structure - { - 'name': 'test step desc2', - 'variables': [], # optional - 'extract': [], # optional - 'validate': [], - 'request': {}, - 'function_meta': {} - }, - teststep2 # another teststep dict - ] - }, - testcase_dict_2 # another testcase dict - ] - variables_mapping (dict): if variables_mapping is specified, it will override variables in config block. - - Returns: - list: parsed testcases list, with config variables/parameters/name/request parsed. - - """ - # exception_stage = "parse tests" - variables_mapping = variables_mapping or {} - parsed_testcases_list = [] - - for testcase in testcases: - testcase_config = testcase.setdefault("config", {}) - project_mapping = testcase_config.pop( - "refs", - { - "debugtalk": { - "variables": {}, - "functions": {} - }, - "env": {}, - "def-api": {}, - "def-testcase": {} - } - ) - - # parse config parameters - config_parameters = testcase_config.pop("parameters", []) - cartesian_product_parameters_list = parser.parse_parameters( - config_parameters, - project_mapping["debugtalk"]["variables"], - project_mapping["debugtalk"]["functions"] - ) or [{}] - - for parameter_mapping in cartesian_product_parameters_list: - testcase_dict = copy.deepcopy(testcase) - config = testcase_dict.get("config") - - # parse config variables - raw_config_variables = config.get("variables", []) - parsed_config_variables = parser.parse_data( - raw_config_variables, - project_mapping["debugtalk"]["variables"], - project_mapping["debugtalk"]["functions"] - ) - - # priority: passed in > debugtalk.py > parameters > variables - # override variables mapping with parameters mapping - config_variables = utils.override_mapping_list( - parsed_config_variables, parameter_mapping) - # merge debugtalk.py module variables - config_variables.update(project_mapping["debugtalk"]["variables"]) - # override variables mapping with passed in variables_mapping - config_variables = utils.override_mapping_list( - config_variables, variables_mapping) - - testcase_dict["config"]["variables"] = config_variables - - # parse config name - testcase_dict["config"]["name"] = parser.parse_data( - testcase_dict["config"].get("name", ""), - config_variables, - project_mapping["debugtalk"]["functions"] - ) - - # parse config request - testcase_dict["config"]["request"] = parser.parse_data( - testcase_dict["config"].get("request", {}), - config_variables, - project_mapping["debugtalk"]["functions"] - ) - - # put loaded project functions to config - testcase_dict["config"]["functions"] = project_mapping["debugtalk"]["functions"] - parsed_testcases_list.append(testcase_dict) - - return parsed_testcases_list - - class HttpRunner(object): def __init__(self, **kwargs): @@ -315,7 +199,7 @@ class HttpRunner(object): """ # parser - parsed_testcases_list = parse_tests(testcases, mapping) + parsed_testcases_list = parser.parse_tests(testcases, mapping) # initialize test_suite = self._add_tests(parsed_testcases_list) diff --git a/httprunner/parser.py b/httprunner/parser.py index 4a467752..7ea6788b 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -556,3 +556,118 @@ def parse_data(content, variables_mapping=None, functions_mapping=None): content = parse_string_variables(content, variables_mapping) return content + + +def parse_tests(testcases, variables_mapping=None): + """ parse testcases configs, including variables/parameters/name/request. + + Args: + testcases (list): testcase list, with config unparsed. + [ + { # testcase data structure + "config": { + "name": "desc1", + "path": "testcase1_path", + "variables": [], # optional + "request": {} # optional + "refs": { + "debugtalk": { + "variables": {}, + "functions": {} + }, + "env": {}, + "def-api": {}, + "def-testcase": {} + } + }, + "teststeps": [ + # teststep data structure + { + 'name': 'test step desc2', + 'variables': [], # optional + 'extract': [], # optional + 'validate': [], + 'request': {}, + 'function_meta': {} + }, + teststep2 # another teststep dict + ] + }, + testcase_dict_2 # another testcase dict + ] + variables_mapping (dict): if variables_mapping is specified, it will override variables in config block. + + Returns: + list: parsed testcases list, with config variables/parameters/name/request parsed. + + """ + # exception_stage = "parse tests" + variables_mapping = variables_mapping or {} + parsed_testcases_list = [] + + for testcase in testcases: + testcase_config = testcase.setdefault("config", {}) + project_mapping = testcase_config.pop( + "refs", + { + "debugtalk": { + "variables": {}, + "functions": {} + }, + "env": {}, + "def-api": {}, + "def-testcase": {} + } + ) + + # parse config parameters + config_parameters = testcase_config.pop("parameters", []) + cartesian_product_parameters_list = parse_parameters( + config_parameters, + project_mapping["debugtalk"]["variables"], + project_mapping["debugtalk"]["functions"] + ) or [{}] + + for parameter_mapping in cartesian_product_parameters_list: + testcase_dict = copy.deepcopy(testcase) + config = testcase_dict.get("config") + + # parse config variables + raw_config_variables = config.get("variables", []) + parsed_config_variables = parse_data( + raw_config_variables, + project_mapping["debugtalk"]["variables"], + project_mapping["debugtalk"]["functions"] + ) + + # priority: passed in > debugtalk.py > parameters > variables + # override variables mapping with parameters mapping + config_variables = utils.override_mapping_list( + parsed_config_variables, parameter_mapping) + # merge debugtalk.py module variables + config_variables.update(project_mapping["debugtalk"]["variables"]) + # override variables mapping with passed in variables_mapping + config_variables = utils.override_mapping_list( + config_variables, variables_mapping) + + testcase_dict["config"]["variables"] = config_variables + + # parse config name + testcase_dict["config"]["name"] = parse_data( + testcase_dict["config"].get("name", ""), + config_variables, + project_mapping["debugtalk"]["functions"] + ) + + # parse config request + testcase_dict["config"]["request"] = parse_data( + testcase_dict["config"].get("request", {}), + config_variables, + project_mapping["debugtalk"]["functions"] + ) + + # put loaded project functions to config + testcase_dict["config"]["functions"] = project_mapping["debugtalk"]["functions"] + parsed_testcases_list.append(testcase_dict) + + return parsed_testcases_list diff --git a/tests/test_api.py b/tests/test_api.py index 96ce9e5f..dda9a870 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -342,7 +342,7 @@ class TestHttpRunner(ApiServerUnittest): testcase_file_path = os.path.join( os.getcwd(), 'tests/data/demo_parameters.yml') testcases = loader.load_tests(testcase_file_path) - parsed_testcases = api.parse_tests(testcases) + parsed_testcases = parser.parse_tests(testcases) runner = HttpRunner() test_suite = runner._add_tests(parsed_testcases) @@ -377,24 +377,6 @@ class TestHttpRunner(ApiServerUnittest): runner = HttpRunner().run(testcase_file_path) self.assertTrue(runner.summary["success"]) - def test_parse_tests(self): - testcase_file_path = os.path.join( - os.getcwd(), 'tests/data/demo_testcase.yml') - testcases = loader.load_tests(testcase_file_path) - parsed_testcases = api.parse_tests(testcases) - self.assertEqual(parsed_testcases[0]["config"]["variables"]["var_c"], 3) - self.assertEqual(len(parsed_testcases), 2 * 2) - self.assertEqual( - parsed_testcases[0]["config"]["request"]["base_url"], - '$BASE_URL' - ) - self.assertEqual( - parsed_testcases[0]["config"]["variables"]["BASE_URL"], - 'http://127.0.0.1:5000' - ) - self.assertIsInstance(parsed_testcases, list) - self.assertEqual(parsed_testcases[0]["config"]["name"], '12311') - class TestLocustRunner(ApiServerUnittest): diff --git a/tests/test_parser.py b/tests/test_parser.py index 9f8c0a7c..b323172a 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -435,3 +435,21 @@ class TestParser(unittest.TestCase): len(cartesian_product_parameters), 3 * 2 * 3 ) + + def test_parse_tests(self): + testcase_file_path = os.path.join( + os.getcwd(), 'tests/data/demo_testcase.yml') + testcases = loader.load_tests(testcase_file_path) + parsed_testcases = parser.parse_tests(testcases) + self.assertEqual(parsed_testcases[0]["config"]["variables"]["var_c"], 3) + self.assertEqual(len(parsed_testcases), 2 * 2) + self.assertEqual( + parsed_testcases[0]["config"]["request"]["base_url"], + '$BASE_URL' + ) + self.assertEqual( + parsed_testcases[0]["config"]["variables"]["BASE_URL"], + 'http://127.0.0.1:5000' + ) + self.assertIsInstance(parsed_testcases, list) + self.assertEqual(parsed_testcases[0]["config"]["name"], '12311')