[py-svn] r61721 - py/branch/pytestplugin/py/test/plugin
hpk at codespeak.net
hpk at codespeak.net
Wed Feb 11 13:19:12 CET 2009
Author: hpk
Date: Wed Feb 11 13:19:12 2009
New Revision: 61721
Added:
py/branch/pytestplugin/py/test/plugin/pytest_unittest.py (contents, props changed)
Modified:
py/branch/pytestplugin/py/test/plugin/pytest_plugintester.py
py/branch/pytestplugin/py/test/plugin/pytest_pytester.py
Log:
port unittest-support conftest to become a plugin
add a bit of plugin testing support code
Modified: py/branch/pytestplugin/py/test/plugin/pytest_plugintester.py
==============================================================================
--- py/branch/pytestplugin/py/test/plugin/pytest_plugintester.py (original)
+++ py/branch/pytestplugin/py/test/plugin/pytest_plugintester.py Wed Feb 11 13:19:12 2009
@@ -51,7 +51,7 @@
while methods:
name, method = methods.popitem()
if name not in hooks:
- print "definition of unknown hook: %s" % name
+ print "found unknown hook: %s" % name
fail = True
else:
hook = hooks[name]
@@ -112,6 +112,10 @@
function has been executed (i.e. pyfuncitem.execute() returns).
"""
+ def pytest_pymodule_makeitem(self, modcol, name, obj):
+ """ return custom item/collector or None. """
+
+
# from pytest_terminal plugin
def pytest_report_teststatus(self, event):
""" return shortletter and verbose word. """
Modified: py/branch/pytestplugin/py/test/plugin/pytest_pytester.py
==============================================================================
--- py/branch/pytestplugin/py/test/plugin/pytest_pytester.py (original)
+++ py/branch/pytestplugin/py/test/plugin/pytest_pytester.py Wed Feb 11 13:19:12 2009
@@ -4,6 +4,9 @@
import py
+from py.__.test import event
+
+
class RunResult:
def __init__(self, ret, outlines, errlines):
self.ret = ret
@@ -35,6 +38,15 @@
if not impname in self._plugins:
self._plugins.append(impname)
+ def parse_and_run(self, *args):
+ config = self.parseconfig(*args)
+ config.pluginmanager.configure(config)
+ session = config.initsession()
+ sorter = EventSorter(config, session)
+ session.main()
+ config.pluginmanager.unconfigure(config)
+ return sorter
+
def parseconfig(self, *args):
return py.test.config._reparse(list(args))
@@ -186,3 +198,63 @@
tmpdir = py.test.ensuretemp("_".join(pyfuncitem.listnames()))
fstester = FSTester(tmpdir)
return fstester, None
+
+class EventSorter(object):
+ def __init__(self, config, session=None):
+ self.config = config
+ self.session = session
+ self.cls2events = d = {}
+ def app(event):
+ print "[event]", event
+ for cls in py.std.inspect.getmro(event.__class__):
+ if cls is not object:
+ d.setdefault(cls, []).append(event)
+ session.bus.subscribe(app)
+
+ def get(self, cls):
+ return self.cls2events.get(cls, [])
+
+ def listoutcomes(self):
+ passed = []
+ skipped = []
+ failed = []
+ for ev in self.get(event.ItemTestReport):
+ if ev.passed:
+ passed.append(ev)
+ elif ev.skipped:
+ skipped.append(ev)
+ elif ev.failed:
+ failed.append(ev)
+ return passed, skipped, failed
+
+ def countoutcomes(self):
+ return map(len, self.listoutcomes())
+
+ def assertoutcome(self, passed=0, skipped=0, failed=0):
+ realpassed, realskipped, realfailed = self.listoutcomes()
+ assert passed == len(realpassed)
+ assert skipped == len(realskipped)
+ assert failed == len(realfailed)
+
+ def getfailedcollections(self):
+ l = []
+ for ev in self.get(event.CollectionReport):
+ if ev.failed:
+ l.append(ev)
+ return l
+
+ def getreport(self, inamepart):
+ """ return a testreport whose dotted import path matches """
+ __tracebackhide__ = True
+ l = []
+ for rep in self.get(event.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]
+
Added: py/branch/pytestplugin/py/test/plugin/pytest_unittest.py
==============================================================================
--- (empty file)
+++ py/branch/pytestplugin/py/test/plugin/pytest_unittest.py Wed Feb 11 13:19:12 2009
@@ -0,0 +1,123 @@
+"""
+automatically collect and run traditional "unittest.py" style tests.
+
+you can mix unittest TestCase subclasses and
+py.test style tests in one test module.
+
+XXX consider user-specified test_suite()
+
+this code is somewhat derived from Guido Wesdorps
+
+ http://johnnydebris.net/svn/projects/py_unittest
+
+$HeadURL: https://codespeak.net/svn/py/branch/pytestplugin/contrib/py_unittest/conftest.py $
+$Id: conftest.py 60979 2009-01-14 22:29:32Z hpk $
+"""
+import py
+
+class Unittest:
+ """ Plugin for discovering and integrating traditional Python Unittest tests.
+ """
+ def pytest_pymodule_makeitem(self, modcol, name, obj):
+ if py.std.inspect.isclass(obj) and issubclass(obj, py.std.unittest.TestCase):
+ return UnitTestCase(name, parent=modcol)
+
+class UnitTestCase(py.test.collect.Class):
+ def collect(self):
+ return [UnitTestCaseInstance("()", self)]
+
+ def setup(self):
+ pass
+
+ def teardown(self):
+ pass
+
+_dummy = object()
+class UnitTestCaseInstance(py.test.collect.Instance):
+ def collect(self):
+ loader = py.std.unittest.TestLoader()
+ names = loader.getTestCaseNames(self.obj.__class__)
+ l = []
+ for name in names:
+ callobj = getattr(self.obj, name)
+ if callable(callobj):
+ l.append(UnitTestFunction(name, parent=self))
+ return l
+
+ def _getobj(self):
+ x = self.parent.obj
+ return self.parent.obj(methodName='run')
+
+class UnitTestFunction(py.test.collect.Function):
+ def __init__(self, name, parent, args=(), obj=_dummy, sort_value=None):
+ super(UnitTestFunction, self).__init__(name, parent)
+ self._args = args
+ if obj is not _dummy:
+ self._obj = obj
+ self._sort_value = sort_value
+
+ def runtest(self):
+ target = self.obj
+ args = self._args
+ target(*args)
+
+ def setup(self):
+ instance = self.obj.im_self
+ instance.setUp()
+
+ def teardown(self):
+ instance = self.obj.im_self
+ instance.tearDown()
+
+
+def test_generic(plugintester):
+ plugintester.apicheck()
+
+def test_simple_unittest(fstester):
+ test_one = fstester.makepyfile(test_one="""
+ import unittest
+ pytest_plugins = "pytest_unittest" # XXX
+ class MyTestCase(unittest.TestCase):
+ def testpassing(self):
+ self.assertEquals('foo', 'foo')
+ def test_failing(self):
+ self.assertEquals('foo', 'bar')
+ """)
+ sorter = fstester.parse_and_run(test_one)
+ assert sorter.getreport("testpassing").passed
+ assert sorter.getreport("test_failing").failed
+
+def test_setup(fstester):
+ test_one = fstester.makepyfile(test_two="""
+ import unittest
+ pytest_plugins = "pytest_unittest" # XXX
+ class MyTestCase(unittest.TestCase):
+ def setUp(self):
+ self.foo = 1
+ def test_setUp(self):
+ self.assertEquals(1, self.foo)
+ """)
+ sorter = fstester.parse_and_run(test_one)
+ rep = sorter.getreport("test_setUp")
+ assert rep.passed
+
+def test_teardown(fstester):
+ testpath = fstester.makepyfile(test_three="""
+ import unittest
+ pytest_plugins = "pytest_unittest" # XXX
+ class MyTestCase(unittest.TestCase):
+ l = []
+ def test_one(self):
+ pass
+ def tearDown(self):
+ self.l.append(None)
+ class Second(unittest.TestCase):
+ def test_check(self):
+ self.assertEquals(MyTestCase.l, [None])
+ """)
+ sorter = fstester.parse_and_run(testpath)
+ passed, skipped, failed = sorter.countoutcomes()
+ assert passed + skipped + failed == 2
+ assert failed == 0, failed
+ assert passed == 2
+
More information about the pytest-commit
mailing list