Merge branch 'doctest_namespace_inject' into features

This commit is contained in:
Bruno Oliveira 2016-03-02 23:38:51 -03:00
commit 4a76b2e9b6
5 changed files with 99 additions and 1 deletions

View File

@ -59,6 +59,7 @@ Marc Schlaich
Mark Abramowitz Mark Abramowitz
Markus Unterwaditzer Markus Unterwaditzer
Martijn Faassen Martijn Faassen
Matt Williams
Michael Aquilina Michael Aquilina
Michael Birtwell Michael Birtwell
Michael Droettboom Michael Droettboom

View File

@ -3,7 +3,9 @@
**New Features** **New Features**
* * New ``doctest_namespace`` fixture for injecting names into the
namespace in which your doctests run.
Thanks `@milliams`_ for the complete PR (`#1428`_).
* *
@ -28,6 +30,11 @@
* *
.. _@milliams: https://github.com/milliams
.. _#1428: https://github.com/pytest-dev/pytest/pull/1428
2.9.0 2.9.0
===== =====

View File

@ -71,6 +71,8 @@ class DoctestItem(pytest.Item):
if self.dtest is not None: if self.dtest is not None:
self.fixture_request = _setup_fixtures(self) self.fixture_request = _setup_fixtures(self)
globs = dict(getfixture=self.fixture_request.getfuncargvalue) globs = dict(getfixture=self.fixture_request.getfuncargvalue)
for name, value in self.fixture_request.getfuncargvalue('doctest_namespace').items():
globs[name] = value
self.dtest.globs.update(globs) self.dtest.globs.update(globs)
def runtest(self): def runtest(self):
@ -159,6 +161,9 @@ class DoctestTextfile(DoctestItem, pytest.Module):
if '__name__' not in globs: if '__name__' not in globs:
globs['__name__'] = '__main__' globs['__name__'] = '__main__'
for name, value in fixture_request.getfuncargvalue('doctest_namespace').items():
globs[name] = value
optionflags = get_optionflags(self) optionflags = get_optionflags(self)
runner = doctest.DebugRunner(verbose=0, optionflags=optionflags, runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
checker=_get_checker()) checker=_get_checker())
@ -288,3 +293,11 @@ def _get_allow_bytes_flag():
""" """
import doctest import doctest
return doctest.register_optionflag('ALLOW_BYTES') return doctest.register_optionflag('ALLOW_BYTES')
@pytest.fixture(scope='session')
def doctest_namespace():
"""
Inject names into the doctest namespace.
"""
return dict()

View File

@ -102,4 +102,31 @@ itself::
>>> get_unicode_greeting() # doctest: +ALLOW_UNICODE >>> get_unicode_greeting() # doctest: +ALLOW_UNICODE
'Hello' 'Hello'
The 'doctest_namespace' fixture
-------------------------------
.. versionadded:: 2.10
The ``doctest_namespace`` fixture can be used to inject items into the
namespace in which your doctests run. It is intended to be used within
your own fixtures to provide the tests that use them with context.
``doctest_namespace`` is a standard ``dict`` object into which you
place the objects you want to appear in the doctest namespace::
# content of conftest.py
import numpy
@pytest.fixture(autouse=True)
def add_np(doctest_namespace):
doctest_namespace['np'] = numpy
which can then be used in your doctests directly::
# content of numpy.py
def arange():
"""
>>> a = np.arange(10)
>>> len(a)
10
"""
pass

View File

@ -713,3 +713,53 @@ class TestDoctestAutoUseFixtures:
result = testdir.runpytest('--doctest-modules') result = testdir.runpytest('--doctest-modules')
assert 'FAILURES' not in str(result.stdout.str()) assert 'FAILURES' not in str(result.stdout.str())
result.stdout.fnmatch_lines(['*=== 1 passed in *']) result.stdout.fnmatch_lines(['*=== 1 passed in *'])
class TestDoctestNamespaceFixture:
SCOPES = ['module', 'session', 'class', 'function']
@pytest.mark.parametrize('scope', SCOPES)
def test_namespace_doctestfile(self, testdir, scope):
"""
Check that inserting something into the namespace works in a
simple text file doctest
"""
testdir.makeconftest("""
import pytest
import contextlib
@pytest.fixture(autouse=True, scope="{scope}")
def add_contextlib(doctest_namespace):
doctest_namespace['cl'] = contextlib
""".format(scope=scope))
p = testdir.maketxtfile("""
>>> print(cl.__name__)
contextlib
""")
reprec = testdir.inline_run(p)
reprec.assertoutcome(passed=1)
@pytest.mark.parametrize('scope', SCOPES)
def test_namespace_pyfile(self, testdir, scope):
"""
Check that inserting something into the namespace works in a
simple Python file docstring doctest
"""
testdir.makeconftest("""
import pytest
import contextlib
@pytest.fixture(autouse=True, scope="{scope}")
def add_contextlib(doctest_namespace):
doctest_namespace['cl'] = contextlib
""".format(scope=scope))
p = testdir.makepyfile("""
def foo():
'''
>>> print(cl.__name__)
contextlib
'''
""")
reprec = testdir.inline_run(p, "--doctest-modules")
reprec.assertoutcome(passed=1)