make setupevent tests of pytest_runner.py work

--HG--
branch : trunk
This commit is contained in:
holger krekel 2009-05-22 19:56:05 +02:00
parent 30e04b1ec6
commit b8926f59da
18 changed files with 368 additions and 487 deletions

View File

@ -25,8 +25,8 @@ class LoopState(object):
self.testsfailed = False self.testsfailed = False
def pytest_itemtestreport(self, rep): def pytest_itemtestreport(self, rep):
if rep.colitem in self.dsession.item2nodes: if rep.item in self.dsession.item2nodes:
self.dsession.removeitem(rep.colitem, rep.node) self.dsession.removeitem(rep.item, rep.node)
if rep.failed: if rep.failed:
self.testsfailed = True self.testsfailed = True

View File

@ -180,10 +180,10 @@ class TestDSession:
session.loop_once(loopstate) session.loop_once(loopstate)
assert loopstate.colitems == [item2] # do not reschedule crash item assert loopstate.colitems == [item2] # do not reschedule crash item
testrep = reprec.matchreport(names="pytest_itemtestreport") rep = reprec.matchreport(names="pytest_itemtestreport")
assert testrep.failed assert rep.failed
assert testrep.colitem == item1 assert rep.item == item1
assert str(testrep.longrepr).find("crashed") != -1 assert str(rep.longrepr).find("crashed") != -1
#assert str(testrep.longrepr).find(node.gateway.spec) != -1 #assert str(testrep.longrepr).find(node.gateway.spec) != -1
def test_testnodeready_adds_to_available(self, testdir): def test_testnodeready_adds_to_available(self, testdir):

View File

