def __validate_suite_parameters(suite): parameters = suite.get_parameters(process_functions=True) if not parameters or not isinstance(parameters, list): if isinstance(parameters, list): return BadParameters( "Argument: \"parameters\" in @Suite() decorator returned empty: <class 'list'>. " "For more info, see this explanation: {}".format( DocumentationLinks.ON_CLASS_IGNORE)) else: return BadParameters( "Argument: \"parameters\" in @Suite() decorator must be of type: <class 'list'> " "but found: {}. For more info, see @Suite() decorator documentation: {}" .format(type(parameters), DocumentationLinks.SUITE_DECORATOR)) return False
def __init__(self, suites, **kwargs): if not suites or not isinstance(suites, list): raise BadParameters( "Runner needs to be initiated with a mandatory argument \"suites\" which must be of " "type {} and it can not be empty. Instead got: {}. Please see documentation: {}" .format(list, suites, DocumentationLinks.RUNNER_OBJECT)) self.__stats = {} self.__suites = self.__prioritize(suites=suites) for suite in self.__suites: suite_object = Builder.get_execution_roster().get(suite, None) suite_object.update_test_objects( self.__prioritize(suite_object=suite_object)) Runner.__process_owners(suite_object) self.__kwargs = kwargs self.__settings = None self.__processor = None self.__cancel = False self.__executed_suites = [] self.__active_suites = [] self.__group_rules = Builder.build_group_definitions(self.__suites) self.__before_group_failure_records = {}
def eval_skip(obj): val = obj.get_skip() try: if not isinstance(val, bool): if inspect.isfunction(val): val = val(meta=obj.get_meta( )) if "meta" in inspect.getargspec(val).args else val() elif inspect.ismethod(val): val = getattr(val.__self__, val.__name__)(meta=obj.get_meta()) \ if "meta" in inspect.getargspec(val).args \ else getattr(val.__self__, val.__name__)() else: raise BadParameters( "Unsupported data type used to pass parameters to the skip property in test: " "{}.{}".format(obj.get_function_module(), obj.get_function_name())) assert isinstance(val, bool), "You were using a function/unbound method to pass parameters to the skip"\ " property in test {}.{} which must return a boolean value. "\ "Got: {} instead of a boolean".format(obj.get_function_module(), obj.get_function_name(), type(val)) except Exception: traceback.print_exc() raise TestJunkieExecutionError( "Encountered error while processing skip condition") return val
def add_group_rule(suites, decorated_function, decorator_kwargs, decorator_type): if not suites or not isinstance(suites, list): raise BadParameters( "Group Rules must be defined with a mandatory argument \"suites\" which must be " "of type {}. Please see documentation: {}".format( list, DocumentationLinks.GROUP_RULES)) suites = sorted(set(suites), key=lambda x: str(x), reverse=True) for suite in list(suites): if suite not in Builder.__REQUESTED_SUITES: suites.remove(suite) if suites: # making sure that rules only apply when we actually run applicable test suites group = hashlib.md5(str(suites).encode("utf8")).hexdigest() if group not in Builder.__GROUP_RULE_DEFINITIONS: Builder.__GROUP_RULE_DEFINITIONS.update( {group: { "suites": suites, "rules": {} }}) if decorator_type not in Builder.__GROUP_RULE_DEFINITIONS[group][ "rules"]: Builder.__GROUP_RULE_DEFINITIONS[group]["rules"].update( {decorator_type: []}) Builder.__GROUP_RULE_DEFINITIONS[group]["rules"][ decorator_type].append({ "decorated_function": decorated_function, "decorator_kwargs": decorator_kwargs })
def __validate_suite_kwargs(kwargs): data = Builder.__validation_failed(kwargs) if data: raise BadParameters( "Argument: \"{}\" in @Suite() decorator must be of either type: {} but found: {}. " "For more info, see @Suite() decorator documentation: {}". format(data["arg"], data["expected"], data["actual"], DocumentationLinks.SUITE_DECORATOR))
def xml_report(self): if self.__xml_report is Undefined: self.__xml_report = self.__get_value( key="xml_report", default=Settings.__DEFAULT_XML) if self.__xml_report and not self.__xml_report.endswith(".xml"): raise BadParameters( "\"xml_report\" parameter requires full path with a file name and .html extension " "for example: /var/www/html/my_report.xml. For more info, see documentation: {link}" .format(link=DocumentationLinks.XML_REPORT)) return self.__xml_report
def __prioritize(suites=None, suite_object=None): """ This function will order the lists of suites and tests according to the priority set by user - Suites/Tests with priorities, will be pushed towards the front according to the priorities defined - Suites/Tests with no priority defined, will be pushed towards the middle - Suites/Tests with no priority defined and not parallelized, will be pushed towards the end :param suites: LIST of class objects decorated with @Suite :param suite_object: SuiteObject :return: LIST ordered list of suites or tests """ ordered = [] priorities = {} no_priority = [] not_parallelized = [] items = suites if suites is not None else suite_object.get_test_objects( ) for item in items: if suites is not None: suite_object = Builder.get_execution_roster().get(item, None) if suite_object is None: raise BadParameters( "Check Runner instance, you initialized it with incorrect test suite object: " "{}.".format(item)) priority = suite_object.get_priority() is_parallelized = suite_object.is_parallelized() else: priority = item.get_priority() is_parallelized = item.is_parallelized() if priority is None: if is_parallelized: no_priority.append(item) else: not_parallelized.append(item) else: if priority not in priorities: priorities.update({priority: [item]}) else: priorities[priority].append(item) ordered_priorities = list(priorities.keys()) ordered_priorities.sort() for priority in ordered_priorities: for item in priorities[priority]: ordered.append(item) ordered += no_priority + not_parallelized return ordered
def __validate_test_parameters(test): parameters = test.get_parameters(process_functions=True) if not parameters or not isinstance(parameters, list): exception = None try: if isinstance(parameters, list): exception = BadParameters( "Argument: \"parameters\" in @test() decorator returned empty: " "<class 'list'>. For more info, see: {}".format( DocumentationLinks.ON_TEST_IGNORE)) else: exception = BadParameters( "Argument: \"parameters\" in @test() decorator must be of type: " "<class 'list'> but found: {}. For more info, see @test() decorator " "documentation: {}".format( type(parameters), DocumentationLinks.TEST_DECORATOR)) raise exception except: return { "exception": exception, "trace": traceback.format_exc() }
def __validate_test_kwargs(kwargs, decorated_function): data = Builder.__validation_failed(kwargs, suite=False) if data: raise BadParameters( "Argument: \"{}\" in @test() decorator must be of either type: {} but found: {}. " "For more info, see @test() decorator documentation: {}". format(data["arg"], data["expected"], data["actual"], DocumentationLinks.TEST_DECORATOR)) if "parameter" not in CU.getargspec( decorated_function).args and kwargs.get( "parameters") is not None: raise BadSignature( "When using \"parameters\" argument for @test() decorator, " "you must accept \"parameter\" in the function's signature. " "For more info, see documentation: {}".format( DocumentationLinks.PARAMETERIZED_TESTS))