def to_dict(self): test_method_self_t = type(six.get_method_self(self.test_method)) assert not isinstance(test_method_self_t, type(None)) return { "previous_run": self.previous_run, "start_time": time.mktime(self.start_time.timetuple()) if self.start_time else None, "end_time": time.mktime(self.end_time.timetuple()) if self.end_time else None, "run_time": (self.run_time.seconds + float(self.run_time.microseconds) / 1000000) if self.run_time is not None else None, "normalized_run_time": None if not self.run_time else "%.2fs" % (self.run_time.seconds + (self.run_time.microseconds / 1000000.0)), "complete": self.complete, "success": self.success, "failure": self.failure, "error": self.error, "interrupted": self.interrupted, "exception_info": self.format_exception_info(), "exception_info_pretty": self.format_exception_info(pretty=True), "exception_only": self.format_exception_only(), "runner_id": self.runner_id, "method": { "module": test_method_self_t.__module__, "class": test_method_self_t.__name__, "name": self.test_method.__name__, "full_name": "%s %s.%s" % (test_method_self_t.__module__, test_method_self_t.__name__, self.test_method.__name__), "fixture_type": None if not inspection.is_fixture_method(self.test_method) else self.test_method._fixture_type, }, }
def to_dict(self): test_method_self_t = type(six.get_method_self(self.test_method)) assert not isinstance(test_method_self_t, type(None)) return { 'previous_run': self.previous_run, 'start_time': time.mktime(self.start_time.timetuple()) if self.start_time else None, 'end_time': time.mktime(self.end_time.timetuple()) if self.end_time else None, 'run_time': (self.run_time.seconds + float(self.run_time.microseconds) / 1000000) if self.run_time is not None else None, 'normalized_run_time': None if not self.run_time else "%.2fs" % (self.run_time.seconds + (self.run_time.microseconds / 1000000.0)), 'complete': self.complete, 'success': self.success, 'failure': self.failure, 'error': self.error, 'interrupted': self.interrupted, 'exception_info': self.format_exception_info(), 'exception_info_pretty': self.format_exception_info(pretty=True), 'exception_only': self.format_exception_only(), 'runner_id': self.runner_id, 'method': { 'module': test_method_self_t.__module__, 'class': test_method_self_t.__name__, 'name': self.test_method.__name__, 'full_name': '%s %s.%s' % ( test_method_self_t.__module__, test_method_self_t.__name__, self.test_method.__name__, ), 'fixture_type': None if not inspection.is_fixture_method(self.test_method) else self.test_method._fixture_type, } }
def to_dict(self): return { 'previous_run' : self.previous_run, 'start_time' : time.mktime(self.start_time.timetuple()) if self.start_time else None, 'end_time' : time.mktime(self.end_time.timetuple()) if self.end_time else None, 'run_time' : (self.run_time.seconds + float(self.run_time.microseconds) / 1000000) if self.run_time else None, 'normalized_run_time' : None if not self.run_time else "%.2fs" % (self.run_time.seconds + (self.run_time.microseconds / 1000000.0)), 'complete': self.complete, 'success' : self.success, 'failure' : self.failure, 'error' : self.error, 'interrupted' : self.interrupted, 'exception_info' : self.format_exception_info(), 'exception_info_pretty' : self.format_exception_info(pretty=True), 'runner_id' : self.runner_id, 'method' : { 'module' : self.test_method.im_class.__module__, 'class' : self.test_method.im_class.__name__, 'name' : self.test_method.__name__, 'full_name' : '%s %s.%s' % (self.test_method.im_class.__module__, self.test_method.im_class.__name__, self.test_method.__name__), 'fixture_type' : None if not inspection.is_fixture_method(self.test_method) else self.test_method._fixture_type, } }
def discover_from(cls, test_case): """Initialize and populate the lists of fixture methods for this TestCase. Fixture methods are identified by the fixture_decorator_factory when the methods are created. This means in order to figure out all the fixtures this particular TestCase will need, we have to test all of its attributes for 'fixture-ness'. See __fixture_decorator_factory for more info. """ all_fixtures = {} for fixture_type in FIXTURE_TYPES: all_fixtures[fixture_type] = [] # the list of classes in our heirarchy, starting with the highest class # (object), and ending with our class test_class = type(test_case) mro = inspect.getmro(test_class) reverse_mro_index = dict((cls, i) for (i, cls) in enumerate(reversed(mro))) # discover which fixures are on this class, including mixed-in ones # We want to know everything on this class (including stuff inherited # from bases), AND where it came from. This code is based on # classify_class_attrs from the inspect module, which does just that. # (classify_class_attrs isn't used here because it does a bunch of # relatively slow checks for the type of the attribute, which we then # completely ignore.) for name in dir(test_class): # Try __dict__ first, to subvert descriptor magic when possible # (important for e.g. methods) if name in test_class.__dict__: obj = test_class.__dict__[name] else: obj = getattr(test_class, name) # Figure out where it came from defining_class = getattr(obj, "__objclass__", None) if defining_class is None: for base in mro: if name in base.__dict__: defining_class = base break # Re-fetch the object, to get it from its owning __dict__ instead # of a getattr, if possible. Don't know why, but inspect does it! if defining_class is not None and name in defining_class.__dict__: obj = defining_class.__dict__[name] # End inspection; now this is testify logic. if inspection.is_fixture_method(obj): fixture_method = obj elif name in DEPRECATED_FIXTURE_TYPE_MAP and inspect.isroutine(obj): # if this is an old setUp/tearDown/etc, tag it as a fixture fixture_type = DEPRECATED_FIXTURE_TYPE_MAP[name] fixture_decorator = globals()[fixture_type] fixture_method = fixture_decorator(obj) else: continue depth = reverse_mro_index[defining_class] fixture_method._defining_class_depth = depth # We grabbed this from the class and need to bind it to the test # case # http://stackoverflow.com/q/4364565 instance_method = fixture_method.__get__(test_case, test_class) all_fixtures[instance_method._fixture_type].append(instance_method) class_level = ["class_setup", "class_teardown", "class_setup_teardown"] inst_level = ["setup", "teardown", "setup_teardown"] return cls( class_fixtures=list(itertools.chain(*[all_fixtures[typ] for typ in class_level])), instance_fixtures=list(itertools.chain(*[all_fixtures[typ] for typ in inst_level])), )
def __init_fixture_methods(self): """Initialize and populate the lists of fixture methods for this TestCase. Fixture methods are identified by the fixture_decorator_factory when the methods are created. This means in order to figure out all the fixtures this particular TestCase will need, we have to test all of its attributes for 'fixture-ness'. See __fixture_decorator_factory for more info. """ # init our self.(class_setup|setup|teardown|class_teardown)_fixtures lists for fixture_type in FIXTURE_TYPES: setattr(self, "%s_fixtures" % fixture_type, []) # the list of classes in our heirarchy, starting with the highest class # (object), and ending with our class reverse_mro_list = [x for x in reversed(type(self).mro())] # discover which fixures are on this class, including mixed-in ones self._fixture_methods = defaultdict(list) # we want to know everything on this class (including stuff inherited # from bases), but we don't want to trigger any lazily loaded # attributes, so dir() isn't an option; this traverses __bases__/__dict__ # correctly for us. for classified_attr in inspect.classify_class_attrs(type(self)): # have to index here for Python 2.5 compatibility attr_name = classified_attr[0] unbound_method = classified_attr[3] defining_class = classified_attr[2] # skip everything that's not a function/method if not inspect.isroutine(unbound_method): continue # if this is an old setUp/tearDown/etc, tag it as a fixture if attr_name in DEPRECATED_FIXTURE_TYPE_MAP: fixture_type = DEPRECATED_FIXTURE_TYPE_MAP[attr_name] fixture_decorator = globals()[fixture_type] unbound_method = fixture_decorator(unbound_method) # collect all of our fixtures in appropriate buckets if inspection.is_fixture_method(unbound_method): # where in our MRO this fixture was defined defining_class_depth = reverse_mro_list.index(defining_class) inspection.callable_setattr( unbound_method, '_defining_class_depth', defining_class_depth, ) # we grabbed this from the class and need to bind it to us instance_method = instancemethod(unbound_method, self, self.__class__) self._fixture_methods[instance_method._fixture_type].append(instance_method) # arrange our fixture buckets appropriately for fixture_type, fixture_methods in self._fixture_methods.iteritems(): # sort our fixtures in order of oldest (smaller id) to newest, but # also grouped by class to correctly place deprecated fixtures fixture_methods.sort(key=lambda x: (x._defining_class_depth, x._fixture_id)) # for setup methods, we want methods defined further back in the # class hierarchy to execute first. for teardown methods though, # we want the opposite while still maintaining the class-level # definition order, so we reverse only on class depth. if fixture_type in REVERSED_FIXTURE_TYPES: fixture_methods.sort(key=lambda x: x._defining_class_depth, reverse=True) fixture_list_name = "%s_fixtures" % fixture_type setattr(self, fixture_list_name, fixture_methods)
def test_instance(self): assert not inspection.is_fixture_method(DummyTestCase.instance)
def test_static_method(self): assert not inspection.is_fixture_method(DummyTestCase.static)
def test_lambda(self): assert not inspection.is_fixture_method(lambda: None)
def test_turtle(self): """Turtles are callable but not fixtures!""" assert not inspection.is_fixture_method(DummyTestCase.turtle_method)
def test_fixture(self): assert inspection.is_fixture_method(DummyTestCase.fixture)
def discover_from(cls, test_case): """Initialize and populate the lists of fixture methods for this TestCase. Fixture methods are identified by the fixture_decorator_factory when the methods are created. This means in order to figure out all the fixtures this particular TestCase will need, we have to test all of its attributes for 'fixture-ness'. See __fixture_decorator_factory for more info. """ all_fixtures = {} for fixture_type in FIXTURE_TYPES: all_fixtures[fixture_type] = [] # the list of classes in our heirarchy, starting with the highest class # (object), and ending with our class reverse_mro_list = [x for x in reversed(type(test_case).mro())] # discover which fixures are on this class, including mixed-in ones # we want to know everything on this class (including stuff inherited # from bases), but we don't want to trigger any lazily loaded # attributes, so dir() isn't an option; this traverses __bases__/__dict__ # correctly for us. for classified_attr in inspect.classify_class_attrs(type(test_case)): # have to index here for Python 2.5 compatibility attr_name = classified_attr[0] unbound_method = classified_attr[3] defining_class = classified_attr[2] # skip everything that's not a function/method if not inspect.isroutine(unbound_method): continue # if this is an old setUp/tearDown/etc, tag it as a fixture if attr_name in DEPRECATED_FIXTURE_TYPE_MAP: fixture_type = DEPRECATED_FIXTURE_TYPE_MAP[attr_name] fixture_decorator = globals()[fixture_type] unbound_method = fixture_decorator(unbound_method) # collect all of our fixtures in appropriate buckets if inspection.is_fixture_method(unbound_method): # where in our MRO this fixture was defined defining_class_depth = reverse_mro_list.index(defining_class) inspection.callable_setattr( unbound_method, '_defining_class_depth', defining_class_depth, ) # we grabbed this from the class and need to bind it to the # test case instance_method = instancemethod(unbound_method, test_case, test_case.__class__) all_fixtures[instance_method._fixture_type].append(instance_method) class_level = ['class_setup', 'class_teardown', 'class_setup_teardown'] inst_level = ['setup', 'teardown', 'setup_teardown'] return cls( class_fixtures=sum([all_fixtures[typ] for typ in class_level], []), instance_fixtures=sum([all_fixtures[typ] for typ in inst_level], []), )
def discover_from(cls, test_case): """Initialize and populate the lists of fixture methods for this TestCase. Fixture methods are identified by the fixture_decorator_factory when the methods are created. This means in order to figure out all the fixtures this particular TestCase will need, we have to test all of its attributes for 'fixture-ness'. See __fixture_decorator_factory for more info. """ all_fixtures = {} for fixture_type in FIXTURE_TYPES: all_fixtures[fixture_type] = [] # the list of classes in our heirarchy, starting with the highest class # (object), and ending with our class test_class = type(test_case) mro = inspect.getmro(test_class) reverse_mro_index = dict( (cls, i) for (i, cls) in enumerate(reversed(mro))) # discover which fixures are on this class, including mixed-in ones # We want to know everything on this class (including stuff inherited # from bases), AND where it came from. This code is based on # classify_class_attrs from the inspect module, which does just that. # (classify_class_attrs isn't used here because it does a bunch of # relatively slow checks for the type of the attribute, which we then # completely ignore.) for name in dir(test_class): # Try __dict__ first, to subvert descriptor magic when possible # (important for e.g. methods) if name in test_class.__dict__: obj = test_class.__dict__[name] else: obj = getattr(test_class, name) # Figure out where it came from defining_class = getattr(obj, '__objclass__', None) if defining_class is None: for base in mro: if name in base.__dict__: defining_class = base break # Re-fetch the object, to get it from its owning __dict__ instead # of a getattr, if possible. Don't know why, but inspect does it! if defining_class is not None and name in defining_class.__dict__: obj = defining_class.__dict__[name] # End inspection; now this is testify logic. if inspection.is_fixture_method(obj): fixture_method = obj elif (name in DEPRECATED_FIXTURE_TYPE_MAP and inspect.isroutine(obj)): # if this is an old setUp/tearDown/etc, tag it as a fixture fixture_type = DEPRECATED_FIXTURE_TYPE_MAP[name] fixture_decorator = globals()[fixture_type] fixture_method = fixture_decorator(obj) else: continue depth = reverse_mro_index[defining_class] fixture_method._defining_class_depth = depth # We grabbed this from the class and need to bind it to the test # case # http://stackoverflow.com/q/4364565 instance_method = fixture_method.__get__(test_case, test_class) all_fixtures[instance_method._fixture_type].append(instance_method) class_level = ['class_setup', 'class_teardown', 'class_setup_teardown'] inst_level = ['setup', 'teardown', 'setup_teardown'] return cls( class_fixtures=list( itertools.chain(*[all_fixtures[typ] for typ in class_level])), instance_fixtures=list( itertools.chain(*[all_fixtures[typ] for typ in inst_level])), )
def __init_fixture_methods(self): """Initialize and populate the lists of fixture methods for this TestCase. Fixture methods are identified by the fixture_decorator_factory when the methods are created. This means in order to figure out all the fixtures this particular TestCase will need, we have to test all of its attributes for 'fixture-ness'. See __fixture_decorator_factory for more info. """ # init our self.(class_setup|setup|teardown|class_teardown)_fixtures lists for fixture_type in FIXTURE_TYPES: setattr(self, "%s_fixtures" % fixture_type, []) # the list of classes in our heirarchy, starting with the highest class # (object), and ending with our class reverse_mro_list = [x for x in reversed(type(self).mro())] # discover which fixures are on this class, including mixed-in ones self._fixture_methods = defaultdict(list) # we want to know everything on this class (including stuff inherited # from bases), but we don't want to trigger any lazily loaded # attributes, so dir() isn't an option; this traverses __bases__/__dict__ # correctly for us. for classified_attr in inspect.classify_class_attrs(type(self)): # have to index here for Python 2.5 compatibility attr_name = classified_attr[0] unbound_method = classified_attr[3] defining_class = classified_attr[2] # skip everything that's not a function/method if not inspect.isroutine(unbound_method): continue # if this is an old setUp/tearDown/etc, tag it as a fixture if attr_name in DEPRECATED_FIXTURE_TYPE_MAP: fixture_type = DEPRECATED_FIXTURE_TYPE_MAP[attr_name] fixture_decorator = globals()[fixture_type] unbound_method = fixture_decorator(unbound_method) # collect all of our fixtures in appropriate buckets if inspection.is_fixture_method(unbound_method): # where in our MRO this fixture was defined defining_class_depth = reverse_mro_list.index(defining_class) inspection.callable_setattr( unbound_method, '_defining_class_depth', defining_class_depth, ) # we grabbed this from the class and need to bind it to us instance_method = instancemethod(unbound_method, self, self.__class__) self._fixture_methods[instance_method._fixture_type].append( instance_method) # arrange our fixture buckets appropriately for fixture_type, fixture_methods in self._fixture_methods.iteritems(): # sort our fixtures in order of oldest (smaller id) to newest, but # also grouped by class to correctly place deprecated fixtures fixture_methods.sort( key=lambda x: (x._defining_class_depth, x._fixture_id)) # for setup methods, we want methods defined further back in the # class hierarchy to execute first. for teardown methods though, # we want the opposite while still maintaining the class-level # definition order, so we reverse only on class depth. if fixture_type in REVERSED_FIXTURE_TYPES: fixture_methods.sort(key=lambda x: x._defining_class_depth, reverse=True) fixture_list_name = "%s_fixtures" % fixture_type setattr(self, fixture_list_name, fixture_methods)