[svn r51033] merging of svn+ssh://codespeak.net/svn/py/branch/reporter-merge/py/test/session.py

revisions 47584 to 51032:

    ------------------------------------------------------------------------
    r51030 | hpk | 2008-01-25 14:30:54 +0100 (Fri, 25 Jan 2008) | 5 lines

    fixing test and restoring the functionality
    that session.main returns a list of failures
    (py.test --exec=python should work again)


    ------------------------------------------------------------------------
    r50984 | hpk | 2008-01-24 18:27:06 +0100 (Thu, 24 Jan 2008) | 1 line

    avoid reporting hooks on session object
    ------------------------------------------------------------------------
    r49391 | fijal | 2007-12-05 17:33:05 +0100 (Wed, 05 Dec 2007) | 2 lines

    Don't cache results.

    ------------------------------------------------------------------------
    r48698 | fijal | 2007-11-15 01:31:42 +0100 (Thu, 15 Nov 2007) | 2 lines

    Uh. 2.4 compatibility

    ------------------------------------------------------------------------
    r48318 | fijal | 2007-11-05 16:47:34 +0100 (Mon, 05 Nov 2007) | 3 lines

    Seems that --pdb don't need to imply -s and worked out of the box.
    I've got no idea how to test it though :-/

    ------------------------------------------------------------------------
    r48140 | fijal | 2007-10-28 19:43:21 +0100 (Sun, 28 Oct 2007) | 2 lines

    Reintroduce boxing

    ------------------------------------------------------------------------
    r48138 | fijal | 2007-10-28 19:22:42 +0100 (Sun, 28 Oct 2007) | 2 lines

    Share more code.

    ------------------------------------------------------------------------
    r48130 | fijal | 2007-10-28 14:58:42 +0100 (Sun, 28 Oct 2007) | 2 lines

    Add --collectonly handling, new style, logic separated

    ------------------------------------------------------------------------
    r48129 | fijal | 2007-10-28 14:41:06 +0100 (Sun, 28 Oct 2007) | 2 lines

    Refactor LocalReporter not to rely on hosts being there

    ------------------------------------------------------------------------
    r48128 | fijal | 2007-10-28 14:24:41 +0100 (Sun, 28 Oct 2007) | 2 lines

    Small regactoring for simple usage of default reporter class

    ------------------------------------------------------------------------
    r48127 | fijal | 2007-10-28 12:56:41 +0100 (Sun, 28 Oct 2007) | 2 lines

    Remove terminal session as it's no longer needed

    ------------------------------------------------------------------------
    r48126 | fijal | 2007-10-28 12:48:35 +0100 (Sun, 28 Oct 2007) | 2 lines

    Some real test for itemgen

    ------------------------------------------------------------------------
    r47678 | fijal | 2007-10-21 18:43:54 +0200 (Sun, 21 Oct 2007) | 2 lines

    Make even less things working.

    ------------------------------------------------------------------------
    r47667 | fijal | 2007-10-21 13:00:20 +0200 (Sun, 21 Oct 2007) | 4 lines

    Huge refactoring, the target is unification of session reporters and
    eventually sessions. Right now there is about 200 lines of code cut,
    but there is still some code to die and also some features missing :)

    ------------------------------------------------------------------------
    r47660 | fijal | 2007-10-21 00:02:04 +0200 (Sun, 21 Oct 2007) | 2 lines

    Create a new branch for reporter merge

    ------------------------------------------------------------------------

--HG--
branch : trunk
This commit is contained in:
hpk 2008-01-25 16:51:46 +01:00
parent b7c0d84ee3
commit 192a890435
1 changed files with 165 additions and 0 deletions

View File

