From acec0b688f542ac5c80c4e703e916595cca07c64 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 4 Mar 2020 05:33:50 +0100 Subject: [PATCH] Fix usage of pytester with doctests (#6802) Use `request.node.name` instead of `request.function.__name__`: `request.function` is `None` with `DoctestItem`s. --- changelog/6802.bugfix.rst | 1 + src/_pytest/pytester.py | 12 ++++++++---- testing/test_pytester.py | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 changelog/6802.bugfix.rst diff --git a/changelog/6802.bugfix.rst b/changelog/6802.bugfix.rst new file mode 100644 index 000000000..af9ebef3a --- /dev/null +++ b/changelog/6802.bugfix.rst @@ -0,0 +1 @@ +The :fixture:`testdir fixture ` works within doctests now. diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 8e27e32a7..9df3ed779 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -543,7 +543,11 @@ class Testdir: self._mod_collections = ( WeakKeyDictionary() ) # type: WeakKeyDictionary[Module, List[Union[Item, Collector]]] - name = request.function.__name__ + if request.function: + name = request.function.__name__ # type: str + else: + name = request.node.name + self._name = name self.tmpdir = tmpdir_factory.mktemp(name, numbered=True) self.test_tmproot = tmpdir_factory.mktemp("tmp-" + name, numbered=True) self.plugins = [] # type: List[Union[str, _PluggyPlugin]] @@ -617,7 +621,7 @@ class Testdir: if lines: source = "\n".join(to_text(x) for x in lines) - basename = self.request.function.__name__ + basename = self._name items.insert(0, (basename, source)) ret = None @@ -720,7 +724,7 @@ class Testdir: example_dir = example_dir.join(*extra_element.args) if name is None: - func_name = self.request.function.__name__ + func_name = self._name maybe_dir = example_dir / func_name maybe_file = example_dir / (func_name + ".py") @@ -1059,7 +1063,7 @@ class Testdir: path = self.tmpdir.join(str(source)) assert not withinit, "not supported for paths" else: - kw = {self.request.function.__name__: Source(source).strip()} + kw = {self._name: Source(source).strip()} path = self.makepyfile(**kw) if withinit: self.makepyfile(__init__="#") diff --git a/testing/test_pytester.py b/testing/test_pytester.py index a15ce1813..959000061 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -89,6 +89,29 @@ def test_testdir_runs_with_plugin(testdir) -> None: result.assert_outcomes(passed=1) +def test_testdir_with_doctest(testdir): + """Check that testdir can be used within doctests. + + It used to use `request.function`, which is `None` with doctests.""" + testdir.makepyfile( + **{ + "sub/t-doctest.py": """ + ''' + >>> import os + >>> testdir = getfixture("testdir") + >>> str(testdir.makepyfile("content")).replace(os.sep, '/') + '.../basetemp/sub.t-doctest0/sub.py' + ''' + """, + "sub/__init__.py": "", + } + ) + result = testdir.runpytest( + "-p", "pytester", "--doctest-modules", "sub/t-doctest.py" + ) + assert result.ret == 0 + + def test_runresult_assertion_on_xfail(testdir) -> None: testdir.makepyfile( """