From f779d3f863f347e38b4b6be9951642a5d75c36d5 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Tue, 28 Sep 2010 12:59:48 +0200 Subject: [PATCH] rework session instantiation and exitstatus handling --HG-- branch : trunk --- py/_plugin/hookspec.py | 4 ++-- py/_plugin/pytest_runner.py | 13 ++++++----- py/_plugin/pytest_terminal.py | 28 +++++++++++++----------- py/_test/session.py | 30 +++++++++++--------------- testing/cmdline/test_cmdline.py | 2 +- testing/plugin/test_pytest_terminal.py | 3 ++- 6 files changed, 41 insertions(+), 39 deletions(-) diff --git a/py/_plugin/hookspec.py b/py/_plugin/hookspec.py index f9ec47ada..3b75d8925 100644 --- a/py/_plugin/hookspec.py +++ b/py/_plugin/hookspec.py @@ -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. """ # ------------------------------------------------------------------------- diff --git a/py/_plugin/pytest_runner.py b/py/_plugin/pytest_runner.py index a9989af2a..7f7672b49 100644 --- a/py/_plugin/pytest_runner.py +++ b/py/_plugin/pytest_runner.py @@ -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 diff --git a/py/_plugin/pytest_terminal.py b/py/_plugin/pytest_terminal.py index db463d601..d4553ad5e 100644 --- a/py/_plugin/pytest_terminal.py +++ b/py/_plugin/pytest_terminal.py @@ -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 diff --git a/py/_test/session.py b/py/_test/session.py index 2524972bd..db9bcc1f8 100644 --- a/py/_test/session.py +++ b/py/_test/session.py @@ -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): diff --git a/testing/cmdline/test_cmdline.py b/testing/cmdline/test_cmdline.py index cc3ce1399..8438d876b 100644 --- a/testing/cmdline/test_cmdline.py +++ b/testing/cmdline/test_cmdline.py @@ -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 diff --git a/testing/plugin/test_pytest_terminal.py b/testing/plugin/test_pytest_terminal.py index feada5178..c84ba4cb1 100644 --- a/testing/plugin/test_pytest_terminal.py +++ b/testing/plugin/test_pytest_terminal.py @@ -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*" ])