test_ok1/py/test/session.py

132 lines
4.5 KiB
Python

import py
class Session(object):
"""
A Session gets test Items from Collectors, # executes the
Items and sends the Outcome to the Reporter.
"""
def __init__(self, config):
self._memo = []
self.config = config
def shouldclose(self):
return False
def header(self, colitems):
""" setup any neccessary resources ahead of the test run. """
if not self.config.option.nomagic:
py.magic.invoke(assertion=1)
def footer(self, colitems):
""" teardown any resources after a test run. """
py.test.Function.state.teardown_all()
if not self.config.option.nomagic:
py.magic.revoke(assertion=1)
def fixoptions(self):
""" check, fix and determine conflicting options. """
option = self.config.option
# implied options
if option.usepdb:
if not option.nocapture:
option.nocapture = 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."
def start(self, colitem):
""" hook invoked before each colitem.run() invocation. """
def finish(self, colitem, outcome):
""" hook invoked after each colitem.run() invocation. """
self._memo.append((colitem, outcome))
def startiteration(self, colitem, subitems):
pass
def getitemoutcomepairs(self, cls):
return [x for x in self._memo if isinstance(x[1], cls)]
def main(self):
""" main loop for running tests. """
colitems = self.config.getcolitems()
try:
self.header(colitems)
try:
try:
for colitem in colitems:
self.runtraced(colitem)
except KeyboardInterrupt:
raise
finally:
self.footer(colitems)
except Exit, ex:
pass
def runtraced(self, colitem):
if self.shouldclose():
raise Exit, "received external close signal"
outcome = None
colitem.startcapture()
try:
self.start(colitem)
try:
try:
if colitem._stickyfailure:
raise colitem._stickyfailure
outcome = self.run(colitem)
except (KeyboardInterrupt, Exit):
raise
except colitem.Outcome, outcome:
if outcome.excinfo is None:
outcome.excinfo = py.code.ExceptionInfo()
except:
excinfo = py.code.ExceptionInfo()
outcome = colitem.Failed(excinfo=excinfo)
assert (outcome is None or
isinstance(outcome, (list, colitem.Outcome)))
finally:
self.finish(colitem, outcome)
if isinstance(outcome, colitem.Failed) and self.config.option.exitfirst:
py.test.exit("exit on first problem configured.", item=colitem)
finally:
colitem.finishcapture()
def run(self, colitem):
if self.config.option.collectonly and isinstance(colitem, py.test.Item):
return
if isinstance(colitem, py.test.Item):
colitem.skipbykeyword(self.config.option.keyword)
res = colitem.run()
if res is None:
return py.test.Item.Passed()
elif not isinstance(res, (list, tuple)):
raise TypeError("%r.run() returned neither "
"list, tuple nor None: %r" % (colitem, res))
else:
finish = self.startiteration(colitem, res)
try:
for name in res:
obj = colitem.join(name)
assert obj is not None
self.runtraced(obj)
finally:
if finish:
finish()
return res
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)