introduce a new pytest_report_header(hook) hook to add additional test-run relevant information to the header of a test report.

--HG--
branch : trunk
This commit is contained in:
holger krekel 2010-01-12 21:43:25 +01:00
parent 676081b87a
commit d53572a710
6 changed files with 56 additions and 32 deletions

View File

@ -21,6 +21,9 @@ Changes between 1.X and 1.1.1
- new "pytestconfig" funcarg allows access to test config object - new "pytestconfig" funcarg allows access to test config object
- new "pytest_report_header" hook can return additional lines
to be displayed at the header of a test run.
- (experimental) allow "py.test path::name1::name2::..." for pointing - (experimental) allow "py.test path::name1::name2::..." for pointing
to a test within a test collection directly. This might eventually to a test within a test collection directly. This might eventually
evolve as a full substitute to "-k" specifications. evolve as a full substitute to "-k" specifications.

View File

@ -16,14 +16,6 @@ With 1.1.1 py.test fails at least on windows if an import
is relative and compared against an absolute conftest.py is relative and compared against an absolute conftest.py
path. Normalize. path. Normalize.
allow plugins/conftests to show extra header information
--------------------------------------------------------
tags: feature 1.2
The test-report header should optionally show information
about the under-test package and versions/locations of
involved packages.
make node._checkcollectable more robust make node._checkcollectable more robust
------------------------------------------------- -------------------------------------------------
tags: bug 1.2 tags: bug 1.2

View File

@ -109,6 +109,9 @@ def pytest_sessionfinish(session, exitstatus):
# hooks for influencing reporting (invoked from pytest_terminal) # hooks for influencing reporting (invoked from pytest_terminal)
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
def pytest_report_header(config):
""" return a string to be displayed as header info for terminal reporting."""
def pytest_report_teststatus(report): def pytest_report_teststatus(report):
""" return result-category, shortletter and verbose word for reporting.""" """ return result-category, shortletter and verbose word for reporting."""
pytest_report_teststatus.firstresult = True pytest_report_teststatus.firstresult = True

View File

@ -10,9 +10,19 @@ def pytest_addoption(parser):
group._addoption('-p', action="append", dest="plugins", default = [], group._addoption('-p', action="append", dest="plugins", default = [],
metavar="name", metavar="name",
help="early-load given plugin (multi-allowed).") help="early-load given plugin (multi-allowed).")
group.addoption('--traceconfig',
action="store_true", dest="traceconfig", default=False,
help="trace considerations of conftest.py files."),
group._addoption('--nomagic',
action="store_true", dest="nomagic", default=False,
help="don't reinterpret asserts, no traceback cutting. ")
group.addoption('--debug',
action="store_true", dest="debug", default=False,
help="generate and show internal debugging information.")
group.addoption("--help-config", action="store_true", dest="helpconfig", group.addoption("--help-config", action="store_true", dest="helpconfig",
help="show available conftest.py and ENV-variable names.") help="show available conftest.py and ENV-variable names.")
def pytest_configure(__multicall__, config): def pytest_configure(__multicall__, config):
if config.option.version: if config.option.version:
p = py.path.local(py.__file__).dirpath() p = py.path.local(py.__file__).dirpath()
@ -65,6 +75,19 @@ conftest_options = (
('rsyncdirs', 'to-be-rsynced directories for dist-testing'), ('rsyncdirs', 'to-be-rsynced directories for dist-testing'),
) )
def pytest_report_header(config):
lines = []
if config.option.debug or config.option.traceconfig:
lines.append("using py lib: %s" % (py.path.local(py.__file__).dirpath()))
if config.option.traceconfig:
lines.append("active plugins:")
plugins = []
items = config.pluginmanager._name2plugin.items()
for name, plugin in items:
lines.append(" %-20s: %s" %(name, repr(plugin)))
return lines
# ===================================================== # =====================================================
# validate plugin syntax and hooks # validate plugin syntax and hooks
# ===================================================== # =====================================================

View File

@ -24,17 +24,6 @@ def pytest_addoption(parser):
action="store_true", dest="fulltrace", default=False, action="store_true", dest="fulltrace", default=False,
help="don't cut any tracebacks (default is to cut).") help="don't cut any tracebacks (default is to cut).")
group = parser.getgroup("debugconfig")
group.addoption('--traceconfig',
action="store_true", dest="traceconfig", default=False,
help="trace considerations of conftest.py files."),
group._addoption('--nomagic',
action="store_true", dest="nomagic", default=False,
help="don't reinterpret asserts, no traceback cutting. ")
group.addoption('--debug',
action="store_true", dest="debug", default=False,
help="generate and show internal debugging information.")
def pytest_configure(config): def pytest_configure(config):
if config.option.collectonly: if config.option.collectonly:
@ -260,19 +249,10 @@ class TerminalReporter:
if self.config.option.verbose or self.config.option.debug or getattr(self.config.option, 'pastebin', None): if self.config.option.verbose or self.config.option.debug or getattr(self.config.option, 'pastebin', None):
msg += " -- " + str(sys.executable) msg += " -- " + str(sys.executable)
self.write_line(msg) self.write_line(msg)
lines = self.config.hook.pytest_report_header(config=self.config)
if self.config.option.debug or self.config.option.traceconfig: lines.reverse()
self.write_line("using py lib: %s" % (py.path.local(py.__file__).dirpath())) for line in flatten(lines):
if self.config.option.traceconfig: self.write_line(line)
self.write_line("active plugins:")
plugins = []
items = self.config.pluginmanager._name2plugin.items()
for name, plugin in items:
repr_plugin = repr(plugin)
fullwidth = getattr(self._tw, 'fullwidth', 65000)
if len(repr_plugin)+26 > fullwidth:
repr_plugin = repr_plugin[:(fullwidth-30)] + '...'
self.write_line(" %-20s: %s" %(name, repr_plugin))
for i, testarg in enumerate(self.config.args): for i, testarg in enumerate(self.config.args):
self.write_line("test object %d: %s" %(i+1, testarg)) self.write_line("test object %d: %s" %(i+1, testarg))
@ -463,3 +443,10 @@ def repr_pythonversion(v=None):
except (TypeError, ValueError): except (TypeError, ValueError):
return str(v) return str(v)
def flatten(l):
for x in l:
if isinstance(x, (list, tuple)):
for y in flatten(x):
yield y
else:
yield x

View File

@ -289,6 +289,22 @@ class TestTerminal:
]) ])
result.stdout.fnmatch_lines(['*KEYBOARD INTERRUPT*']) result.stdout.fnmatch_lines(['*KEYBOARD INTERRUPT*'])
def test_pytest_report_header(self, testdir):
testdir.makeconftest("""
def pytest_report_header(config):
return "hello: info"
""")
testdir.mkdir("a").join("conftest.py").write("""if 1:
def pytest_report_header(config):
return ["line1", "line2"]
""")
result = testdir.runpytest("a")
result.stdout.fnmatch_lines([
"*hello: info*",
"line1",
"line2",
])
class TestCollectonly: class TestCollectonly:
def test_collectonly_basic(self, testdir, linecomp): def test_collectonly_basic(self, testdir, linecomp):