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_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] names = [i.name for i in items] 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 setup_test_classes(): for test_class in test_classes: for sub_cls in plugin_base.generate_sub_tests( test_class.cls, test_class.module): if sub_cls is not test_class.cls: per_cls_dict = rebuilt_items[test_class.cls] # support pytest 5.4.0 and above pytest.Class.from_parent ctor = getattr(pytest.Class, "from_parent", pytest.Class) module = test_class.getparent(pytest.Module) for fn in collect( ctor(name=sub_cls.__name__, parent=module)): per_cls_dict[fn.name].append(fn)
def setup_test_classes(): 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] # support pytest 5.4.0 and above pytest.Class.from_parent ctor = getattr(pytest.Class, "from_parent", pytest.Class) for inst in ctor( name=sub_cls.__name__, parent=test_class.parent.parent).collect(): for t in inst.collect(): per_cls_dict[t.name].append(t)
def setup_test_classes(): for test_class in test_classes: # transfer legacy __backend__ and __sparse_backend__ symbols # to be markers add_markers = set() if getattr(test_class.cls, "__backend__", False) or getattr( test_class.cls, "__only_on__", False ): add_markers = {"backend"} elif getattr(test_class.cls, "__sparse_backend__", False): add_markers = {"sparse_backend"} else: add_markers = frozenset() existing_markers = { mark.name for mark in test_class.iter_markers() } add_markers = add_markers - existing_markers all_markers = existing_markers.union(add_markers) for marker in add_markers: test_class.add_marker(marker) for sub_cls in plugin_base.generate_sub_tests( test_class.cls, test_class.module, all_markers ): if sub_cls is not test_class.cls: per_cls_dict = rebuilt_items[test_class.cls] module = test_class.getparent(pytest.Module) new_cls = pytest.Class.from_parent( name=sub_cls.__name__, parent=module ) for marker in add_markers: new_cls.add_marker(marker) for fn in collect(new_cls): per_cls_dict[fn.name].append(fn)