@ -0,0 +1,165 @@
import py
import sys
from py.__.test.outcome import Outcome, Failed, Passed, Skipped
from py.__.test.reporter import choose_reporter, TestReporter
from py.__.test import repevent
from py.__.test.outcome import SerializableOutcome, ReprOutcome
from py.__.test.reporter import LocalReporter
from py.__.test.executor import RunExecutor, BoxExecutor
""" The session implementation - reporter version:
* itemgen is responsible for iterating and telling reporter
about skipped and failed iterations (this is for collectors only),
this should be probably moved to session (for uniformity)
* session gets items which needs to be executed one after another
and tells reporter about that
"""
try:
GeneratorExit
except NameError:
GeneratorExit = StopIteration # I think
def itemgen(session, colitems, reporter, keyword=None):
stopitems = py.test.collect.Item # XXX should be generator here as well
while 1:
if not colitems:
break
next = colitems.pop(0)
if reporter:
reporter(repevent.ItemStart(next))
if isinstance(next, stopitems):
try:
next._skipbykeyword(keyword)
yield next
except Skipped:
if session.config.option.keyword_oneshot:
keyword = None
excinfo = py.code.ExceptionInfo()
reporter(repevent.SkippedTryiter(excinfo, next))
else:
try:
cols = [next.join(x) for x in next.run()]
for x in itemgen(session, cols, reporter, keyword):
yield x
except (KeyboardInterrupt, SystemExit, GeneratorExit):
raise
except:
excinfo = py.code.ExceptionInfo()
if excinfo.type is Skipped:
reporter(repevent.SkippedTryiter(excinfo, next))
else:
reporter(repevent.FailedTryiter(excinfo, next))
if reporter:
reporter(repevent.ItemFinish(next))
class AbstractSession(object):
""" An abstract session executes collectors/items through a runner.
"""
def __init__(self, config):
self.config = config
self._keyword = config.option.keyword
def fixoptions(self):
""" check, fix and determine conflicting options. """
option = self.config.option
if option.runbrowser and not option.startserver:
#print "--runbrowser implies --startserver"
option.startserver = True
if self.config.getvalue("dist_boxed") and option.dist:
option.boxed = True
# conflicting options
if option.looponfailing and option.usepdb:
raise ValueError, "--looponfailing together with --pdb not supported."
if option.looponfailing and option.dist:
raise ValueError, "--looponfailing together with --dist not supported."
if option.executable and option.usepdb:
raise ValueError, "--exec together with --pdb not supported."
if option.keyword_oneshot and not option.keyword:
raise ValueError, "--keyword-oneshot makes sense only when --keyword is supplied"
def init_reporter(self, reporter, config, hosts):
if reporter is None:
reporter = choose_reporter(self.reporterclass, config)\
(config, hosts)
else:
reporter = TestReporter(reporter)
checkfun = lambda : self.config.option.exitfirst and \
reporter.was_failure()
return reporter, checkfun
class Session(AbstractSession):
"""
A Session gets test Items from Collectors, executes the
Items and sends the Outcome to the Reporter.
"""
reporterclass = LocalReporter
def shouldclose(self):
return False
def header(self, colitems):
""" setup any neccessary resources ahead of the test run. """
self.reporter(repevent.TestStarted(None, self.config,
None))
if not self.config.option.nomagic:
py.magic.invoke(assertion=1)
def footer(self, colitems):
""" teardown any resources after a test run. """
py.test.collect.Function._state.teardown_all()
if not self.config.option.nomagic:
py.magic.revoke(assertion=1)
self.reporter(repevent.TestFinished())
def main(self, reporter=None):
""" main loop for running tests. """
config = self.config
self.reporter, shouldstop = self.init_reporter(reporter, config, None)
colitems = self.config.getcolitems()
self.header(colitems)
keyword = self.config.option.keyword
reporter = self.reporter
itemgenerator = itemgen(self, colitems, reporter, keyword)
failures = []
try:
while 1:
try:
item = itemgenerator.next()
if shouldstop():
return
outcome = self.run(item)
if outcome is not None:
if not outcome.passed and not outcome.skipped:
failures.append((item, outcome))
reporter(repevent.ReceivedItemOutcome(None, item, outcome))
except StopIteration:
break
finally:
self.footer(colitems)
return failures
return self.getitemoutcomepairs(Failed)
def run(self, item):
if not self.config.option.boxed:
executor = RunExecutor(item, self.config.option.usepdb,
self.reporter, self.config)
return ReprOutcome(executor.execute().make_repr())
else:
executor = BoxExecutor(item, self.config.option.usepdb,
self.reporter, self.config)
return ReprOutcome(executor.execute())
class Exit(Exception):
""" for immediate program exits without tracebacks and reporter/summary. """
def __init__(self, msg="unknown reason", item=None):
self.msg = msg
Exception.__init__(self, msg)
def exit(msg, item=None):
raise Exit(msg=msg, item=item)