@ -115,7 +115,7 @@ class TestMasterSlaveConnection:
rep = kwargs['rep'] rep = kwargs['rep']
assert rep.passed assert rep.passed
print rep print rep
assert rep.colitem == item assert rep.item == item
def test_send_some(self, testdir, mysetup): def test_send_some(self, testdir, mysetup):
items = testdir.getitems(""" items = testdir.getitems("""

View File

@ -150,4 +150,4 @@ def slave_runsession(channel, config, fullwidth, hasmarkup):
session.config.hook.pytest_looponfailinfo( session.config.hook.pytest_looponfailinfo(
failreports=list(failreports), failreports=list(failreports),
rootdirs=[config.topdir]) rootdirs=[config.topdir])
channel.send([x.colitem._totrail() for x in failreports]) channel.send([rep.getnode()._totrail() for rep in failreports])

View File

@ -84,10 +84,11 @@ class PluginHooks:
def pytest_itemtestreport(self, rep): def pytest_itemtestreport(self, rep):
""" test has been run. """ """ test has been run. """
# XXX pytest_runner reports
def pytest_item_runtest_finished(self, item, excinfo, outerr): def pytest_item_runtest_finished(self, item, excinfo, outerr):
""" test has been run. """ """ test has been run. """
def pytest_itemsetupreport(self, rep): def pytest_itemfixturereport(self, rep):
""" a report on running a fixture function. """ """ a report on running a fixture function. """
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -91,7 +91,7 @@ class HookRecorder:
if call._name == name: if call._name == name:
del self.calls[i] del self.calls[i]
return call return call
raise ValueError("could not find call %r in %r" %(name, self.calls)) raise ValueError("could not find call %r" %(name, ))
def getcall(self, name): def getcall(self, name):
l = self.getcalls(name) l = self.getcalls(name)

View File

@ -141,7 +141,6 @@ class TestDoctests:
reprec.assertoutcome(failed=1) reprec.assertoutcome(failed=1)
def test_txtfile_failing(self, testdir): def test_txtfile_failing(self, testdir):
testdir.plugins.append("doctest")
p = testdir.maketxtfile(""" p = testdir.maketxtfile("""
>>> i = 0 >>> i = 0
>>> i + 1 >>> i + 1

View File

@ -305,6 +305,9 @@ class ReportRecorder(object):
def getcall(self, name): def getcall(self, name):
return self.hookrecorder.getcall(name) return self.hookrecorder.getcall(name)
def popcall(self, name):
return self.hookrecorder.popcall(name)
def getcalls(self, names): def getcalls(self, names):
""" return list of ParsedCall instances matching the given eventname. """ """ return list of ParsedCall instances matching the given eventname. """
return self.hookrecorder.getcalls(names) return self.hookrecorder.getcalls(names)
@ -318,7 +321,8 @@ class ReportRecorder(object):
""" return a testreport whose dotted import path matches """ """ return a testreport whose dotted import path matches """
l = [] l = []
for rep in self.getreports(names=names): for rep in self.getreports(names=names):
if not inamepart or inamepart in rep.colitem.listnames(): colitem = rep.getnode()
if not inamepart or inamepart in colitem.listnames():
l.append(rep) l.append(rep)
if not l: if not l:
raise ValueError("could not find test report matching %r: no test reports at all!" % raise ValueError("could not find test report matching %r: no test reports at all!" %

View File

@ -20,7 +20,7 @@ def pytest_unconfigure(config):
resultlog = getattr(config, '_resultlog', None) resultlog = getattr(config, '_resultlog', None)
if resultlog: if resultlog:
resultlog.logfile.close() resultlog.logfile.close()
del config.resultlog del config._resultlog
config.pluginmanager.unregister(resultlog) config.pluginmanager.unregister(resultlog)
def generic_path(item): def generic_path(item):
@ -55,8 +55,8 @@ class ResultLog(object):
for line in longrepr.splitlines(): for line in longrepr.splitlines():
print >>self.logfile, " %s" % line print >>self.logfile, " %s" % line
def log_outcome(self, event, shortrepr, longrepr): def log_outcome(self, node, shortrepr, longrepr):
testpath = generic_path(event.colitem) testpath = generic_path(node)
self.write_log_entry(testpath, shortrepr, longrepr) self.write_log_entry(testpath, shortrepr, longrepr)
def pytest_itemtestreport(self, rep): def pytest_itemtestreport(self, rep):
@ -67,7 +67,7 @@ class ResultLog(object):
longrepr = str(rep.longrepr) longrepr = str(rep.longrepr)
elif rep.skipped: elif rep.skipped:
longrepr = str(rep.longrepr.reprcrash.message) longrepr = str(rep.longrepr.reprcrash.message)
self.log_outcome(rep, code, longrepr) self.log_outcome(rep.item, code, longrepr)
def pytest_collectreport(self, rep): def pytest_collectreport(self, rep):
if not rep.passed: if not rep.passed:
@ -77,7 +77,7 @@ class ResultLog(object):
assert rep.skipped assert rep.skipped
code = "S" code = "S"
longrepr = str(rep.longrepr.reprcrash) longrepr = str(rep.longrepr.reprcrash)
self.log_outcome(rep, code, longrepr) self.log_outcome(rep.collector, code, longrepr)
def pytest_internalerror(self, excrepr): def pytest_internalerror(self, excrepr):
path = excrepr.reprcrash.path path = excrepr.reprcrash.path

View File

@ -1,29 +1,37 @@
import py import py
from py.__.test.outcome import Skipped from py.__.test.outcome import Skipped
from py.__.test.runner import SetupState
class RunnerPlugin: py.test.skip("remove me")
def pytest_configure(self, config):
def pytest_configure(config):
config._setupstate = SetupState() config._setupstate = SetupState()
def pytest_unconfigure(self, config): def pytest_unconfigure(config):
config._setupstate.teardown_all() config._setupstate.teardown_all()
def pytest_item_setup_and_runtest(self, item): def pytest_item_setup_and_runtest(item):
setupstate = item.config._setupstate setupstate = item.config._setupstate
# setup (and implied teardown of previous items)
call = item.config.guardedcall(lambda: setupstate.prepare(item)) call = item.config.guardedcall(lambda: setupstate.prepare(item))
if call.excinfo: if call.excinfo:
rep = ItemSetupReport(item, call.excinfo, call.outerr) rep = ItemTestReport(item, call.excinfo, call.outerr)
item.config.hook.pytest_itemsetupreport(rep=rep) item.config.hook.pytest_itemfixturereport(rep=rep)
else: return
# runtest
call = item.config.guardedcall(lambda: item.runtest()) call = item.config.guardedcall(lambda: item.runtest())
item.config.hook.pytest_item_runtest_finished( item.config.hook.pytest_item_runtest_finished(
item=item, excinfo=call.excinfo, outerr=call.outerr) item=item, excinfo=call.excinfo, outerr=call.outerr)
call = item.config.guardedcall(lambda: self.teardown_exact(item))
if call.excinfo:
rep = ItemSetupReport(item, call.excinfo, call.outerr)
item.config.hook.pytest_itemsetupreport(rep=rep)
def pytest_collector_collect(self, collector): # teardown
call = item.config.guardedcall(lambda: setupstate.teardown_exact(item))
if call.excinfo:
rep = ItemFixtureReport(item, call.excinfo, call.outerr)
item.config.hook.pytest_itemfixturereport(rep=rep)
def pytest_collector_collect(collector):
call = item.config.guardedcall(lambda x: collector._memocollect()) call = item.config.guardedcall(lambda x: collector._memocollect())
return CollectReport(collector, res, excinfo, outerr) return CollectReport(collector, res, excinfo, outerr)
@ -97,7 +105,7 @@ class CollectReport(BaseReport):
else: else:
self.failed = True self.failed = True
class ItemSetupReport(BaseReport): class ItemFixtureReport(BaseReport):
failed = passed = skipped = False failed = passed = skipped = False
def __init__(self, item, excinfo=None, outerr=None): def __init__(self, item, excinfo=None, outerr=None):
self.item = item self.item = item
@ -111,33 +119,6 @@ class ItemSetupReport(BaseReport):
self.failed = True self.failed = True
self.excrepr = item._repr_failure_py(excinfo, []) self.excrepr = item._repr_failure_py(excinfo, [])
class SetupState(object):
""" shared state for setting up/tearing down test items or collectors. """
def __init__(self):
self.stack = []
def teardown_all(self):
while self.stack:
col = self.stack.pop()
col.teardown()
def teardown_exact(self, item):
if self.stack and self.stack[-1] == item:
col = self.stack.pop()
col.teardown()
def prepare(self, colitem):
""" setup objects along the collector chain to the test-method
Teardown any unneccessary previously setup objects."""
needed_collectors = colitem.listchain()
while self.stack:
if self.stack == needed_collectors[:len(self.stack)]:
break
col = self.stack.pop()
col.teardown()
for col in needed_collectors[len(self.stack):]:
col.setup()
self.stack.append(col)
# =============================================================================== # ===============================================================================
# #
@ -206,67 +187,71 @@ class TestSetupState:
class TestRunnerPlugin: class TestRunnerPlugin:
def test_pytest_item_setup_and_runtest(self, testdir): def test_pytest_item_setup_and_runtest(self, testdir):
item = testdir.getitem("""def test_func(): pass""") item = testdir.getitem("""def test_func(): pass""")
plugin = RunnerPlugin() pytest_configure(item.config)
plugin.pytest_configure(item.config)
reprec = testdir.getreportrecorder(item) reprec = testdir.getreportrecorder(item)
plugin.pytest_item_setup_and_runtest(item) pytest_item_setup_and_runtest(item)
rep = reprec.getcall("pytest_itemtestreport").rep rep = reprec.getcall("pytest_itemtestreport").rep
assert rep.passed assert rep.passed
class TestSetupEvents: class TestSetupEvents:
disabled = True def pytest_funcarg__runfunc(self, request):
testdir = request.getfuncargvalue("testdir")
def runfunc(source):
item = testdir.getitem(source)
reprec = testdir.getreportrecorder(item)
pytest_item_setup_and_runtest(item)
return reprec
return runfunc
def test_setup_runtest_ok(self, testdir): def test_setup_runtest_ok(self, runfunc):
reprec = testdir.inline_runsource(""" reprec = runfunc("""
def setup_module(mod): def setup_module(mod):
pass pass
def test_func(): def test_func():
pass pass
""") """)
assert not reprec.getcalls(pytest_itemsetupreport) assert not reprec.getcalls("pytest_itemfixturereport")
def test_setup_fails(self, testdir): def test_setup_fails(self, runfunc):
reprec = testdir.inline_runsource(""" reprec = runfunc("""
def setup_module(mod): def setup_module(mod):
print "world" print "world"
raise ValueError(42) raise ValueError(42)
def test_func(): def test_func():
pass pass
""") """)
rep = reprec.popcall(pytest_itemsetupreport).rep rep = reprec.popcall("pytest_itemfixturereport").rep
assert rep.failed assert rep.failed
assert not rep.skipped assert not rep.skipped
assert rep.excrepr assert rep.excrepr
assert "42" in str(rep.excrepr) assert "42" in str(rep.excrepr)
assert rep.outerr[0].find("world") != -1 assert rep.outerr[0].find("world") != -1
def test_teardown_fails(self, testdir): def test_teardown_fails(self, runfunc):
reprec = testdir.inline_runsource(""" reprec = runfunc("""
def test_func(): def test_func():
pass pass
def teardown_function(func): def teardown_function(func):
print "13" print "13"
raise ValueError(25) raise ValueError(25)
""") """)
rep = reprec.popcall(pytest_itemsetupreport).rep rep = reprec.popcall("pytest_itemfixturereport").rep
assert rep.failed assert rep.failed
assert rep.item == item assert rep.item.name == "test_func"
assert not rep.passed assert not rep.passed
assert "13" in rep.outerr[0] assert "13" in rep.outerr[0]
assert "25" in str(rep.excrepr) assert "25" in str(rep.excrepr)
def test_setup_skips(self, testdir): def test_setup_skips(self, runfunc):
reprec = testdir.inline_runsource(""" reprec = runfunc("""
import py import py
def setup_module(mod): def setup_module(mod):
py.test.skip("17") py.test.skip("17")
def test_func(): def test_func():
pass pass
""") """)
rep = reprec.popcall(pytest_itemsetupreport) rep = reprec.popcall("pytest_itemfixturereport").rep
assert not rep.failed assert not rep.failed
assert rep.skipped assert rep.skipped
assert rep.excrepr assert rep.excrepr
assert "17" in str(rep.excrepr) assert "17" in str(rep.excrepr)

View File

@ -162,7 +162,7 @@ class TerminalReporter:
self.write_fspath_result(fspath, "") self.write_fspath_result(fspath, "")
def pytest_itemtestreport(self, rep): def pytest_itemtestreport(self, rep):
fspath = rep.colitem.fspath fspath = rep.item.fspath
cat, letter, word = self.getcategoryletterword(rep) cat, letter, word = self.getcategoryletterword(rep)
if isinstance(word, tuple): if isinstance(word, tuple):
word, markup = word word, markup = word
@ -170,10 +170,10 @@ class TerminalReporter:
markup = {} markup = {}
self.stats.setdefault(cat, []).append(rep) self.stats.setdefault(cat, []).append(rep)
if not self.config.option.verbose: if not self.config.option.verbose:
fspath, lineno, msg = self._getreportinfo(rep.colitem) fspath, lineno, msg = self._getreportinfo(rep.item)
self.write_fspath_result(fspath, letter) self.write_fspath_result(fspath, letter)
else: else:
line = self._reportinfoline(rep.colitem) line = self._reportinfoline(rep.item)
if not hasattr(rep, 'node'): if not hasattr(rep, 'node'):
self.write_ensure_prefix(line, word, **markup) self.write_ensure_prefix(line, word, **markup)
else: else:
@ -189,10 +189,10 @@ class TerminalReporter:
if rep.failed: if rep.failed:
self.stats.setdefault("failed", []).append(rep) self.stats.setdefault("failed", []).append(rep)
msg = rep.longrepr.reprcrash.message msg = rep.longrepr.reprcrash.message
self.write_fspath_result(rep.colitem.fspath, "F") self.write_fspath_result(rep.collector.fspath, "F")
elif rep.skipped: elif rep.skipped:
self.stats.setdefault("skipped", []).append(rep) self.stats.setdefault("skipped", []).append(rep)
self.write_fspath_result(rep.colitem.fspath, "S") self.write_fspath_result(rep.collector.fspath, "S")
def pytest_testrunstart(self): def pytest_testrunstart(self):
self.write_sep("=", "test session starts", bold=True) self.write_sep("=", "test session starts", bold=True)
@ -268,10 +268,10 @@ class TerminalReporter:
return line % locals() + " " return line % locals() + " "
def _getfailureheadline(self, rep): def _getfailureheadline(self, rep):
if isinstance(rep.colitem, py.test.collect.Collector): if hasattr(rep, "collector"):
return str(rep.colitem.fspath) return str(rep.collector.fspath)
else: else:
fspath, lineno, msg = self._getreportinfo(rep.colitem) fspath, lineno, msg = self._getreportinfo(rep.item)
return msg return msg
def _getreportinfo(self, item): def _getreportinfo(self, item):

View File

@ -40,7 +40,7 @@ def pytest_terminal_summary(terminalreporter):
entry = event.longrepr.reprcrash entry = event.longrepr.reprcrash
key = entry.path, entry.lineno, entry.message key = entry.path, entry.lineno, entry.message
reason = event.longrepr.reprcrash.message reason = event.longrepr.reprcrash.message
modpath = event.colitem.getmodpath(includemodule=True) modpath = event.item.getmodpath(includemodule=True)
#tr._tw.line("%s %s:%d: %s" %(modpath, entry.path, entry.lineno, entry.message)) #tr._tw.line("%s %s:%d: %s" %(modpath, entry.path, entry.lineno, entry.message))
tr._tw.line("%s %s:%d: " %(modpath, entry.path, entry.lineno)) tr._tw.line("%s %s:%d: " %(modpath, entry.path, entry.lineno))
@ -48,7 +48,7 @@ def pytest_terminal_summary(terminalreporter):
if xpassed: if xpassed:
tr.write_sep("_", "UNEXPECTEDLY PASSING TESTS") tr.write_sep("_", "UNEXPECTEDLY PASSING TESTS")
for event in xpassed: for event in xpassed:
tr._tw.line("%s: xpassed" %(event.colitem,)) tr._tw.line("%s: xpassed" %(event.item,))
# =============================================================================== # ===============================================================================
# #

View File

@ -19,13 +19,13 @@ def basic_run_report(item, pdb=None):
when = "setup" when = "setup"
item.config._setupstate.prepare(item) item.config._setupstate.prepare(item)
try: try:
when = "execute" when = "runtest"
if not item._deprecated_testexecution(): if not item._deprecated_testexecution():
item.runtest() item.runtest()
finally: finally:
when = "teardown" when = "teardown"
item.config._setupstate.teardown_exact(item) item.config._setupstate.teardown_exact(item)
when = "execute" when = "runtest"
finally: finally:
outerr = capture.reset() outerr = capture.reset()
except KeyboardInterrupt: except KeyboardInterrupt:
@ -41,18 +41,13 @@ def basic_run_report(item, pdb=None):
return testrep return testrep
def basic_collect_report(collector): def basic_collect_report(collector):
excinfo = res = None call = collector.config.guardedcall(
try: lambda: collector._memocollect()
capture = collector.config._getcapture() )
try: result = None
res = collector._memocollect() if not call.excinfo:
finally: result = call.result
outerr = capture.reset() return CollectReport(collector, result, call.excinfo, call.outerr)
except KeyboardInterrupt:
raise
except:
excinfo = py.code.ExceptionInfo()
return CollectReport(collector, res, excinfo, outerr)
def forked_run_report(item, pdb=None): def forked_run_report(item, pdb=None):
EXITSTATUS_TESTEXIT = 4 EXITSTATUS_TESTEXIT = 4
@ -99,11 +94,10 @@ class BaseReport(object):
class ItemTestReport(BaseReport): class ItemTestReport(BaseReport):
failed = passed = skipped = False failed = passed = skipped = False
# XXX rename colitem to item here def __init__(self, item, excinfo=None, when=None, outerr=None):
def __init__(self, colitem, excinfo=None, when=None, outerr=None): self.item = item
self.colitem = colitem if item and when != "setup":
if colitem and when != "setup": self.keywords = item.readkeywords()
self.keywords = colitem.readkeywords()
else: else:
# if we fail during setup it might mean # if we fail during setup it might mean
# we are not able to access the underlying object # we are not able to access the underlying object
@ -123,50 +117,40 @@ class ItemTestReport(BaseReport):
elif excinfo.errisinstance(Skipped): elif excinfo.errisinstance(Skipped):
self.skipped = True self.skipped = True
shortrepr = "s" shortrepr = "s"
longrepr = self.colitem._repr_failure_py(excinfo, outerr) longrepr = self.item._repr_failure_py(excinfo, outerr)
else: else:
self.failed = True self.failed = True
shortrepr = self.colitem.shortfailurerepr shortrepr = self.item.shortfailurerepr
if self.when == "execute": if self.when == "runtest":
longrepr = self.colitem.repr_failure(excinfo, outerr) longrepr = self.item.repr_failure(excinfo, outerr)
else: # exception in setup or teardown else: # exception in setup or teardown
longrepr = self.colitem._repr_failure_py(excinfo, outerr) longrepr = self.item._repr_failure_py(excinfo, outerr)
shortrepr = shortrepr.lower() shortrepr = shortrepr.lower()
self.shortrepr = shortrepr self.shortrepr = shortrepr
self.longrepr = longrepr self.longrepr = longrepr
def getnode(self):
return self.item
class CollectReport(BaseReport): class CollectReport(BaseReport):
skipped = failed = passed = False skipped = failed = passed = False
def __init__(self, colitem, result, excinfo=None, outerr=None): def __init__(self, collector, result, excinfo=None, outerr=None):
# XXX rename to collector self.collector = collector
self.colitem = colitem
if not excinfo: if not excinfo:
self.passed = True self.passed = True
self.result = result self.result = result
else: else:
self.outerr = outerr self.outerr = outerr
self.longrepr = self.colitem._repr_failure_py(excinfo, outerr) self.longrepr = self.collector._repr_failure_py(excinfo, outerr)
if excinfo.errisinstance(Skipped): if excinfo.errisinstance(Skipped):
self.skipped = True self.skipped = True
self.reason = str(excinfo.value) self.reason = str(excinfo.value)
else: else:
self.failed = True self.failed = True
class ItemSetupReport(BaseReport): def getnode(self):
failed = passed = skipped = False return self.collector
def __init__(self, item, excinfo=None, outerr=None):
self.item = item
self.outerr = outerr
if not excinfo:
self.passed = True
else:
if excinfo.errisinstance(Skipped):
self.skipped = True
else:
self.failed = True
self.excrepr = item._repr_failure_py(excinfo, [])
class SetupState(object): class SetupState(object):
""" shared state for setting up/tearing down test items or collectors. """ """ shared state for setting up/tearing down test items or collectors. """

View File

@ -176,7 +176,7 @@ class TestCollectPluginHooks:
assert "world" in wascalled assert "world" in wascalled
# make sure the directories do not get double-appended # make sure the directories do not get double-appended
colreports = reprec.getreports("pytest_collectreport") colreports = reprec.getreports("pytest_collectreport")
names = [rep.colitem.name for rep in colreports] names = [rep.collector.name for rep in colreports]
assert names.count("hello") == 1 assert names.count("hello") == 1
class TestCustomConftests: class TestCustomConftests:
@ -214,8 +214,8 @@ class TestCustomConftests:
""") """)
testdir.mkdir("hello") testdir.mkdir("hello")
reprec = testdir.inline_run(testdir.tmpdir) reprec = testdir.inline_run(testdir.tmpdir)
names = [rep.colitem.name for rep in reprec.getreports("pytest_collectreport")] names = [rep.collector.name for rep in reprec.getreports("pytest_collectreport")]
assert 'hello' not in names assert 'hello' not in names
reprec = testdir.inline_run(testdir.tmpdir, "--XX") reprec = testdir.inline_run(testdir.tmpdir, "--XX")
names = [rep.colitem.name for rep in reprec.getreports("pytest_collectreport")] names = [rep.collector.name for rep in reprec.getreports("pytest_collectreport")]
assert 'hello' in names assert 'hello' in names

View File

@ -73,7 +73,7 @@ class TestKeywordSelection:
reprec = testdir.inline_run("-s", "-k", keyword, file_test) reprec = testdir.inline_run("-s", "-k", keyword, file_test)
passed, skipped, failed = reprec.listoutcomes() passed, skipped, failed = reprec.listoutcomes()
assert len(failed) == 1 assert len(failed) == 1
assert failed[0].colitem.name == name assert failed[0].item.name == name
assert len(reprec.getcalls('pytest_deselected')) == 1 assert len(reprec.getcalls('pytest_deselected')) == 1
for keyword in ['test_one', 'est_on']: for keyword in ['test_one', 'est_on']:
@ -101,7 +101,7 @@ class TestKeywordSelection:
print "keyword", repr(keyword) print "keyword", repr(keyword)
passed, skipped, failed = reprec.listoutcomes() passed, skipped, failed = reprec.listoutcomes()
assert len(passed) == 1 assert len(passed) == 1
assert passed[0].colitem.name == "test_2" assert passed[0].item.name == "test_2"
dlist = reprec.getcalls("pytest_deselected") dlist = reprec.getcalls("pytest_deselected")
assert len(dlist) == 1 assert len(dlist) == 1
assert dlist[0].items[0].name == 'test_1' assert dlist[0].items[0].name == 'test_1'

View File

@ -1,9 +1,10 @@
import py
from py.__.test.config import SetupState from py.__.test import runner
from py.__.code.excinfo import ReprExceptionInfo
class TestSetupState: class TestSetupState:
def test_setup(self, testdir): def test_setup(self, testdir):
ss = SetupState() ss = runner.SetupState()
item = testdir.getitem("def test_func(): pass") item = testdir.getitem("def test_func(): pass")
l = [1] l = [1]
ss.prepare(item) ss.prepare(item)
@ -14,7 +15,7 @@ class TestSetupState:
def test_setup_scope_None(self, testdir): def test_setup_scope_None(self, testdir):
item = testdir.getitem("def test_func(): pass") item = testdir.getitem("def test_func(): pass")
ss = SetupState() ss = runner.SetupState()
l = [1] l = [1]
ss.prepare(item) ss.prepare(item)
ss.addfinalizer(l.pop, colitem=None) ss.addfinalizer(l.pop, colitem=None)
@ -26,93 +27,263 @@ class TestSetupState:
ss.teardown_all() ss.teardown_all()
assert not l assert not l
class TestSetupStateFunctional:
disabled = True class BaseFunctionalTests:
def test_setup_ok(self, testdir): def test_funcattr(self, testdir):
item = testdir.getitem(""" rep = testdir.runitem("""
def setup_module(mod): import py
pass @py.test.mark(xfail="needs refactoring")
def test_func():
raise Exit()
""")
assert rep.keywords['xfail'] == "needs refactoring"
def test_passfunction(self, testdir):
rep = testdir.runitem("""
def test_func(): def test_func():
pass pass
""") """)
reprec = testdir.getreportrecorder(item.config) assert rep.passed
setup = SetupState() assert not rep.failed
res = setup.do_setup(item) assert rep.shortrepr == "."
assert res assert not hasattr(rep, 'longrepr')
def test_setup_fails(self, testdir): def test_failfunction(self, testdir):
item = testdir.getitem(""" rep = testdir.runitem("""
def setup_module(mod): def test_func():
print "world" assert 0
""")
assert not rep.passed
assert not rep.skipped
assert rep.failed
assert rep.when == "runtest"
assert isinstance(rep.longrepr, ReprExceptionInfo)
assert str(rep.shortrepr) == "F"
def test_skipfunction(self, testdir):
rep = testdir.runitem("""
import py
def test_func():
py.test.skip("hello")
""")
assert not rep.failed
assert not rep.passed
assert rep.skipped
#assert rep.skipped.when == "runtest"
#assert rep.skipped.when == "runtest"
#assert rep.skipped == "%sreason == "hello"
#assert rep.skipped.location.lineno == 3
#assert rep.skipped.location.path
#assert not rep.skipped.failurerepr
def test_skip_in_setup_function(self, testdir):
rep = testdir.runitem("""
import py
def setup_function(func):
py.test.skip("hello")
def test_func():
pass
""")
print rep
assert not rep.failed
assert not rep.passed
assert rep.skipped
#assert rep.skipped.reason == "hello"
#assert rep.skipped.location.lineno == 3
#assert rep.skipped.location.lineno == 3
def test_failure_in_setup_function(self, testdir):
rep = testdir.runitem("""
import py
def setup_function(func):
raise ValueError(42) raise ValueError(42)
def test_func(): def test_func():
pass pass
""") """)
reprec = testdir.getreportrecorder(item.config) print rep
setup = SetupState()
res = setup.do_setup(item)
assert not res
rep = reprec.popcall(pytest_itemsetupreport).rep
assert rep.failed
assert not rep.skipped assert not rep.skipped
assert rep.excrepr
assert "42" in str(rep.excrepr)
assert rep.outerr[0].find("world") != -1
def test_teardown_fails(self, testdir):
item = testdir.getitem("""
def test_func():
pass
def teardown_function(func):
print "13"
raise ValueError(25)
""")
reprec = testdir.getreportrecorder(item.config)
setup = SetupState()
res = setup.do_setup(item)
assert res
rep = reprec.popcall(pytest_itemsetupreport).rep
assert rep.passed
setup.do_teardown(item)
rep = reprec.popcall(pytest_itemsetupreport).rep
assert rep.item == item
assert rep.failed
assert not rep.passed assert not rep.passed
assert "13" in rep.outerr[0] assert rep.failed
assert "25" in str(rep.excrepr) assert rep.when == "setup"
def test_setupitem_skips(self, testdir): def test_failure_in_teardown_function(self, testdir):
item = testdir.getitem(""" rep = testdir.runitem("""
import py import py
def setup_module(mod): def teardown_function(func):
py.test.skip("17") raise ValueError(42)
def test_func(): def test_func():
pass pass
""") """)
reprec = testdir.getreportrecorder(item.config) print rep
setup = SetupState() assert not rep.skipped
setup.do_setup(item) assert not rep.passed
rep = reprec.popcall(pytest_itemsetupreport).rep assert rep.failed
assert not rep.failed assert rep.when == "teardown"
assert rep.longrepr.reprcrash.lineno == 3
assert rep.longrepr.reprtraceback.reprentries
def test_custom_failure_repr(self, testdir):
testdir.makepyfile(conftest="""
import py
class Function(py.test.collect.Function):
def repr_failure(self, excinfo, outerr):
return "hello"
""")
rep = testdir.runitem("""
import py
def test_func():
assert 0
""")
assert not rep.skipped
assert not rep.passed
assert rep.failed
#assert rep.outcome.when == "runtest"
#assert rep.failed.where.lineno == 3
#assert rep.failed.where.path.basename == "test_func.py"
#assert rep.failed.failurerepr == "hello"
def test_failure_in_setup_function_ignores_custom_failure_repr(self, testdir):
testdir.makepyfile(conftest="""
import py
class Function(py.test.collect.Function):
def repr_failure(self, excinfo):
assert 0
""")
rep = testdir.runitem("""
import py
def setup_function(func):
raise ValueError(42)
def test_func():
pass
""")
print rep
assert not rep.skipped
assert not rep.passed
assert rep.failed
#assert rep.outcome.when == "setup"
#assert rep.outcome.where.lineno == 3
#assert rep.outcome.where.path.basename == "test_func.py"
#assert instanace(rep.failed.failurerepr, PythonFailureRepr)
def test_capture_in_func(self, testdir):
rep = testdir.runitem("""
import py
def setup_function(func):
print >>py.std.sys.stderr, "in setup"
def test_func():
print "in function"
assert 0
def teardown_func(func):
print "in teardown"
""")
assert rep.failed
# out, err = rep.failed.outerr
# assert out == ['in function\nin teardown\n']
# assert err == ['in setup\n']
def test_systemexit_does_not_bail_out(self, testdir):
try:
rep = testdir.runitem("""
def test_func():
raise SystemExit(42)
""")
except SystemExit:
py.test.fail("runner did not catch SystemExit")
assert rep.failed
assert rep.when == "runtest"
def test_exit_propagates(self, testdir):
from py.__.test.outcome import Exit
try:
testdir.runitem("""
from py.__.test.outcome import Exit
def test_func():
raise Exit()
""")
except Exit:
pass
else:
py.test.fail("did not raise")
class TestExecutionNonForked(BaseFunctionalTests):
def getrunner(self):
return runner.basic_run_report
def test_keyboardinterrupt_propagates(self, testdir):
from py.__.test.outcome import Exit
try:
testdir.runitem("""
def test_func():
raise KeyboardInterrupt("fake")
""")
except KeyboardInterrupt, e:
pass
else:
py.test.fail("did not raise")
def test_pdb_on_fail(self, testdir):
l = []
rep = testdir.runitem("""
def test_func():
assert 0
""", pdb=l.append)
assert rep.failed
assert rep.when == "runtest"
assert len(l) == 1
def test_pdb_on_skip(self, testdir):
l = []
rep = testdir.runitem("""
import py
def test_func():
py.test.skip("hello")
""", pdb=l.append)
assert len(l) == 0
assert rep.skipped assert rep.skipped
assert rep.excrepr
assert "17" in str(rep.excrepr)
def test_runtest_ok(self, testdir): class TestExecutionForked(BaseFunctionalTests):
item = testdir.getitem("def test_func(): pass") def getrunner(self):
reprec = testdir.getreportrecorder(item.config) if not hasattr(py.std.os, 'fork'):
setup = SetupState() py.test.skip("no os.fork available")
setup.do_fixture_and_runtest(item) return runner.forked_run_report
rep = reprec.popcall(pytest_itemtestreport).rep
def test_suicide(self, testdir):
rep = testdir.runitem("""
def test_func():
import os
os.kill(os.getpid(), 15)
""")
assert rep.failed
assert rep.when == "???"
class TestCollectionReports:
def test_collect_result(self, testdir):
col = testdir.getmodulecol("""
def test_func1():
pass
class TestClass:
pass
""")
rep = runner.basic_collect_report(col)
assert not rep.failed
assert not rep.skipped
assert rep.passed assert rep.passed
res = rep.result
assert len(res) == 2
assert res[0].name == "test_func1"
assert res[1].name == "TestClass"
def test_runtest_fails(self, testdir): def test_skip_at_module_scope(self, testdir):
item = testdir.getitem("def test_func(): assert 0") col = testdir.getmodulecol("""
reprec = testdir.getreportrecorder(item.config) import py
setup = SetupState() py.test.skip("hello")
setup.do_fixture_and_runtest(item) def test_func():
event = reprec.popcall(pytest_item_runtest_finished) pass
assert event.excinfo """)
rep = runner.basic_collect_report(col)
assert not rep.failed
assert not rep.passed
assert rep.skipped

View File

@ -1,263 +0,0 @@
import py
from py.__.test.runner import basic_run_report, forked_run_report, basic_collect_report
from py.__.code.excinfo import ReprExceptionInfo
class BaseTests:
def test_funcattr(self, testdir):
ev = testdir.runitem("""
import py
@py.test.mark(xfail="needs refactoring")
def test_func():
raise Exit()
""")
assert ev.keywords['xfail'] == "needs refactoring"
def test_passfunction(self, testdir):
ev = testdir.runitem("""
def test_func():
pass
""")
assert ev.passed
assert not ev.failed
assert ev.shortrepr == "."
assert not hasattr(ev, 'longrepr')
def test_failfunction(self, testdir):
ev = testdir.runitem("""
def test_func():
assert 0
""")
assert not ev.passed
assert not ev.skipped
assert ev.failed
assert ev.when == "execute"
assert isinstance(ev.longrepr, ReprExceptionInfo)
assert str(ev.shortrepr) == "F"
def test_skipfunction(self, testdir):
ev = testdir.runitem("""
import py
def test_func():
py.test.skip("hello")
""")
assert not ev.failed
assert not ev.passed
assert ev.skipped
#assert ev.skipped.when == "execute"
#assert ev.skipped.when == "execute"
#assert ev.skipped == "%sreason == "hello"
#assert ev.skipped.location.lineno == 3
#assert ev.skipped.location.path
#assert not ev.skipped.failurerepr
def test_skip_in_setup_function(self, testdir):
ev = testdir.runitem("""
import py
def setup_function(func):
py.test.skip("hello")
def test_func():
pass
""")
print ev
assert not ev.failed
assert not ev.passed
assert ev.skipped
#assert ev.skipped.reason == "hello"
#assert ev.skipped.location.lineno == 3
#assert ev.skipped.location.lineno == 3
def test_failure_in_setup_function(self, testdir):
ev = testdir.runitem("""
import py
def setup_function(func):
raise ValueError(42)
def test_func():
pass
""")
print ev
assert not ev.skipped
assert not ev.passed
assert ev.failed
assert ev.when == "setup"
def test_failure_in_teardown_function(self, testdir):
ev = testdir.runitem("""
import py
def teardown_function(func):
raise ValueError(42)
def test_func():
pass
""")
print ev
assert not ev.skipped
assert not ev.passed
assert ev.failed
assert ev.when == "teardown"
assert ev.longrepr.reprcrash.lineno == 3
assert ev.longrepr.reprtraceback.reprentries
def test_custom_failure_repr(self, testdir):
testdir.makepyfile(conftest="""
import py
class Function(py.test.collect.Function):
def repr_failure(self, excinfo, outerr):
return "hello"
""")
ev = testdir.runitem("""
import py
def test_func():
assert 0
""")
assert not ev.skipped
assert not ev.passed
assert ev.failed
#assert ev.outcome.when == "execute"
#assert ev.failed.where.lineno == 3
#assert ev.failed.where.path.basename == "test_func.py"
#assert ev.failed.failurerepr == "hello"
def test_failure_in_setup_function_ignores_custom_failure_repr(self, testdir):
testdir.makepyfile(conftest="""
import py
class Function(py.test.collect.Function):
def repr_failure(self, excinfo):
assert 0
""")
ev = testdir.runitem("""
import py
def setup_function(func):
raise ValueError(42)
def test_func():
pass
""")
print ev
assert not ev.skipped
assert not ev.passed
assert ev.failed
#assert ev.outcome.when == "setup"
#assert ev.outcome.where.lineno == 3
#assert ev.outcome.where.path.basename == "test_func.py"
#assert instanace(ev.failed.failurerepr, PythonFailureRepr)
def test_capture_in_func(self, testdir):
ev = testdir.runitem("""
import py
def setup_function(func):
print >>py.std.sys.stderr, "in setup"
def test_func():
print "in function"
assert 0
def teardown_func(func):
print "in teardown"
""")
assert ev.failed
# out, err = ev.failed.outerr
# assert out == ['in function\nin teardown\n']
# assert err == ['in setup\n']
def test_systemexit_does_not_bail_out(self, testdir):
try:
ev = testdir.runitem("""
def test_func():
raise SystemExit(42)
""")
except SystemExit:
py.test.fail("runner did not catch SystemExit")
assert ev.failed
assert ev.when == "execute"
def test_exit_propagates(self, testdir):
from py.__.test.outcome import Exit
try:
testdir.runitem("""
from py.__.test.outcome import Exit
def test_func():
raise Exit()
""")
except Exit:
pass
else:
py.test.fail("did not raise")
class TestExecutionNonForked(BaseTests):
def getrunner(self):
return basic_run_report
def test_keyboardinterrupt_propagates(self, testdir):
from py.__.test.outcome import Exit
try:
testdir.runitem("""
def test_func():
raise KeyboardInterrupt("fake")
""")
except KeyboardInterrupt, e:
pass
else:
py.test.fail("did not raise")
def test_pdb_on_fail(self, testdir):
l = []
ev = testdir.runitem("""
def test_func():
assert 0
""", pdb=l.append)
assert ev.failed
assert ev.when == "execute"
assert len(l) == 1
def test_pdb_on_skip(self, testdir):
l = []
ev = testdir.runitem("""
import py
def test_func():
py.test.skip("hello")
""", pdb=l.append)
assert len(l) == 0
assert ev.skipped
class TestExecutionForked(BaseTests):
def getrunner(self):
if not hasattr(py.std.os, 'fork'):
py.test.skip("no os.fork available")
return forked_run_report
def test_suicide(self, testdir):
ev = testdir.runitem("""
def test_func():
import os
os.kill(os.getpid(), 15)
""")
assert ev.failed
assert ev.when == "???"
class TestCollectionEvent:
def test_collect_result(self, testdir):
col = testdir.getmodulecol("""
def test_func1():
pass
class TestClass:
pass
""")
ev = basic_collect_report(col)
assert not ev.failed
assert not ev.skipped
assert ev.passed
res = ev.result
assert len(res) == 2
assert res[0].name == "test_func1"
assert res[1].name == "TestClass"
def test_skip_at_module_scope(self, testdir):
col = testdir.getmodulecol("""
import py
py.test.skip("hello")
def test_func():
pass
""")
ev = basic_collect_report(col)
assert not ev.failed
assert not ev.passed
assert ev.skipped

View File

@ -22,9 +22,9 @@ class SessionTests:
assert len(skipped) == 0 assert len(skipped) == 0
assert len(passed) == 1 assert len(passed) == 1
assert len(failed) == 3 assert len(failed) == 3
assert failed[0].colitem.name == "test_one_one" assert failed[0].item.name == "test_one_one"
assert failed[1].colitem.name == "test_other" assert failed[1].item.name == "test_other"
assert failed[2].colitem.name == "test_two" assert failed[2].item.name == "test_two"
itemstarted = reprec.getcalls("pytest_itemstart") itemstarted = reprec.getcalls("pytest_itemstart")
assert len(itemstarted) == 4 assert len(itemstarted) == 4
colstarted = reprec.getcalls("pytest_collectstart") colstarted = reprec.getcalls("pytest_collectstart")