So my method doesn't work when Packages are involved. package.collect()
returns the necessary nodes only once (it thinks the second execution
encountered duplicates, so it returns empty tuple). So my gen_nodeids
breaks normal collection. The bug or feature is demonstrated below. Is
there a better way, please? If I invoke runpytest with "--keepduplicates"
the test passes. Maybe I could use package._collectfile(...,
handle_dupes=False) but that is non-API territory so I didn't investigate
further yet.

Tibor

This fails with
/Users/tibor/tmonworkspace/testmon.io/test/test_collect.py:33: in
pytest_collect_file
    assert nodeids == nodeids2
E   AssertionError: assert ['test_a.py::Test1::test_1',
'test_a.py::Test1::test_2'] == []

import pytest

pytest_plugins = "pytester"


def test_pytest_assumption(testdir):
    testdir.makepyfile(__init__="")

    testdir.makepyfile(test_a="""
        class Test1():
            def test_1(self):
                pass
            def test_2(self):
                pass
    """)

    class Plugin:

        @pytest.hookimpl(hookwrapper=True)
        def pytest_collect_file(self, path, parent):
            def gen_nodeids(nodes):
                for node in nodes:
                    if isinstance(node, pytest.Item):
                        yield node.nodeid
                    else:
                        yield from gen_nodeids(node.collect())


            collect_file_result = yield
            nodeids =  list(gen_nodeids(collect_file_result.get_result()))
            nodeids2 = list(gen_nodeids(collect_file_result.get_result()))
            assert len(nodeids) == 2
            assert nodeids == nodeids2

    result = testdir.runpytest_inprocess("-v",
"test_a.py::Test1::test_1", plugins=[Plugin()])
    result.assert_outcomes(1, 0, 0)



On Sat, Nov 2, 2019 at 9:52 PM Tibor Arpas <tibor.ar...@infinit.sk> wrote:

> Hi,
>
> For pytest-testmon plugin I need to extract all node ids which exist in a
> python file (after parametrization). Initially, I thought
> pytest_collection_modifyitems used as a hookwrapper would have all the
> node_ids in all the files (which would be ideal for me). It turns out if
> you call pytest test_a.py::test_1 , pytest_collection_modifyitems only gets
> test_a.py::test_1 (but no other nodes which might be in test_a.py).
> pytest_pycollect_makemodule sounds like the pretty low-level hook which
> should get all I need. However, it gets a hierarchy, which I have to
> manually flatten. My gen_nodeids bellow looks like a code that definitely
> lives somewhere in pytest. What is the optimal and most forward-compatible
> way to get the list, please? Below is what I came up with so far (and it
> seems to work).
>
> I would be glad to get any comments or pointers.
>
> Best,
> Tibor
> twitter: tibor_a
>
> import pytest
>
> pytest_plugins = "pytester"
>
>
> def test_pytest_assumption(testdir):
>     testdir.makepyfile(test_a="""
>         class Test1():
>             def test_1(self):
>                 pass
>     """)
>
>     class Plugin:
>         @pytest.hookimpl(hookwrapper=True)
>         def pytest_pycollect_makemodule(self, path, parent):
>             def gen_nodeids(nodes):
>                 for node in nodes:
>                     if isinstance(node, pytest.Function):
>                         yield node.nodeid
>                     else:
>                         yield from gen_nodeids(node.collect())
>
>             make_module_result = yield
>             nodeids =  
> list(gen_nodeids(make_module_result.get_result().collect()))
>             assert nodeids == ['test_a.py::Test1::test_1']
>
>     result = testdir.runpytest_inprocess("--testmon-dev", plugins=[Plugin()])
>     result.assert_outcomes(1, 0, 0)
>
>
_______________________________________________
pytest-dev mailing list
pytest-dev@python.org
https://mail.python.org/mailman/listinfo/pytest-dev

Reply via email to