示例#1
0
    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)
示例#2
0
 def test_set_method_attr(self):
     inspection.callable_setattr(DummyTestCase.fixture, 'foo', True)
     assert DummyTestCase.fixture.foo
示例#3
0
 def test_set_function_attr(self):
     function = lambda: None
     inspection.callable_setattr(function, 'foo', True)
     assert function.foo
示例#4
0
    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], []),
        )
示例#5
0
    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_set_function_attr(self):
     def function():
         pass
     inspection.callable_setattr(function, 'foo', True)
     assert function.foo