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