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,
        ),
    )
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)