parent
308396ae3c
commit
72bf11cbe9
|
@ -34,6 +34,10 @@
|
||||||
* New ``pytest_make_parametrize_id`` hook.
|
* New ``pytest_make_parametrize_id`` hook.
|
||||||
Thanks `@palaviv`_ for the PR.
|
Thanks `@palaviv`_ for the PR.
|
||||||
|
|
||||||
|
* ``capsys`` and ``capfd`` now have a ``disabled()`` method, which is a context manager
|
||||||
|
that can be used to temporarily disable capture within a test.
|
||||||
|
Thanks `@nicoddemus`_ for the PR.
|
||||||
|
|
||||||
* New cli flag ``--fixtures-per-test`` that shows which fixtures are being used
|
* New cli flag ``--fixtures-per-test`` that shows which fixtures are being used
|
||||||
for each selected test item. Features doc strings of fixtures by default.
|
for each selected test item. Features doc strings of fixtures by default.
|
||||||
Can also show where fixtures are defined if combined with ``-v``.
|
Can also show where fixtures are defined if combined with ``-v``.
|
||||||
|
|
|
@ -4,6 +4,7 @@ per-test stdout/stderr capturing mechanism.
|
||||||
"""
|
"""
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from tempfile import TemporaryFile
|
from tempfile import TemporaryFile
|
||||||
|
@ -146,8 +147,8 @@ class CaptureManager:
|
||||||
def pytest_internalerror(self, excinfo):
|
def pytest_internalerror(self, excinfo):
|
||||||
self.reset_capturings()
|
self.reset_capturings()
|
||||||
|
|
||||||
def suspendcapture_item(self, item, when):
|
def suspendcapture_item(self, item, when, in_=False):
|
||||||
out, err = self.suspendcapture()
|
out, err = self.suspendcapture(in_=in_)
|
||||||
item.add_report_section(when, "stdout", out)
|
item.add_report_section(when, "stdout", out)
|
||||||
item.add_report_section(when, "stderr", err)
|
item.add_report_section(when, "stderr", err)
|
||||||
|
|
||||||
|
@ -162,7 +163,7 @@ def capsys(request):
|
||||||
"""
|
"""
|
||||||
if "capfd" in request._funcargs:
|
if "capfd" in request._funcargs:
|
||||||
raise request.raiseerror(error_capsysfderror)
|
raise request.raiseerror(error_capsysfderror)
|
||||||
request.node._capfuncarg = c = CaptureFixture(SysCapture)
|
request.node._capfuncarg = c = CaptureFixture(SysCapture, request)
|
||||||
return c
|
return c
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -175,17 +176,18 @@ def capfd(request):
|
||||||
request.raiseerror(error_capsysfderror)
|
request.raiseerror(error_capsysfderror)
|
||||||
if not hasattr(os, 'dup'):
|
if not hasattr(os, 'dup'):
|
||||||
pytest.skip("capfd funcarg needs os.dup")
|
pytest.skip("capfd funcarg needs os.dup")
|
||||||
request.node._capfuncarg = c = CaptureFixture(FDCapture)
|
request.node._capfuncarg = c = CaptureFixture(FDCapture, request)
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
class CaptureFixture:
|
class CaptureFixture:
|
||||||
def __init__(self, captureclass):
|
def __init__(self, captureclass, request):
|
||||||
self.captureclass = captureclass
|
self.captureclass = captureclass
|
||||||
|
self.request = request
|
||||||
|
|
||||||
def _start(self):
|
def _start(self):
|
||||||
self._capture = MultiCapture(out=True, err=True, in_=False,
|
self._capture = MultiCapture(out=True, err=True, in_=False,
|
||||||
Capture=self.captureclass)
|
Capture=self.captureclass)
|
||||||
self._capture.start_capturing()
|
self._capture.start_capturing()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
@ -200,6 +202,15 @@ class CaptureFixture:
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return self._outerr
|
return self._outerr
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def disabled(self):
|
||||||
|
capmanager = self.request.config.pluginmanager.getplugin('capturemanager')
|
||||||
|
capmanager.suspendcapture_item(self.request.node, "call", in_=True)
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
capmanager.resumecapture()
|
||||||
|
|
||||||
|
|
||||||
def safe_text_dupfile(f, mode, default_encoding="UTF8"):
|
def safe_text_dupfile(f, mode, default_encoding="UTF8"):
|
||||||
""" return a open text file object that's a duplicate of f on the
|
""" return a open text file object that's a duplicate of f on the
|
||||||
|
|
|
@ -115,4 +115,19 @@ same interface but allows to also capture output from
|
||||||
libraries or subprocesses that directly write to operating
|
libraries or subprocesses that directly write to operating
|
||||||
system level output streams (FD1 and FD2).
|
system level output streams (FD1 and FD2).
|
||||||
|
|
||||||
|
|
||||||
|
.. versionadded:: 2.10
|
||||||
|
|
||||||
|
To temporarily disable capture within a test, both ``capsys``
|
||||||
|
and ``capfd`` have a ``disabled()`` method that can be used
|
||||||
|
as a context manager, disabling capture inside the ``with`` block:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def test_disabling_capturing(capsys):
|
||||||
|
print('this output is captured')
|
||||||
|
with capsys.disabled():
|
||||||
|
print('output not captured, going directly to sys.stdout')
|
||||||
|
print('this output is also captured')
|
||||||
|
|
||||||
.. include:: links.inc
|
.. include:: links.inc
|
||||||
|
|
|
@ -480,6 +480,22 @@ class TestCaptureFixture:
|
||||||
result = testdir.runpytest_subprocess(p)
|
result = testdir.runpytest_subprocess(p)
|
||||||
assert 'closed' not in result.stderr.str()
|
assert 'closed' not in result.stderr.str()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('fixture', ['capsys', 'capfd'])
|
||||||
|
def test_disabled_capture_fixture(self, testdir, fixture):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
def test_disabled({fixture}):
|
||||||
|
print('captured before')
|
||||||
|
with {fixture}.disabled():
|
||||||
|
print('while capture is disabled')
|
||||||
|
print('captured after')
|
||||||
|
""".format(fixture=fixture))
|
||||||
|
result = testdir.runpytest_subprocess()
|
||||||
|
result.stdout.fnmatch_lines("""
|
||||||
|
*while capture is disabled*
|
||||||
|
""")
|
||||||
|
assert 'captured before' not in result.stdout.str()
|
||||||
|
assert 'captured after' not in result.stdout.str()
|
||||||
|
|
||||||
|
|
||||||
def test_setup_failure_does_not_kill_capturing(testdir):
|
def test_setup_failure_does_not_kill_capturing(testdir):
|
||||||
sub1 = testdir.mkpydir("sub1")
|
sub1 = testdir.mkpydir("sub1")
|
||||||
|
|
Loading…
Reference in New Issue