From 07a560ff246a28e4ab8567404d7f55afb40a3c36 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Tue, 21 Aug 2018 20:55:45 -0300 Subject: [PATCH] Fix collection error when tests is specified with --doctest-modules The problem was that _matchnodes would receive two items: [DoctestModule, Module]. It would then collect the first one, *cache it*, and fail to match against the name in the command line. Next, it would reuse the cached item (DoctestModule) instead of collecting the Module which would eventually find the "test" name on it. Added the type of the node to the cache key to avoid this problem, although I'm not a big fan of caches that have different key types. Fix #3843 --- changelog/3843.bugfix.rst | 1 + src/_pytest/main.py | 7 ++++--- testing/acceptance_test.py | 10 ++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 changelog/3843.bugfix.rst diff --git a/changelog/3843.bugfix.rst b/changelog/3843.bugfix.rst new file mode 100644 index 000000000..3186c3fc5 --- /dev/null +++ b/changelog/3843.bugfix.rst @@ -0,0 +1 @@ +Fix collection error when specifying test functions directly in the command line using ``test.py::test`` syntax together with ``--doctest-module``. diff --git a/src/_pytest/main.py b/src/_pytest/main.py index eae0bb255..947c6aa4b 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -625,11 +625,12 @@ class Session(nodes.FSCollector): resultnodes.append(node) continue assert isinstance(node, nodes.Collector) - if node.nodeid in self._node_cache: - rep = self._node_cache[node.nodeid] + key = (type(node), node.nodeid) + if key in self._node_cache: + rep = self._node_cache[key] else: rep = collect_one_node(node) - self._node_cache[node.nodeid] = rep + self._node_cache[key] = rep if rep.passed: has_matched = False for x in rep.result: diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index bc4e3bed8..5d6baf121 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -660,6 +660,16 @@ class TestInvocationVariants(object): ["*test_world.py::test_other*PASSED*", "*1 passed*"] ) + def test_invoke_test_and_doctestmodules(self, testdir): + p = testdir.makepyfile( + """ + def test(): + pass + """ + ) + result = testdir.runpytest(str(p) + "::test", "--doctest-modules") + result.stdout.fnmatch_lines(["*1 passed*"]) + @pytest.mark.skipif(not hasattr(os, "symlink"), reason="requires symlinks") def test_cmdline_python_package_symlink(self, testdir, monkeypatch): """