def pytest_pycollect_makeitem(collector, name, obj): if inspect.isclass(obj) and plugin_base.want_class(name, obj): # in pytest 5.4.0 # return [ # pytest.Class.from_parent(collector, # name=parametrize_cls.__name__) # for parametrize_cls in _parametrize_cls(collector.module, obj) # ] return [ pytest.Class(parametrize_cls.__name__, parent=collector) for parametrize_cls in _parametrize_cls(collector.module, obj) ] elif ( inspect.isfunction(obj) and isinstance(collector, pytest.Instance) and plugin_base.want_method(collector.cls, obj) ): # None means, fall back to default logic, which includes # method-level parametrize return None else: # empty list means skip this item return []
def pytest_pycollect_makeitem(collector, name, obj): if inspect.isclass(obj) and plugin_base.want_class(obj): return pytest.Class(name, parent=collector) elif (inspect.isfunction(obj) and isinstance(collector, pytest.Instance) and plugin_base.want_method(collector.cls, obj)): return pytest.Function(name, parent=collector) else: return []
def pytest_collection_modifyitems(session, config, items): # look for all those classes that specify __backend__ and # expand them out into per-database test cases. # this is much easier to do within pytest_pycollect_makeitem, however # pytest is iterating through cls.__dict__ as makeitem is # called which causes a "dictionary changed size" error on py3k. # I'd submit a pullreq for them to turn it into a list first, but # it's to suit the rather odd use case here which is that we are adding # new classes to a module on the fly. rebuilt_items = collections.defaultdict( lambda: collections.defaultdict(list) ) items[:] = [ item for item in items if isinstance(item.parent, pytest.Instance) and not item.parent.parent.name.startswith("_") ] test_classes = set(item.parent for item in items) for test_class in test_classes: for sub_cls in plugin_base.generate_sub_tests( test_class.cls, test_class.parent.module ): if sub_cls is not test_class.cls: per_cls_dict = rebuilt_items[test_class.cls] # in pytest 5.4.0 # for inst in pytest.Class.from_parent( # test_class.parent.parent, name=sub_cls.__name__ # ).collect(): for inst in pytest.Class( sub_cls.__name__, parent=test_class.parent.parent ).collect(): for t in inst.collect(): per_cls_dict[t.name].append(t) newitems = [] for item in items: if item.parent.cls in rebuilt_items: newitems.extend(rebuilt_items[item.parent.cls][item.name]) else: newitems.append(item) # seems like the functions attached to a test class aren't sorted already? # is that true and why's that? (when using unittest, they're sorted) items[:] = sorted( newitems, key=lambda item: ( item.parent.parent.parent.name, item.parent.parent.name, item.name, ), )
def pytest_pycollect_makeitem(collector, name, obj): if inspect.isclass(obj) and plugin_base.want_class(obj): return pytest.Class(name, parent=collector) elif inspect.isfunction(obj) and \ name.startswith("test_") and \ isinstance(collector, pytest.Instance): return pytest.Function(name, parent=collector) else: return []
def pytest_pycollect_makeitem(collector, name, obj): if inspect.isclass(obj): if issubclass(obj, ImageComparisonTest): # Workaround `image_compare` decorator as it returns class # instead of function and this confuses pytest because it crawls # original names and sees 'test_*', but not 'Test*' in that case return pytest.Class(name, parent=collector) if is_nose_class(obj) and not issubclass(obj, unittest.TestCase): # Workaround unittest-like setup/teardown names in pure classes setup = getattr(obj, 'setUp', None) if setup is not None: obj.setup_method = lambda self, _: obj.setUp(self) tearDown = getattr(obj, 'tearDown', None) if tearDown is not None: obj.teardown_method = lambda self, _: obj.tearDown(self) setUpClass = getattr(obj, 'setUpClass', None) if setUpClass is not None: obj.setup_class = obj.setUpClass tearDownClass = getattr(obj, 'tearDownClass', None) if tearDownClass is not None: obj.teardown_class = obj.tearDownClass return pytest.Class(name, parent=collector)
def pytest_pycollect_makeitem(collector, name, obj): if inspect.isclass(obj): if is_nose_class(obj) and not issubclass(obj, unittest.TestCase): # Workaround unittest-like setup/teardown names in pure classes setup = getattr(obj, 'setUp', None) if setup is not None: obj.setup_method = lambda self, _: obj.setUp(self) tearDown = getattr(obj, 'tearDown', None) if tearDown is not None: obj.teardown_method = lambda self, _: obj.tearDown(self) setUpClass = getattr(obj, 'setUpClass', None) if setUpClass is not None: obj.setup_class = obj.setUpClass tearDownClass = getattr(obj, 'tearDownClass', None) if tearDownClass is not None: obj.teardown_class = obj.tearDownClass return pytest.Class(name, parent=collector)
def pytest_pycollect_makeitem(collector, name, obj): """ @see PyCollector._genfunctions @see _pytest.python """ if safe_isclass(obj): if collector.istestclass(obj, name) or (issubclass(obj, AbstractTestCase) and obj != AbstractTestCase): if hasattr(pytest.Class, "from_parent"): return pytest.Class.from_parent(collector, name=name) else: return pytest.Class(name, parent=collector) else: obj = getattr(obj, "__func__", obj) if (inspect.isfunction(obj) or inspect.isfunction(get_real_func(obj))) and getattr(obj, "__test__", True) and isinstance(collector, pytest.Instance) and hasattr(obj, "pytestmark"): if not is_generator(obj): return list(collector._genfunctions(name, obj)) else: return [] else: return []