From a37c32783dda01d953c40351a49a97770c3f13f0 Mon Sep 17 00:00:00 2001 From: hpk Date: Tue, 7 Apr 2009 12:48:57 +0200 Subject: [PATCH] [svn r63785] further renaming, streamlining the testing machinery and helpers. --HG-- branch : trunk --- py/test/dist/testing/test_dsession.py | 10 +-- py/test/dist/testing/test_nodemanage.py | 6 +- py/test/plugin/api.py | 3 + py/test/plugin/pytest_doctest.py | 18 ++--- py/test/plugin/pytest_iocapture.py | 7 +- py/test/plugin/pytest_pytester.py | 89 +++++++++++------------- py/test/plugin/pytest_unittest.py | 6 +- py/test/runner.py | 3 + py/test/testing/test_collect.py | 10 +-- py/test/testing/test_pytestplugin.py | 11 ++- py/test/testing/test_session.py | 16 ++--- py/test/testing/test_setup_functional.py | 6 +- 12 files changed, 86 insertions(+), 99 deletions(-) diff --git a/py/test/dist/testing/test_dsession.py b/py/test/dist/testing/test_dsession.py index 084c14554..010a28447 100644 --- a/py/test/dist/testing/test_dsession.py +++ b/py/test/dist/testing/test_dsession.py @@ -181,7 +181,7 @@ class TestDSession: session.loop_once(loopstate) assert loopstate.colitems == [item2] # do not reschedule crash item - testrep = evrec.getfirstnamed("itemtestreport") + testrep = evrec.matchreport(names="itemtestreport") assert testrep.failed assert testrep.colitem == item1 assert str(testrep.longrepr).find("crashed") != -1 @@ -204,9 +204,9 @@ class TestDSession: session = DSession(item.config) evrec = EventRecorder(session.bus) - session.queueevent("NOPevent", 42) + session.queueevent("NOP", 42) session.loop_once(session._initloopstate([])) - assert evrec.getfirstnamed('NOPevent') + assert evrec.getcall('NOP') def runthrough(self, item): session = DSession(item.config) @@ -274,10 +274,10 @@ class TestDSession: evrec = EventRecorder(session.bus) session.queueevent("itemtestreport", run(item, node)) session.loop_once(loopstate) - assert not evrec.getfirstnamed("testnodedown") + assert not evrec.getcalls("testnodedown") session.queueevent("testnodedown", node, None) session.loop_once(loopstate) - assert evrec.getfirstnamed('testnodedown') == node + assert evrec.getcall('testnodedown').node == node def test_filteritems(self, testdir, EventRecorder): modcol = testdir.getmodulecol(""" diff --git a/py/test/dist/testing/test_nodemanage.py b/py/test/dist/testing/test_nodemanage.py index 8cb801032..eb63d3525 100644 --- a/py/test/dist/testing/test_nodemanage.py +++ b/py/test/dist/testing/test_nodemanage.py @@ -104,11 +104,11 @@ class TestNodeManager: config = py.test.config._reparse([source, '--debug']) assert config.option.debug nodemanager = NodeManager(config, specs) - evrec = EventRecorder(config.bus, debug=True) + sorter = EventRecorder(config.bus, debug=True) nodemanager.setup_nodes(putevent=[].append) for spec in nodemanager.gwmanager.specs: - l = evrec.getnamed("trace") - print evrec.events + l = sorter.getcalls("trace") + print sorter.events assert l nodemanager.teardown_nodes() diff --git a/py/test/plugin/api.py b/py/test/plugin/api.py index 0918556ec..6741289f9 100644 --- a/py/test/plugin/api.py +++ b/py/test/plugin/api.py @@ -61,6 +61,9 @@ class Events: def pyevent(self, eventname, args, kwargs): """ generically called for each notification event. """ + def pyevent__NOP(self, *args, **kwargs): + """ the no-operation call. """ + def pyevent__gateway_init(self, gateway): """ called after a gateway has been initialized. """ diff --git a/py/test/plugin/pytest_doctest.py b/py/test/plugin/pytest_doctest.py index fed1c7f94..f7e5bec29 100644 --- a/py/test/plugin/pytest_doctest.py +++ b/py/test/plugin/pytest_doctest.py @@ -108,9 +108,8 @@ class TestDoctests: >>> x == 1 False """) - events = testdir.inline_run(p) - ev, = events.getnamed("itemtestreport") - assert ev.failed + sorter = testdir.inline_run(p) + sorter.assertoutcome(failed=1) def test_doctest_unexpected_exception(self, testdir): from py.__.test.outcome import Failed @@ -123,11 +122,9 @@ class TestDoctests: 2 """) sorter = testdir.inline_run(p) - events = sorter.getnamed("itemtestreport") - assert len(events) == 1 - ev, = events - assert ev.failed - assert ev.longrepr + call = sorter.getcall("itemtestreport") + assert call.rep.failed + assert call.rep.longrepr # XXX #testitem, = items #excinfo = py.test.raises(Failed, "testitem.runtest()") @@ -144,9 +141,8 @@ class TestDoctests: ''' """) - events = testdir.inline_run(p, "--doctest-modules") - ev, = events.getnamed("itemtestreport") - assert ev.failed + sorter = testdir.inline_run(p, "--doctest-modules") + sorter.assertoutcome(failed=1) def test_txtfile_failing(self, testdir): testdir.plugins.append('pytest_doctest') diff --git a/py/test/plugin/pytest_iocapture.py b/py/test/plugin/pytest_iocapture.py index 164ce92aa..e7df7190a 100644 --- a/py/test/plugin/pytest_iocapture.py +++ b/py/test/plugin/pytest_iocapture.py @@ -37,8 +37,7 @@ class TestCapture: out, err = stdcapture.reset() assert out.startswith("42") """) - ev, = evrec.getnamed("itemtestreport") - assert ev.passed + evrec.assertoutcome(passed=1) def test_stdfd_functional(self, testdir): testdir.plugins.append(IocapturePlugin()) @@ -49,6 +48,4 @@ class TestCapture: out, err = stdcapturefd.reset() assert out.startswith("42") """) - ev, = evrec.getnamed("itemtestreport") - assert ev.passed - + evrec.assertoutcome(passed=1) diff --git a/py/test/plugin/pytest_pytester.py b/py/test/plugin/pytest_pytester.py index c229efe31..784795587 100644 --- a/py/test/plugin/pytest_pytester.py +++ b/py/test/plugin/pytest_pytester.py @@ -296,12 +296,19 @@ class EventRecorder(object): return eventparser(*event.args, **event.kwargs) raise KeyError("popevent: %r not found in %r" %(name, self.events)) - def getcalls(self, eventname): + def getcall(self, name): + l = self.getcalls(name) + assert len(l) == 1, (name, l) + return l[0] + + def getcalls(self, *names): """ return list of ParsedCall instances matching the given eventname. """ - method = self._getcallparser(eventname) + if len(names) == 1 and isinstance(names, str): + names = names.split() l = [] for event in self.events: - if event.name == eventname: + if event.name in names: + method = self._getcallparser(event.name) pevent = method(*event.args, **event.kwargs) l.append(pevent) return l @@ -318,35 +325,34 @@ class EventRecorder(object): exec code return locals()[mname] - def get(self, cls): + # functionality for test reports + + def getreports(self, names="itemtestreport collectionreport"): + names = names.split() l = [] - for event in self.events: - try: - value = event.args[0] - except IndexError: - continue - else: - if isinstance(value, cls): - l.append(value) + for call in self.getcalls(*names): + l.append(call.rep) return l - def getnamed(self, *names): + def matchreport(self, inamepart="", names="itemtestreport collectionreport"): + """ return a testreport whose dotted import path matches """ l = [] - for event in self.events: - if event.name in names: - l.append(event.args[0]) - return l - - def getfirstnamed(self, name): - for event in self.events: - if event.name == name: - return event.args[0] + for rep in self.getreports(names=names): + if not inamepart or inamepart in rep.colitem.listnames(): + l.append(rep) + if not l: + raise ValueError("could not find test report matching %r: no test reports at all!" % + (inamepart,)) + if len(l) > 1: + raise ValueError("found more than one testreport matching %r: %s" %( + inamepart, l)) + return l[0] def getfailures(self, names='itemtestreport collectionreport'): l = [] - for ev in self.getnamed(*names.split()): - if ev.failed: - l.append(ev) + for call in self.getcalls(*names.split()): + if call.rep.failed: + l.append(call.rep) return l def getfailedcollections(self): @@ -356,13 +362,13 @@ class EventRecorder(object): passed = [] skipped = [] failed = [] - for ev in self.getnamed('itemtestreport'): # , 'collectionreport'): - if ev.passed: - passed.append(ev) - elif ev.skipped: - skipped.append(ev) - elif ev.failed: - failed.append(ev) + for rep in self.getreports("itemtestreport"): + if rep.passed: + passed.append(rep) + elif rep.skipped: + skipped.append(rep) + elif rep.failed: + failed.append(rep) return passed, skipped, failed def countoutcomes(self): @@ -374,21 +380,6 @@ class EventRecorder(object): assert skipped == len(realskipped) assert failed == len(realfailed) - def getreport(self, inamepart): - """ return a testreport whose dotted import path matches """ - __tracebackhide__ = True - l = [] - for rep in self.get(runner.ItemTestReport): - if inamepart in rep.colitem.listnames(): - l.append(rep) - if not l: - raise ValueError("could not find test report matching %r: no test reports at all!" % - (inamepart,)) - if len(l) > 1: - raise ValueError("found more than one testreport matching %r: %s" %( - inamepart, l)) - return l[0] - def clear(self): self.events[:] = [] @@ -407,9 +398,7 @@ def test_eventrecorder(): bus.notify("itemtestreport", rep) failures = recorder.getfailures() assert failures == [rep] - failures = recorder.get(runner.ItemTestReport) - assert failures == [rep] - failures = recorder.getnamed("itemtestreport") + failures = recorder.getfailures() assert failures == [rep] rep = runner.ItemTestReport(None, None) diff --git a/py/test/plugin/pytest_unittest.py b/py/test/plugin/pytest_unittest.py index 000399825..109c3ba0b 100644 --- a/py/test/plugin/pytest_unittest.py +++ b/py/test/plugin/pytest_unittest.py @@ -84,8 +84,8 @@ def test_simple_unittest(testdir): self.assertEquals('foo', 'bar') """) sorter = testdir.inline_run(testpath) - assert sorter.getreport("testpassing").passed - assert sorter.getreport("test_failing").failed + assert sorter.matchreport("testpassing").passed + assert sorter.matchreport("test_failing").failed def test_setup(testdir): testpath = testdir.makepyfile(test_two=""" @@ -98,7 +98,7 @@ def test_setup(testdir): self.assertEquals(1, self.foo) """) sorter = testdir.inline_run(testpath) - rep = sorter.getreport("test_setUp") + rep = sorter.matchreport("test_setUp") assert rep.passed def test_teardown(testdir): diff --git a/py/test/runner.py b/py/test/runner.py index 747d50e09..0f8bdfbd0 100644 --- a/py/test/runner.py +++ b/py/test/runner.py @@ -98,6 +98,7 @@ class BaseReport(object): else: out.line(str(longrepr)) +# XXX rename to runtest() report ? class ItemTestReport(BaseReport): """ Test Execution Report. """ failed = passed = skipped = False @@ -138,11 +139,13 @@ class ItemTestReport(BaseReport): self.longrepr = longrepr +# XXX rename to collectreport class CollectionReport(BaseReport): """ Collection Report. """ skipped = failed = passed = False def __init__(self, colitem, result, excinfo=None, outerr=None): + # XXX rename to collector self.colitem = colitem if not excinfo: self.passed = True diff --git a/py/test/testing/test_collect.py b/py/test/testing/test_collect.py index 429c03f16..1b515e492 100644 --- a/py/test/testing/test_collect.py +++ b/py/test/testing/test_collect.py @@ -163,11 +163,11 @@ class TestCollectPluginHooks: testdir.plugins.append(Plugin()) testdir.mkdir("hello") testdir.mkdir("world") - evrec = testdir.inline_run() + sorter = testdir.inline_run() assert "hello" in wascalled assert "world" in wascalled # make sure the directories do not get double-appended - colreports = evrec.getnamed("collectionreport") + colreports = sorter.getreports(names="collectionreport") names = [rep.colitem.name for rep in colreports] assert names.count("hello") == 1 @@ -206,11 +206,11 @@ class TestCustomConftests: return parent.config.getvalue("XX") """) testdir.mkdir("hello") - evrec = testdir.inline_run(testdir.tmpdir) - names = [rep.colitem.name for rep in evrec.getnamed("collectionreport")] + sorter = testdir.inline_run(testdir.tmpdir) + names = [rep.colitem.name for rep in sorter.getreports("collectionreport")] assert 'hello' not in names evrec = testdir.inline_run(testdir.tmpdir, "--XX") - names = [rep.colitem.name for rep in evrec.getnamed("collectionreport")] + names = [rep.colitem.name for rep in evrec.getreports("collectionreport")] assert 'hello' in names class TestCollectorReprs: diff --git a/py/test/testing/test_pytestplugin.py b/py/test/testing/test_pytestplugin.py index 90fcc0f37..8b04dd263 100644 --- a/py/test/testing/test_pytestplugin.py +++ b/py/test/testing/test_pytestplugin.py @@ -74,18 +74,17 @@ class TestBootstrapping: mod.pytest_plugins = "pytest_a" aplugin = testdir.makepyfile(pytest_a="""class APlugin: pass""") plugins = PytestPlugins() - evrec = EventRecorder(plugins) + sorter = EventRecorder(plugins) #syspath.prepend(aplugin.dirpath()) py.std.sys.path.insert(0, str(aplugin.dirpath())) plugins.consider_module(mod) - evlist = evrec.getnamed("plugin_registered") - assert len(evlist) == 1 - assert evlist[0].__class__.__name__ == "APlugin" + call = sorter.getcall("plugin_registered") + assert call.plugin.__class__.__name__ == "APlugin" # check that it is not registered twice plugins.consider_module(mod) - evlist = evrec.getnamed("plugin_registered") - assert len(evlist) == 1 + l = sorter.getcalls("plugin_registered") + assert len(l) == 1 def test_consider_conftest(self, testdir): pp = PytestPlugins() diff --git a/py/test/testing/test_session.py b/py/test/testing/test_session.py index 8e5071e02..2d85a13c9 100644 --- a/py/test/testing/test_session.py +++ b/py/test/testing/test_session.py @@ -130,9 +130,9 @@ class SessionTests: def test_one(): pass """) sorter = testdir.inline_run(testdir.tmpdir) - skips = sorter.getnamed("collectionreport") - assert len(skips) == 1 - assert skips[0].skipped + reports = sorter.getreports("collectionreport") + assert len(reports) == 1 + assert reports[0].skipped class TestNewSession(SessionTests): def test_pdb_run(self, testdir, monkeypatch): @@ -146,7 +146,7 @@ class TestNewSession(SessionTests): l.append(args) monkeypatch.setattr(py.__.test.custompdb, 'post_mortem', mypdb) sorter = testdir.inline_run('--pdb', tfile) - rep = sorter.getreport("test_usepdb") + rep = sorter.matchreport("test_usepdb") assert rep.failed assert len(l) == 1 tb = py.code.Traceback(l[0][0]) @@ -199,11 +199,11 @@ class TestNewSession(SessionTests): ) sorter = testdir.inline_run('--collectonly', p.dirpath()) - itemstarted = sorter.getnamed("itemstart") + itemstarted = sorter.getcalls("itemstart") assert len(itemstarted) == 3 - assert not sorter.getnamed("itemtestreport") + assert not sorter.getreports("itemtestreport") started = sorter.getcalls("collectionstart") - finished = sorter.getnamed("collectionreport") + finished = sorter.getreports("collectionreport") assert len(started) == len(finished) assert len(started) == 8 colfail = [x for x in finished if x.failed] @@ -215,7 +215,7 @@ class TestNewSession(SessionTests): testdir.makepyfile(__init__="") testdir.makepyfile(test_one="xxxx", test_two="yyyy") sorter = testdir.inline_run("-x", testdir.tmpdir) - finished = sorter.getnamed("collectionreport") + finished = sorter.getreports("collectionreport") colfail = [x for x in finished if x.failed] assert len(colfail) == 1 diff --git a/py/test/testing/test_setup_functional.py b/py/test/testing/test_setup_functional.py index 838bac64e..e0d0a2736 100644 --- a/py/test/testing/test_setup_functional.py +++ b/py/test/testing/test_setup_functional.py @@ -27,9 +27,9 @@ def test_module_and_function_setup(testdir): assert modlevel[0] == 42 assert not hasattr(test_modlevel, 'answer') """) - rep = sorter.getreport("test_modlevel") + rep = sorter.matchreport("test_modlevel") assert rep.passed - rep = sorter.getreport("test_module") + rep = sorter.matchreport("test_module") assert rep.passed def test_class_setup(testdir): @@ -118,7 +118,7 @@ def test_func_generator_setup(testdir): yield check assert x == [1] """) - rep = sorter.getreport("test_one") + rep = sorter.matchreport("test_one", names="itemtestreport") assert rep.passed def test_method_setup_uses_fresh_instances(testdir):