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 __call__(self, decorated_function): Builder.add_group_rule(suites=self.group, decorated_function=decorated_function, decorator_kwargs=self.decorator_kwargs, decorator_type=DecoratorType.BEFORE_GROUP) return decorated_function
def __call__(self, decorated_function): Builder.build_suite_definitions( decorated_function=decorated_function, decorator_kwargs=self.decorator_kwargs, decorator_type=DecoratorType.AFTER_CLASS) return decorated_function
def __call__(self, cls): Builder.build_suite_definitions( decorated_function=cls, decorator_kwargs=self.decorator_kwargs, decorator_type=DecoratorType.TEST_SUITE) return cls
def get_meta(suite, parameter=None, suite_parameter=None): """ Use this function inside a @test() where you want to check the current values of the metadata for that test :param suite: Object, class object that the test is part of. Typically will be "self". :param parameter: User defined parameter for the test. :param suite_parameter: User defined suite parameter for the test. :return: Dictionary """ def __get_test_metadata(class_object): for frame in inspect.stack(): try: getattr(class_object.get_class_object(), str(inspect.getframeinfo(frame[0]).function)) test_function_name = str(inspect.getframeinfo(frame[0]).function) for test_object in class_object.get_test_objects(): if test_object.get_function_name() == test_function_name: return test_object.get_meta(parameter, suite_parameter) except: pass from test_junkie.builder import Builder suite_objects = Builder.get_execution_roster().values() for suite_object in suite_objects: if suite.__class__ == suite_object.get_class_object(): metadata = __get_test_metadata(suite_object) if metadata is not None: return metadata
def get_meta(suite, parameter=None, suite_parameter=None): from test_junkie.builder import Builder suite_objects = Builder.get_execution_roster().values() for suite_object in suite_objects: if suite.__class__ == suite_object.get_class_object(): m = suite_object._get_test_meta(parameter, suite_parameter) if m is not None: return m
def update(suite, parameter=None, suite_parameter=None, **kwargs): from test_junkie.builder import Builder suite_objects = Builder.get_execution_roster().values() for suite_object in suite_objects: if suite.__class__ == suite_object.get_class_object(): if suite_object._update_test_meta(parameter, suite_parameter, **kwargs) is True: return
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 __init__(self, suites, args): self.aggregated_data = { "absolute_test_count": 0, # parameterized tests will be treated as 1 test "absolute_suite_count": 0, "context_by_features": {}, "context_by_owners": {}, "context_by_suites": {}, "context_by_tags": {}, "context_by_components": {}, "parameterized_test_count": 0, "parameterized_suite_count": 0, } self.suites = suites self.exe_roster = Builder.get_execution_roster() self.args = args
def run(self, **kwargs): """ Initiates the execution process that runs tests :return: None """ self.__settings = Settings(runner_kwargs=self.__kwargs, run_kwargs=kwargs) initial_start_time = time.time() resource_monitor = None try: if self.__settings.monitor_resources: resource_monitor = ResourceMonitor() resource_monitor.start() self.__processor = ParallelProcessor(self.__settings) with suppressed_stdout(self.__settings.quiet): while self.__suites: for suite in list(self.__suites): suite_object = Builder.get_execution_roster().get( suite, None) if suite_object is not None: if self.__processor.suite_multithreading( ) and suite_object.is_parallelized(): while True: if self.__processor.suite_qualifies( suite_object): time.sleep( Limiter.get_suite_throttling()) self.__executed_suites.append( suite_object) ParallelProcessor.run_suite_in_a_thread( self.__run_suite, suite_object) self.__suites.remove(suite) break elif suite_object.get_priority() is None: break else: time.sleep(1) else: if not suite_object.is_parallelized(): LogJunkie.debug( "Cant run suite: {} in parallel with any other suites. Waiting for " "parallel suites to finish so I can run it by itself." .format( suite_object.get_class_object())) ParallelProcessor.wait_currently_active_suites_to_finish( ) self.__executed_suites.append(suite_object) self.__run_suite(suite_object) self.__suites.remove(suite) else: LogJunkie.warn( "Suite: {} not found! Make sure that your input is correct. " "If it is, make sure the use of Test Junkie's decorators " "is correct.".format(suite)) self.__suites.remove(suite) LogJunkie.debug("{} Suite(s) left in queue.".format( len(self.__suites))) time.sleep(0.2) ParallelProcessor.wait_currently_active_suites_to_finish() finally: if self.__settings.monitor_resources: resource_monitor.shutdown() runtime = time.time() - initial_start_time print("========== Test Junkie finished in {:0.2f} seconds ==========". format(runtime)) aggregator = Aggregator(self.get_executed_suites()) Aggregator.present_console_output(aggregator) if self.__settings.html_report: reporter = Reporter( monitoring_file=resource_monitor.get_file_path() if resource_monitor is not None else None, runtime=runtime, aggregator=aggregator, multi_threading_enabled=self.__processor.test_multithreading() or self.__processor.suite_multithreading()) reporter.generate_html_report(self.__settings.html_report) XmlReporter.create_xml_report(write_file=self.__settings.xml_report, suites=self.get_executed_suites()) if self.__settings.monitor_resources: resource_monitor.cleanup() return aggregator
def __call__(self, decorated_function): Builder.register_group_rules(decorated_function=decorated_function, decorator_kwargs=self.decorator_kwargs, decorator_type=DecoratorType.GROUP_RULES) return decorated_function