diff --git a/py/test/dist/dsession.py b/py/test/dist/dsession.py index 3cf2394f0..d517993da 100644 --- a/py/test/dist/dsession.py +++ b/py/test/dist/dsession.py @@ -25,8 +25,8 @@ class LoopState(object): self.testsfailed = False def pytest_itemtestreport(self, rep): - if rep.colitem in self.dsession.item2nodes: - self.dsession.removeitem(rep.colitem, rep.node) + if rep.item in self.dsession.item2nodes: + self.dsession.removeitem(rep.item, rep.node) if rep.failed: self.testsfailed = True diff --git a/py/test/dist/testing/test_dsession.py b/py/test/dist/testing/test_dsession.py index 0c237b263..0ebce2ffa 100644 --- a/py/test/dist/testing/test_dsession.py +++ b/py/test/dist/testing/test_dsession.py @@ -180,10 +180,10 @@ class TestDSession: session.loop_once(loopstate) assert loopstate.colitems == [item2] # do not reschedule crash item - testrep = reprec.matchreport(names="pytest_itemtestreport") - assert testrep.failed - assert testrep.colitem == item1 - assert str(testrep.longrepr).find("crashed") != -1 + rep = reprec.matchreport(names="pytest_itemtestreport") + assert rep.failed + assert rep.item == item1 + assert str(rep.longrepr).find("crashed") != -1 #assert str(testrep.longrepr).find(node.gateway.spec) != -1 def test_testnodeready_adds_to_available(self, testdir): diff --git a/py/test/dist/testing/test_txnode.py b/py/test/dist/testing/test_txnode.py index c96d972ba..d988a798d 100644 --- a/py/test/dist/testing/test_txnode.py +++ b/py/test/dist/testing/test_txnode.py @@ -115,7 +115,7 @@ class TestMasterSlaveConnection: rep = kwargs['rep'] assert rep.passed print rep - assert rep.colitem == item + assert rep.item == item def test_send_some(self, testdir, mysetup): items = testdir.getitems(""" diff --git a/py/test/looponfail/remote.py b/py/test/looponfail/remote.py index 6046bc531..6ff438e55 100644 --- a/py/test/looponfail/remote.py +++ b/py/test/looponfail/remote.py @@ -150,4 +150,4 @@ def slave_runsession(channel, config, fullwidth, hasmarkup): session.config.hook.pytest_looponfailinfo( failreports=list(failreports), rootdirs=[config.topdir]) - channel.send([x.colitem._totrail() for x in failreports]) + channel.send([rep.getnode()._totrail() for rep in failreports]) diff --git a/py/test/plugin/api.py b/py/test/plugin/api.py index eceb1d7a6..6739d38f1 100644 --- a/py/test/plugin/api.py +++ b/py/test/plugin/api.py @@ -84,10 +84,11 @@ class PluginHooks: def pytest_itemtestreport(self, rep): """ test has been run. """ + # XXX pytest_runner reports def pytest_item_runtest_finished(self, item, excinfo, outerr): """ test has been run. """ - def pytest_itemsetupreport(self, rep): + def pytest_itemfixturereport(self, rep): """ a report on running a fixture function. """ # ------------------------------------------------------------------------------ diff --git a/py/test/plugin/pytest__pytest.py b/py/test/plugin/pytest__pytest.py index 711d1053a..5e720eb01 100644 --- a/py/test/plugin/pytest__pytest.py +++ b/py/test/plugin/pytest__pytest.py @@ -91,7 +91,7 @@ class HookRecorder: if call._name == name: del self.calls[i] 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): l = self.getcalls(name) diff --git a/py/test/plugin/pytest_doctest.py b/py/test/plugin/pytest_doctest.py index a39e53771..ddd22f1fa 100644 --- a/py/test/plugin/pytest_doctest.py +++ b/py/test/plugin/pytest_doctest.py @@ -141,7 +141,6 @@ class TestDoctests: reprec.assertoutcome(failed=1) def test_txtfile_failing(self, testdir): - testdir.plugins.append("doctest") p = testdir.maketxtfile(""" >>> i = 0 >>> i + 1 diff --git a/py/test/plugin/pytest_pytester.py b/py/test/plugin/pytest_pytester.py index 468bb2175..23406907a 100644 --- a/py/test/plugin/pytest_pytester.py +++ b/py/test/plugin/pytest_pytester.py @@ -305,6 +305,9 @@ class ReportRecorder(object): def getcall(self, name): return self.hookrecorder.getcall(name) + def popcall(self, name): + return self.hookrecorder.popcall(name) + def getcalls(self, names): """ return list of ParsedCall instances matching the given eventname. """ return self.hookrecorder.getcalls(names) @@ -318,7 +321,8 @@ class ReportRecorder(object): """ return a testreport whose dotted import path matches """ l = [] 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) if not l: raise ValueError("could not find test report matching %r: no test reports at all!" % diff --git a/py/test/plugin/pytest_resultlog.py b/py/test/plugin/pytest_resultlog.py index 2a8ab2dbe..12c9f2a1e 100644 --- a/py/test/plugin/pytest_resultlog.py +++ b/py/test/plugin/pytest_resultlog.py @@ -20,7 +20,7 @@ def pytest_unconfigure(config): resultlog = getattr(config, '_resultlog', None) if resultlog: resultlog.logfile.close() - del config.resultlog + del config._resultlog config.pluginmanager.unregister(resultlog) def generic_path(item): @@ -55,8 +55,8 @@ class ResultLog(object): for line in longrepr.splitlines(): print >>self.logfile, " %s" % line - def log_outcome(self, event, shortrepr, longrepr): - testpath = generic_path(event.colitem) + def log_outcome(self, node, shortrepr, longrepr): + testpath = generic_path(node) self.write_log_entry(testpath, shortrepr, longrepr) def pytest_itemtestreport(self, rep): @@ -67,7 +67,7 @@ class ResultLog(object): longrepr = str(rep.longrepr) elif rep.skipped: longrepr = str(rep.longrepr.reprcrash.message) - self.log_outcome(rep, code, longrepr) + self.log_outcome(rep.item, code, longrepr) def pytest_collectreport(self, rep): if not rep.passed: @@ -77,7 +77,7 @@ class ResultLog(object): assert rep.skipped code = "S" longrepr = str(rep.longrepr.reprcrash) - self.log_outcome(rep, code, longrepr) + self.log_outcome(rep.collector, code, longrepr) def pytest_internalerror(self, excrepr): path = excrepr.reprcrash.path diff --git a/py/test/plugin/pytest_runner.py b/py/test/plugin/pytest_runner.py index 1faecf130..1fb196d5e 100644 --- a/py/test/plugin/pytest_runner.py +++ b/py/test/plugin/pytest_runner.py @@ -1,31 +1,39 @@ import py from py.__.test.outcome import Skipped +from py.__.test.runner import SetupState -class RunnerPlugin: - def pytest_configure(self, config): - config._setupstate = SetupState() +py.test.skip("remove me") - def pytest_unconfigure(self, config): - config._setupstate.teardown_all() +def pytest_configure(config): + config._setupstate = SetupState() - def pytest_item_setup_and_runtest(self, item): - setupstate = item.config._setupstate - call = item.config.guardedcall(lambda: setupstate.prepare(item)) - if call.excinfo: - rep = ItemSetupReport(item, call.excinfo, call.outerr) - item.config.hook.pytest_itemsetupreport(rep=rep) - else: - call = item.config.guardedcall(lambda: item.runtest()) - item.config.hook.pytest_item_runtest_finished( - 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_unconfigure(config): + config._setupstate.teardown_all() - def pytest_collector_collect(self, collector): - call = item.config.guardedcall(lambda x: collector._memocollect()) - return CollectReport(collector, res, excinfo, outerr) +def pytest_item_setup_and_runtest(item): + setupstate = item.config._setupstate + + # setup (and implied teardown of previous items) + call = item.config.guardedcall(lambda: setupstate.prepare(item)) + if call.excinfo: + rep = ItemTestReport(item, call.excinfo, call.outerr) + item.config.hook.pytest_itemfixturereport(rep=rep) + return + + # runtest + call = item.config.guardedcall(lambda: item.runtest()) + item.config.hook.pytest_item_runtest_finished( + item=item, excinfo=call.excinfo, outerr=call.outerr) + + # 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()) + return CollectReport(collector, res, excinfo, outerr) class BaseReport(object): def __repr__(self): @@ -97,7 +105,7 @@ class CollectReport(BaseReport): else: self.failed = True -class ItemSetupReport(BaseReport): +class ItemFixtureReport(BaseReport): failed = passed = skipped = False def __init__(self, item, excinfo=None, outerr=None): self.item = item @@ -111,33 +119,6 @@ class ItemSetupReport(BaseReport): self.failed = True 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: def test_pytest_item_setup_and_runtest(self, testdir): item = testdir.getitem("""def test_func(): pass""") - plugin = RunnerPlugin() - plugin.pytest_configure(item.config) + pytest_configure(item.config) reprec = testdir.getreportrecorder(item) - plugin.pytest_item_setup_and_runtest(item) + pytest_item_setup_and_runtest(item) rep = reprec.getcall("pytest_itemtestreport").rep assert rep.passed - + class TestSetupEvents: - disabled = True - - def test_setup_runtest_ok(self, testdir): - reprec = testdir.inline_runsource(""" + 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, runfunc): + reprec = runfunc(""" def setup_module(mod): pass def test_func(): pass """) - assert not reprec.getcalls(pytest_itemsetupreport) + assert not reprec.getcalls("pytest_itemfixturereport") - def test_setup_fails(self, testdir): - reprec = testdir.inline_runsource(""" + def test_setup_fails(self, runfunc): + reprec = runfunc(""" def setup_module(mod): print "world" raise ValueError(42) def test_func(): pass """) - rep = reprec.popcall(pytest_itemsetupreport).rep + rep = reprec.popcall("pytest_itemfixturereport").rep assert rep.failed 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): - reprec = testdir.inline_runsource(""" + def test_teardown_fails(self, runfunc): + reprec = runfunc(""" def test_func(): pass def teardown_function(func): print "13" raise ValueError(25) """) - rep = reprec.popcall(pytest_itemsetupreport).rep + rep = reprec.popcall("pytest_itemfixturereport").rep assert rep.failed - assert rep.item == item + assert rep.item.name == "test_func" assert not rep.passed assert "13" in rep.outerr[0] assert "25" in str(rep.excrepr) - def test_setup_skips(self, testdir): - reprec = testdir.inline_runsource(""" + def test_setup_skips(self, runfunc): + reprec = runfunc(""" import py def setup_module(mod): py.test.skip("17") def test_func(): pass """) - rep = reprec.popcall(pytest_itemsetupreport) + rep = reprec.popcall("pytest_itemfixturereport").rep assert not rep.failed assert rep.skipped assert rep.excrepr assert "17" in str(rep.excrepr) - - diff --git a/py/test/plugin/pytest_terminal.py b/py/test/plugin/pytest_terminal.py index 4598024ae..b53036a7f 100644 --- a/py/test/plugin/pytest_terminal.py +++ b/py/test/plugin/pytest_terminal.py @@ -162,7 +162,7 @@ class TerminalReporter: self.write_fspath_result(fspath, "") def pytest_itemtestreport(self, rep): - fspath = rep.colitem.fspath + fspath = rep.item.fspath cat, letter, word = self.getcategoryletterword(rep) if isinstance(word, tuple): word, markup = word @@ -170,10 +170,10 @@ class TerminalReporter: markup = {} self.stats.setdefault(cat, []).append(rep) 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) else: - line = self._reportinfoline(rep.colitem) + line = self._reportinfoline(rep.item) if not hasattr(rep, 'node'): self.write_ensure_prefix(line, word, **markup) else: @@ -189,10 +189,10 @@ class TerminalReporter: if rep.failed: self.stats.setdefault("failed", []).append(rep) msg = rep.longrepr.reprcrash.message - self.write_fspath_result(rep.colitem.fspath, "F") + self.write_fspath_result(rep.collector.fspath, "F") elif rep.skipped: 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): self.write_sep("=", "test session starts", bold=True) @@ -268,10 +268,10 @@ class TerminalReporter: return line % locals() + " " def _getfailureheadline(self, rep): - if isinstance(rep.colitem, py.test.collect.Collector): - return str(rep.colitem.fspath) + if hasattr(rep, "collector"): + return str(rep.collector.fspath) else: - fspath, lineno, msg = self._getreportinfo(rep.colitem) + fspath, lineno, msg = self._getreportinfo(rep.item) return msg def _getreportinfo(self, item): diff --git a/py/test/plugin/pytest_xfail.py b/py/test/plugin/pytest_xfail.py index 6024eb673..8bbd29c5b 100644 --- a/py/test/plugin/pytest_xfail.py +++ b/py/test/plugin/pytest_xfail.py @@ -40,7 +40,7 @@ def pytest_terminal_summary(terminalreporter): entry = event.longrepr.reprcrash key = entry.path, entry.lineno, entry.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: " %(modpath, entry.path, entry.lineno)) @@ -48,7 +48,7 @@ def pytest_terminal_summary(terminalreporter): if xpassed: tr.write_sep("_", "UNEXPECTEDLY PASSING TESTS") for event in xpassed: - tr._tw.line("%s: xpassed" %(event.colitem,)) + tr._tw.line("%s: xpassed" %(event.item,)) # =============================================================================== # diff --git a/py/test/runner.py b/py/test/runner.py index 7b399e055..dada94c90 100644 --- a/py/test/runner.py +++ b/py/test/runner.py @@ -19,13 +19,13 @@ def basic_run_report(item, pdb=None): when = "setup" item.config._setupstate.prepare(item) try: - when = "execute" + when = "runtest" if not item._deprecated_testexecution(): item.runtest() finally: when = "teardown" item.config._setupstate.teardown_exact(item) - when = "execute" + when = "runtest" finally: outerr = capture.reset() except KeyboardInterrupt: @@ -41,18 +41,13 @@ def basic_run_report(item, pdb=None): return testrep def basic_collect_report(collector): - excinfo = res = None - try: - capture = collector.config._getcapture() - try: - res = collector._memocollect() - finally: - outerr = capture.reset() - except KeyboardInterrupt: - raise - except: - excinfo = py.code.ExceptionInfo() - return CollectReport(collector, res, excinfo, outerr) + call = collector.config.guardedcall( + lambda: collector._memocollect() + ) + result = None + if not call.excinfo: + result = call.result + return CollectReport(collector, result, call.excinfo, call.outerr) def forked_run_report(item, pdb=None): EXITSTATUS_TESTEXIT = 4 @@ -99,11 +94,10 @@ class BaseReport(object): class ItemTestReport(BaseReport): failed = passed = skipped = False - # XXX rename colitem to item here - def __init__(self, colitem, excinfo=None, when=None, outerr=None): - self.colitem = colitem - if colitem and when != "setup": - self.keywords = colitem.readkeywords() + def __init__(self, item, excinfo=None, when=None, outerr=None): + self.item = item + if item and when != "setup": + self.keywords = item.readkeywords() else: # if we fail during setup it might mean # we are not able to access the underlying object @@ -123,50 +117,40 @@ class ItemTestReport(BaseReport): elif excinfo.errisinstance(Skipped): self.skipped = True shortrepr = "s" - longrepr = self.colitem._repr_failure_py(excinfo, outerr) + longrepr = self.item._repr_failure_py(excinfo, outerr) else: self.failed = True - shortrepr = self.colitem.shortfailurerepr - if self.when == "execute": - longrepr = self.colitem.repr_failure(excinfo, outerr) + shortrepr = self.item.shortfailurerepr + if self.when == "runtest": + longrepr = self.item.repr_failure(excinfo, outerr) 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() self.shortrepr = shortrepr self.longrepr = longrepr - + + def getnode(self): + return self.item class CollectReport(BaseReport): skipped = failed = passed = False - def __init__(self, colitem, result, excinfo=None, outerr=None): - # XXX rename to collector - self.colitem = colitem + def __init__(self, collector, result, excinfo=None, outerr=None): + self.collector = collector if not excinfo: self.passed = True self.result = result else: 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): self.skipped = True self.reason = str(excinfo.value) else: self.failed = True -class ItemSetupReport(BaseReport): - failed = passed = skipped = False - 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, []) + def getnode(self): + return self.collector class SetupState(object): """ shared state for setting up/tearing down test items or collectors. """ diff --git a/py/test/testing/test_collect.py b/py/test/testing/test_collect.py index 8b32349d2..d7c1b0e65 100644 --- a/py/test/testing/test_collect.py +++ b/py/test/testing/test_collect.py @@ -176,7 +176,7 @@ class TestCollectPluginHooks: assert "world" in wascalled # make sure the directories do not get double-appended 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 class TestCustomConftests: @@ -214,8 +214,8 @@ class TestCustomConftests: """) testdir.mkdir("hello") 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 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 diff --git a/py/test/testing/test_genitems.py b/py/test/testing/test_genitems.py index 2ebfbe302..f917e5386 100644 --- a/py/test/testing/test_genitems.py +++ b/py/test/testing/test_genitems.py @@ -73,7 +73,7 @@ class TestKeywordSelection: reprec = testdir.inline_run("-s", "-k", keyword, file_test) passed, skipped, failed = reprec.listoutcomes() assert len(failed) == 1 - assert failed[0].colitem.name == name + assert failed[0].item.name == name assert len(reprec.getcalls('pytest_deselected')) == 1 for keyword in ['test_one', 'est_on']: @@ -101,7 +101,7 @@ class TestKeywordSelection: print "keyword", repr(keyword) passed, skipped, failed = reprec.listoutcomes() assert len(passed) == 1 - assert passed[0].colitem.name == "test_2" + assert passed[0].item.name == "test_2" dlist = reprec.getcalls("pytest_deselected") assert len(dlist) == 1 assert dlist[0].items[0].name == 'test_1' diff --git a/py/test/testing/test_runner.py b/py/test/testing/test_runner.py index 9bc8638c1..41bdc1433 100644 --- a/py/test/testing/test_runner.py +++ b/py/test/testing/test_runner.py @@ -1,9 +1,10 @@ - -from py.__.test.config import SetupState +import py +from py.__.test import runner +from py.__.code.excinfo import ReprExceptionInfo class TestSetupState: def test_setup(self, testdir): - ss = SetupState() + ss = runner.SetupState() item = testdir.getitem("def test_func(): pass") l = [1] ss.prepare(item) @@ -14,7 +15,7 @@ class TestSetupState: def test_setup_scope_None(self, testdir): item = testdir.getitem("def test_func(): pass") - ss = SetupState() + ss = runner.SetupState() l = [1] ss.prepare(item) ss.addfinalizer(l.pop, colitem=None) @@ -26,93 +27,263 @@ class TestSetupState: ss.teardown_all() assert not l -class TestSetupStateFunctional: - disabled = True - def test_setup_ok(self, testdir): - item = testdir.getitem(""" - def setup_module(mod): - pass + +class BaseFunctionalTests: + def test_funcattr(self, testdir): + rep = testdir.runitem(""" + import py + @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(): pass """) - reprec = testdir.getreportrecorder(item.config) - setup = SetupState() - res = setup.do_setup(item) - assert res + assert rep.passed + assert not rep.failed + assert rep.shortrepr == "." + assert not hasattr(rep, 'longrepr') + + def test_failfunction(self, testdir): + rep = testdir.runitem(""" + def test_func(): + 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_setup_fails(self, testdir): - item = testdir.getitem(""" - def setup_module(mod): - print "world" + 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) def test_func(): pass """) - reprec = testdir.getreportrecorder(item.config) - setup = SetupState() - res = setup.do_setup(item) - assert not res - rep = reprec.popcall(pytest_itemsetupreport).rep - assert rep.failed - 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 + print rep + assert not rep.skipped + assert not rep.passed assert rep.failed - assert not rep.passed - assert "13" in rep.outerr[0] - assert "25" in str(rep.excrepr) + assert rep.when == "setup" - def test_setupitem_skips(self, testdir): - item = testdir.getitem(""" + def test_failure_in_teardown_function(self, testdir): + rep = testdir.runitem(""" import py - def setup_module(mod): - py.test.skip("17") + def teardown_function(func): + raise ValueError(42) def test_func(): pass """) - reprec = testdir.getreportrecorder(item.config) - setup = SetupState() - setup.do_setup(item) - rep = reprec.popcall(pytest_itemsetupreport).rep - assert not rep.failed - assert rep.skipped - assert rep.excrepr - assert "17" in str(rep.excrepr) + print rep + assert not rep.skipped + assert not rep.passed + assert rep.failed + assert rep.when == "teardown" + assert rep.longrepr.reprcrash.lineno == 3 + assert rep.longrepr.reprtraceback.reprentries - def test_runtest_ok(self, testdir): - item = testdir.getitem("def test_func(): pass") - reprec = testdir.getreportrecorder(item.config) - setup = SetupState() - setup.do_fixture_and_runtest(item) - rep = reprec.popcall(pytest_itemtestreport).rep - assert rep.passed + 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_runtest_fails(self, testdir): - item = testdir.getitem("def test_func(): assert 0") - reprec = testdir.getreportrecorder(item.config) - setup = SetupState() - setup.do_fixture_and_runtest(item) - event = reprec.popcall(pytest_item_runtest_finished) - assert event.excinfo + 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 + +class TestExecutionForked(BaseFunctionalTests): + def getrunner(self): + if not hasattr(py.std.os, 'fork'): + py.test.skip("no os.fork available") + return runner.forked_run_report + + 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 + res = rep.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 + """) + rep = runner.basic_collect_report(col) + assert not rep.failed + assert not rep.passed + assert rep.skipped + diff --git a/py/test/testing/test_runner_functional.py b/py/test/testing/test_runner_functional.py deleted file mode 100644 index 478e4f651..000000000 --- a/py/test/testing/test_runner_functional.py +++ /dev/null @@ -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 - - diff --git a/py/test/testing/test_session.py b/py/test/testing/test_session.py index 30446b3d8..042c62976 100644 --- a/py/test/testing/test_session.py +++ b/py/test/testing/test_session.py @@ -22,9 +22,9 @@ class SessionTests: assert len(skipped) == 0 assert len(passed) == 1 assert len(failed) == 3 - assert failed[0].colitem.name == "test_one_one" - assert failed[1].colitem.name == "test_other" - assert failed[2].colitem.name == "test_two" + assert failed[0].item.name == "test_one_one" + assert failed[1].item.name == "test_other" + assert failed[2].item.name == "test_two" itemstarted = reprec.getcalls("pytest_itemstart") assert len(itemstarted) == 4 colstarted = reprec.getcalls("pytest_collectstart")