def test_cartesian_product_multiple(self): parameters_content_list = [[{ "a": 1 }, { "a": 2 }], [{ "x": 111, "y": 112 }, { "x": 121, "y": 122 }]] product_list = utils.gen_cartesian_product(*parameters_content_list) self.assertEqual(product_list, [{ 'a': 1, 'x': 111, 'y': 112 }, { 'a': 1, 'x': 121, 'y': 122 }, { 'a': 2, 'x': 111, 'y': 112 }, { 'a': 2, 'x': 121, 'y': 122 }])
def parse_parameters(parameters, variables_mapping, functions_mapping): ''' parse parameters and generate cartesian product Args: parameters (list):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, "${parameter(account.csv)}" (3) call custom function in confcustom.py, ${gen_app_version()} variables_mapping (dict): variables mapping loaded from confcustom.py functions_mapping (dict): functions mapping loaded from confcustom.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_verison': '${gen_app_version()}'} ] >>> parse_parameters(parameters) ''' 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'],['user2','222222']]} # => [{'username':'******','password':'******'},{'username':'******','password':'******'}] 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'} parameter_content_dict = dict( zip(parameter_name_list, parameter_item)) parameter_content_list.append(parameter_content_dict) else: # (2) & (3) parsed_parameter_content = parse_data(parameter_content, variables_mapping, functions_mapping) if not isinstance(parsed_parameter_content, list): raise exceptions.ParamError( f'{parameters} parameters syntax error!') parameter_content_list = [{ 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)
def test_cartesian_product_one(self): parameters_content_list = [ [ {"a": 1}, {"a": 2} ] ] product_list = utils.gen_cartesian_product(*parameters_content_list) self.assertEqual( product_list, [ {"a": 1}, {"a": 2} ] )
def test_cartesian_product_empty(self): parameters_content_list = [] product_list = utils.gen_cartesian_product(*parameters_content_list) self.assertEqual(product_list, [])
def parse_parameters(parameters, variables_mapping=None, functions_mapping=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()}" variables_mapping (dict): variables mapping loaded from testcase config functions_mapping (dict): functions mapping loaded from debugtalk.py Returns: list: cartesian product list Examples: >>> parameters = [ {"user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"]}, {"username-password": "******"}, {"app_version": "${gen_app_version()}"} ] >>> parse_parameters(parameters) """ variables_mapping = variables_mapping or {} functions_mapping = functions_mapping or {} parsed_parameters_list = [] parameters = utils.ensure_mapping_format(parameters) for parameter_name, parameter_content in parameters.items(): 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": "******", "password": "******"}, {"username": "******", "password": "******"}] 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": "******", "password": "******"} parameter_content_dict = dict( zip(parameter_name_list, parameter_item)) parameter_content_list.append(parameter_content_dict) else: # (2) & (3) parsed_variables_mapping = parse_variables_mapping( variables_mapping) parsed_parameter_content = eval_lazy_data( parameter_content, parsed_variables_mapping, functions_mapping) if not isinstance(parsed_parameter_content, list): raise exceptions.ParamsError("parameters syntax error!") parameter_content_list = [] for parameter_item in parsed_parameter_content: if isinstance(parameter_item, dict): # get subset by parameter name # {"app_version": "${gen_app_version()}"} # gen_app_version() => [{'app_version': '2.8.5'}, {'app_version': '2.8.6'}] # {"username-password": "******"} # get_account() => [ # {"username": "******", "password": "******"}, # {"username": "******", "password": "******"} # ] parameter_dict = { key: parameter_item[key] for key in parameter_name_list } elif isinstance(parameter_item, (list, tuple)): # {"username-password": "******"} # get_account() => [("user1", "111111"), ("user2", "222222")] parameter_dict = dict( zip(parameter_name_list, parameter_item)) elif len(parameter_name_list) == 1: # {"user_agent": "${get_user_agent()}"} # get_user_agent() => ["iOS/10.1", "iOS/10.2"] parameter_dict = {parameter_name_list[0]: parameter_item} parameter_content_list.append(parameter_dict) parsed_parameters_list.append(parameter_content_list) return utils.gen_cartesian_product(*parsed_parameters_list)
def parse_parameters(parameters: Dict, ) -> List[Dict]: """ parse parameters and generate cartesian product. Args: parameters (Dict) parameters: parameter name and value mapping 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()}" Returns: list: cartesian product list Examples: >>> parameters = { "user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"], "username-password": "******", "app_version": "${gen_app_version()}", } >>> parse_parameters(parameters) """ parsed_parameters_list: List[List[Dict]] = [] # load project_meta functions project_meta = loader.load_project_meta(os.getcwd()) functions_mapping = project_meta.functions for parameter_name, parameter_content in parameters.items(): 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": "******", "password": "******"}, {"username": "******", "password": "******"}] parameter_content_list: List[Dict] = [] 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": "******", "password": "******"} parameter_content_dict = dict(zip(parameter_name_list, parameter_item)) parameter_content_list.append(parameter_content_dict) elif isinstance(parameter_content, Text): # (2) & (3) parsed_parameter_content: List = parse_data( parameter_content, {}, functions_mapping ) if not isinstance(parsed_parameter_content, List): raise exceptions.ParamsError( f"parameters content should be in List type, got {parsed_parameter_content} for {parameter_content}" ) parameter_content_list: List[Dict] = [] for parameter_item in parsed_parameter_content: if isinstance(parameter_item, Dict): # get subset by parameter name # {"app_version": "${gen_app_version()}"} # gen_app_version() => [{'app_version': '2.8.5'}, {'app_version': '2.8.6'}] # {"username-password": "******"} # get_account() => [ # {"username": "******", "password": "******"}, # {"username": "******", "password": "******"} # ] parameter_dict: Dict = { key: parameter_item[key] for key in parameter_name_list } elif isinstance(parameter_item, (List, tuple)): if len(parameter_name_list) == len(parameter_item): # {"username-password": "******"} # get_account() => [("user1", "111111"), ("user2", "222222")] parameter_dict = dict(zip(parameter_name_list, parameter_item)) else: raise exceptions.ParamsError( f"parameter names length are not equal to value length.\n" f"parameter names: {parameter_name_list}\n" f"parameter values: {parameter_item}" ) elif len(parameter_name_list) == 1: # {"user_agent": "${get_user_agent()}"} # get_user_agent() => ["iOS/10.1", "iOS/10.2"] # parameter_dict will get: {"user_agent": "iOS/10.1", "user_agent": "iOS/10.2"} parameter_dict = {parameter_name_list[0]: parameter_item} else: raise exceptions.ParamsError( f"Invalid parameter names and values:\n" f"parameter names: {parameter_name_list}\n" f"parameter values: {parameter_item}" ) parameter_content_list.append(parameter_dict) else: raise exceptions.ParamsError( f"parameter content should be List or Text(variables or functions call), got {parameter_content}" ) parsed_parameters_list.append(parameter_content_list) return utils.gen_cartesian_product(*parsed_parameters_list)
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": "******"}, {"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": "******", "password": "******"}, {"username": "******", "password": "******"}] 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": "******", "password": "******"} 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": "******", "password": "******"}, {"username": "******", "password": "******"}] 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)