[Pytest-commit] commit/pytest: RonnyPfannschmidt: use hook wrapping to separate logging for test, call, teardown
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Thu Feb 19 22:58:21 CET 2015
1 new commit in pytest:
https://bitbucket.org/hpk42/pytest/commits/c321b799400d/
Changeset: c321b799400d
Branch: copy-in-cache
User: RonnyPfannschmidt
Date: 2015-02-19 21:58:11+00:00
Summary: use hook wrapping to separate logging for test, call, teardown
Affected #: 3 files
diff -r 7c39287ab3d0b487a74f38930df27de1f17ade08 -r c321b799400db373e4f10b50cb6cb43961109c23 _pytest/cache.py
--- a/_pytest/cache.py
+++ b/_pytest/cache.py
@@ -117,8 +117,12 @@
def pytest_addoption(parser):
- outside_looponfail = 'xdist' in sys.modules and \
- 'looponfail.py' in pkg_resources.resource_listdir('xdist', '.')
+ try:
+ ls = pkg_resources.resource_listdir('xdist', '.')
+ except:
+ outside_looponfail = False
+ else:
+ outside_looponfail = 'looponfail.py' in ls
group = parser.getgroup("general")
group.addoption(
diff -r 7c39287ab3d0b487a74f38930df27de1f17ade08 -r c321b799400db373e4f10b50cb6cb43961109c23 _pytest/capture_log.py
--- a/_pytest/capture_log.py
+++ b/_pytest/capture_log.py
@@ -110,6 +110,7 @@
import py
import logging
+import pytest
LOG_FORMAT = '%(filename)-25s %(lineno)4d %(levelname)-8s %(message)s'
@@ -137,7 +138,7 @@
"""Activate log capturing if appropriate."""
if config.getvalue('capturelog'):
- config.pluginmanager.register(CaptureLogPlugin(config), '_capturelog')
+ config.pluginmanager.register(CaptureLogPlugin(config), 'capturelog')
class CaptureLogPlugin(object):
@@ -153,6 +154,7 @@
self.formatter = logging.Formatter(config.getvalue('log_format'),
config.getvalue('log_date_format'))
+ @pytest.mark.hookwrapper
def pytest_runtest_setup(self, item):
"""Start capturing log messages for this test.
@@ -173,6 +175,11 @@
root_logger = logging.getLogger()
root_logger.addHandler(item.capturelog_handler)
root_logger.setLevel(logging.NOTSET)
+ yield
+ item.capturelog_handler.close()
+ root_logger.removeHandler(item.capturelog_handler)
+
+ pytest_runtest_teardown = pytest_runtest_call = pytest_runtest_setup
def pytest_runtest_makereport(self, __multicall__, item, call):
"""Add captured log messages for this report."""
@@ -182,23 +189,11 @@
# This fn called after setup, call and teardown. Only
# interested in just after test call has finished.
if call.when == 'call':
-
- # Detach the handler from the root logger to ensure no
- # further access to the handler.
- root_logger = logging.getLogger()
- root_logger.removeHandler(item.capturelog_handler)
-
- # For failed tests that have captured log messages add a
- # captured log section to the report.
- if not report.passed:
- longrepr = getattr(report, 'longrepr', None)
- if hasattr(longrepr, 'addsection'):
- log = item.capturelog_handler.stream.getvalue().strip()
- if log:
- longrepr.addsection('Captured log', log)
-
- # Release the handler resources.
- item.capturelog_handler.close()
+ longrepr = getattr(report, 'longrepr', None)
+ if hasattr(longrepr, 'addsection'):
+ log = item.capturelog_handler.value.strip()
+ if log:
+ report.sections.append(('Captured log ' + call.when, log))
del item.capturelog_handler
return report
@@ -212,11 +207,19 @@
logging.StreamHandler.__init__(self)
self.stream = py.io.TextIO()
- self.records = []
+ self.records = []
+ self._value = None
+
+ @property
+ def value(self):
+ if self._value is None:
+ return self.stream.getvalue()
+ else:
+ return self._value
def close(self):
"""Close this log handler and its underlying stream."""
-
+ self._value = self.stream.getvalue()
logging.StreamHandler.close(self)
self.stream.close()
@@ -230,15 +233,19 @@
class CaptureLogFuncArg(object):
"""Provides access and control of log capturing."""
- def __init__(self, handler):
+ def __init__(self, node):
"""Creates a new funcarg."""
- self.handler = handler
+ self.node = node
+
+ @property
+ def handler(self):
+ return self.node.capturelog_handler
def text(self):
"""Returns the log text."""
- return self.handler.stream.getvalue()
+ return self.handler.value
def records(self):
"""Returns the list of log records."""
@@ -288,14 +295,8 @@
self.obj.setLevel(self.orig_level)
-
-def pytest_funcarg__caplog(request):
+ at pytest.fixture
+def caplog(request):
"""Returns a funcarg to access and control log capturing."""
- return CaptureLogFuncArg(request._pyfuncitem.capturelog_handler)
-
-
-def pytest_funcarg__capturelog(request):
- """Returns a funcarg to access and control log capturing."""
-
- return CaptureLogFuncArg(request._pyfuncitem.capturelog_handler)
+ return CaptureLogFuncArg(request.node)
diff -r 7c39287ab3d0b487a74f38930df27de1f17ade08 -r c321b799400db373e4f10b50cb6cb43961109c23 _pytest/onchange.py
--- a/_pytest/onchange.py
+++ b/_pytest/onchange.py
@@ -1,5 +1,5 @@
import py
-
+import subprocess
SCRIPT = """
import pytest
@@ -7,6 +7,14 @@
"""
+def run_once(args, tw=None):
+ tw = py.io.TerminalWriter()
+ subprocess.call(args)
+ tw.line()
+ tw.sep('#', 'waiting for changes')
+ tw.line()
+
+
def looponchange(config):
newargs = config._origargs[:]
if '--looponchange' in newargs:
@@ -14,10 +22,8 @@
else:
newargs.remove('-f')
stats = StatRecorder(config.getini('looponchangeroots'))
- command = py.std.functools.partial(
- py.std.subprocess.call, [
- py.std.sys.executable,
- '-c', SCRIPT % newargs])
+ command = py.std.functools.partial(run_once, [
+ py.std.sys.executable, '-c', SCRIPT % newargs])
command()
loop_forever(stats, command)
return 2
Repository URL: https://bitbucket.org/hpk42/pytest/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the pytest-commit
mailing list