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 <[email protected]> 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
[email protected]
https://mail.python.org/mailman/listinfo/pytest-dev