rework session instantiation and exitstatus handling
--HG-- branch : trunk
This commit is contained in:
parent
2718fccfa0
commit
f779d3f863
|
@ -109,7 +109,7 @@ def pytest_runtest_protocol(item):
|
|||
""" implement fixture, run and report about the given test item. """
|
||||
pytest_runtest_protocol.firstresult = True
|
||||
|
||||
def pytest_runtest_logstart(nodeid, location):
|
||||
def pytest_runtest_logstart(nodeid, location, fspath):
|
||||
""" signal the start of a test run. """
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
|
@ -133,7 +133,7 @@ def pytest__teardown_final(session):
|
|||
""" called before test session finishes. """
|
||||
pytest__teardown_final.firstresult = True
|
||||
|
||||
def pytest__teardown_final_logerror(report):
|
||||
def pytest__teardown_final_logerror(report, session):
|
||||
""" called if runtest_teardown_final failed. """
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
@ -27,7 +27,8 @@ def pytest_sessionfinish(session, exitstatus):
|
|||
hook = session.config.hook
|
||||
rep = hook.pytest__teardown_final(session=session)
|
||||
if rep:
|
||||
hook.pytest__teardown_final_logerror(report=rep)
|
||||
hook.pytest__teardown_final_logerror(session=session, report=rep)
|
||||
session.exitstatus = 1
|
||||
|
||||
class NodeInfo:
|
||||
def __init__(self, nodeid, nodenames, fspath, location):
|
||||
|
@ -52,7 +53,8 @@ def pytest_runtest_protocol(item):
|
|||
nodeinfo = getitemnodeinfo(item)
|
||||
item.ihook.pytest_runtest_logstart(
|
||||
nodeid=nodeinfo.nodeid,
|
||||
location=nodeinfo.location
|
||||
location=nodeinfo.location,
|
||||
fspath=str(item.fspath),
|
||||
)
|
||||
runtestprotocol(item)
|
||||
return True
|
||||
|
@ -80,7 +82,8 @@ def pytest__teardown_final(session):
|
|||
if call.excinfo:
|
||||
ntraceback = call.excinfo.traceback .cut(excludepath=py._pydir)
|
||||
call.excinfo.traceback = ntraceback.filter()
|
||||
return TeardownErrorReport(call.excinfo)
|
||||
longrepr = call.excinfo.getrepr(funcargs=True)
|
||||
return TeardownErrorReport(longrepr)
|
||||
|
||||
def pytest_report_teststatus(report):
|
||||
if report.when in ("setup", "teardown"):
|
||||
|
@ -184,8 +187,8 @@ class TestReport(BaseReport):
|
|||
class TeardownErrorReport(BaseReport):
|
||||
outcome = "failed"
|
||||
when = "teardown"
|
||||
def __init__(self, excinfo):
|
||||
self.longrepr = excinfo.getrepr(funcargs=True)
|
||||
def __init__(self, longrepr):
|
||||
self.longrepr = longrepr
|
||||
|
||||
def pytest_make_collect_report(collector):
|
||||
result = excinfo = None
|
||||
|
|
|
@ -138,14 +138,14 @@ class TerminalReporter:
|
|||
def pytest__teardown_final_logerror(self, report):
|
||||
self.stats.setdefault("error", []).append(report)
|
||||
|
||||
def pytest_runtest_logstart(self, nodeid, location):
|
||||
def pytest_runtest_logstart(self, nodeid, location, fspath):
|
||||
# ensure that the path is printed before the
|
||||
# 1st test of a module starts running
|
||||
if self.config.option.verbose:
|
||||
line = self._locationline(*location)
|
||||
line = self._locationline(fspath, *location)
|
||||
self.write_ensure_prefix(line, "")
|
||||
else:
|
||||
self.write_fspath_result(py.path.local(location[0]), "")
|
||||
self.write_fspath_result(py.path.local(fspath), "")
|
||||
|
||||
def pytest_runtest_logreport(self, report):
|
||||
rep = report
|
||||
|
@ -158,11 +158,16 @@ class TerminalReporter:
|
|||
if isinstance(word, tuple):
|
||||
word, markup = word
|
||||
else:
|
||||
markup = {}
|
||||
if rep.passed:
|
||||
markup = {'green':True}
|
||||
elif rep.failed:
|
||||
markup = {'red':True}
|
||||
elif rep.skipped:
|
||||
markup = {'yellow':True}
|
||||
if not self.config.option.verbose:
|
||||
self.write_fspath_result(rep.fspath, letter)
|
||||
else:
|
||||
line = self._locationline(*rep.location)
|
||||
line = self._locationline(str(rep.fspath), *rep.location)
|
||||
if not hasattr(rep, 'node'):
|
||||
self.write_ensure_prefix(line, word, **markup)
|
||||
#self._tw.write(word, **markup)
|
||||
|
@ -227,13 +232,12 @@ class TerminalReporter:
|
|||
else:
|
||||
excrepr.reprcrash.toterminal(self._tw)
|
||||
|
||||
def _locationline(self, fspath, lineno, domain):
|
||||
#collect_fspath = self._getfspath(item)
|
||||
#if fspath and fspath != collect_fspath:
|
||||
# fspath = "%s <- %s" % (
|
||||
# self.curdir.bestrelpath(collect_fspath),
|
||||
# self.curdir.bestrelpath(fspath))
|
||||
if fspath:
|
||||
def _locationline(self, collect_fspath, fspath, lineno, domain):
|
||||
if fspath and fspath != collect_fspath:
|
||||
fspath = "%s <- %s" % (
|
||||
self.curdir.bestrelpath(py.path.local(collect_fspath)),
|
||||
self.curdir.bestrelpath(py.path.local(fspath)))
|
||||
elif fspath:
|
||||
fspath = self.curdir.bestrelpath(py.path.local(fspath))
|
||||
if lineno is not None:
|
||||
lineno += 1
|
||||
|
|
|
@ -44,14 +44,7 @@ class Session(object):
|
|||
self.config.pluginmanager.register(self, name="session", prepend=True)
|
||||
self._testsfailed = 0
|
||||
self.shouldstop = False
|
||||
self.collection = Collection(config)
|
||||
|
||||
def sessionfinishes(self, exitstatus):
|
||||
# XXX move to main loop / refactor mainloop
|
||||
self.config.hook.pytest_sessionfinish(
|
||||
session=self,
|
||||
exitstatus=exitstatus,
|
||||
)
|
||||
self.collection = Collection(config) # XXX move elswehre
|
||||
|
||||
def pytest_runtest_logreport(self, report):
|
||||
if report.failed:
|
||||
|
@ -66,32 +59,33 @@ class Session(object):
|
|||
def main(self):
|
||||
""" main loop for running tests. """
|
||||
self.shouldstop = False
|
||||
exitstatus = EXIT_OK
|
||||
self.exitstatus = EXIT_OK
|
||||
config = self.config
|
||||
try:
|
||||
config.pluginmanager.do_configure(config)
|
||||
config.hook.pytest_sessionstart(session=self)
|
||||
config.hook.pytest_perform_collection(session=self)
|
||||
config.hook.pytest_runtest_mainloop(session=self)
|
||||
if self._testsfailed:
|
||||
exitstatus = EXIT_TESTSFAILED
|
||||
self.sessionfinishes(exitstatus=exitstatus)
|
||||
config.pluginmanager.do_unconfigure(config)
|
||||
except self.config.Error:
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
self.config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
||||
exitstatus = EXIT_INTERRUPTED
|
||||
self.exitstatus = EXIT_INTERRUPTED
|
||||
except:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
self.config.pluginmanager.notify_exception(excinfo)
|
||||
exitstatus = EXIT_INTERNALERROR
|
||||
self.exitstatus = EXIT_INTERNALERROR
|
||||
if excinfo.errisinstance(SystemExit):
|
||||
sys.stderr.write("mainloop: caught Spurious SystemExit!\n")
|
||||
if exitstatus in (EXIT_INTERNALERROR, EXIT_INTERRUPTED):
|
||||
self.sessionfinishes(exitstatus=exitstatus)
|
||||
return exitstatus
|
||||
|
||||
if not self.exitstatus and self._testsfailed:
|
||||
self.exitstatus = EXIT_TESTSFAILED
|
||||
self.config.hook.pytest_sessionfinish(
|
||||
session=self, exitstatus=self.exitstatus,
|
||||
)
|
||||
config.pluginmanager.do_unconfigure(config)
|
||||
return self.exitstatus
|
||||
|
||||
class Collection:
|
||||
def __init__(self, config):
|
||||
|
|
|
@ -7,7 +7,7 @@ def test_cmdmain(name, pytestconfig):
|
|||
main = getattr(py.cmdline, name)
|
||||
assert py.builtin.callable(main)
|
||||
assert name[:2] == "py"
|
||||
if pytestconfig.getvalue("toolsonpath"):
|
||||
if not pytestconfig.getvalue("notoolsonpath"):
|
||||
scriptname = "py." + name[2:]
|
||||
assert py.path.local.sysfind(scriptname), scriptname
|
||||
|
||||
|
|
|
@ -95,7 +95,8 @@ class TestTerminal:
|
|||
item.config.pluginmanager.register(tr)
|
||||
nodeid = item.collection.getid(item)
|
||||
location = item.ihook.pytest_report_iteminfo(item=item)
|
||||
tr.config.hook.pytest_runtest_logstart(nodeid=nodeid, location=location)
|
||||
tr.config.hook.pytest_runtest_logstart(nodeid=nodeid,
|
||||
location=location, fspath=str(item.fspath))
|
||||
linecomp.assert_contains_lines([
|
||||
"*test_show_runtest_logstart.py*"
|
||||
])
|
||||
|
|
Loading…
Reference in New Issue