diff --git a/CHANGELOG b/CHANGELOG index 08e2f0c0b..bbc784908 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ Changes between 1.3.4 and 2.0.0dev0 ---------------------------------------------- - pytest-2.0 is now its own package and depends on pylib-2.0 +- try harder to run unittest test suites in a more compatible manner + by deferring setup/teardown semantics to the unittest package. - introduce a new way to set config options via ini-style files, by default setup.cfg and tox.ini files are searched. The old ways (certain environment variables, dynamic conftest.py reading diff --git a/pytest/__init__.py b/pytest/__init__.py index f9d9caf1e..3d9e1f424 100644 --- a/pytest/__init__.py +++ b/pytest/__init__.py @@ -5,7 +5,7 @@ see http://pytest.org for documentation and details (c) Holger Krekel and others, 2004-2010 """ -__version__ = '2.0.0.dev17' +__version__ = '2.0.0.dev18' __all__ = ['config', 'cmdline'] diff --git a/pytest/plugin/python.py b/pytest/plugin/python.py index f2be50710..b2cac8289 100644 --- a/pytest/plugin/python.py +++ b/pytest/plugin/python.py @@ -383,7 +383,8 @@ class Function(FunctionMixin, pytest.collect.Item): config=config, collection=collection) self._args = args if self._isyieldedfunction(): - assert not callspec, "yielded functions (deprecated) cannot have funcargs" + assert not callspec, ( + "yielded functions (deprecated) cannot have funcargs") else: if callspec is not None: self.funcargs = callspec.funcargs or {} diff --git a/pytest/plugin/unittest.py b/pytest/plugin/unittest.py index 5398be6c1..9bf156e23 100644 --- a/pytest/plugin/unittest.py +++ b/pytest/plugin/unittest.py @@ -18,52 +18,32 @@ def pytest_pycollect_makeitem(collector, name, obj): return UnitTestCase(name, parent=collector) 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 py.builtin.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 - if hasattr(self.parent, 'newinstance'): - self.parent.newinstance() - self.obj = self._getobj() - - def runtest(self): - target = self.obj - args = self._args - target(*args) + for name in loader.getTestCaseNames(self.obj): + yield TestCaseFunction(name, parent=self) def setup(self): - instance = py.builtin._getimself(self.obj) - instance.setUp() + meth = getattr(self.obj, 'setUpClass', None) + if meth is not None: + meth() def teardown(self): - instance = py.builtin._getimself(self.obj) - instance.tearDown() + meth = getattr(self.obj, 'tearDownClass', None) + if meth is not None: + meth() +class TestCaseFunction(py.test.collect.Function): + def startTest(self, testcase): + pass + def addError(self, testcase, rawexcinfo): + py.builtin._reraise(*rawexcinfo) + def addFailure(self, testcase, rawexcinfo): + py.builtin._reraise(*rawexcinfo) + def addSuccess(self, testcase): + pass + def stopTest(self, testcase): + pass + def runtest(self): + testcase = self.parent.obj(self.name) + testcase(result=self) diff --git a/setup.py b/setup.py index bd8e05669..c4deb75bd 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def main(): name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.0.0.dev17', + version='2.0.0.dev18', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff --git a/testing/plugin/test_unittest.py b/testing/plugin/test_unittest.py index 40ae56556..e3f06e737 100644 --- a/testing/plugin/test_unittest.py +++ b/testing/plugin/test_unittest.py @@ -81,3 +81,25 @@ def test_module_level_pytestmark(testdir): """) reprec = testdir.inline_run(testpath, "-s") reprec.assertoutcome(skipped=1) + +def test_class_setup(testdir): + testpath = testdir.makepyfile(""" + import unittest + import py + class MyTestCase(unittest.TestCase): + x = 0 + @classmethod + def setUpClass(cls): + cls.x += 1 + def test_func1(self): + assert self.x == 1 + def test_func2(self): + assert self.x == 1 + @classmethod + def tearDownClass(cls): + cls.x -= 1 + def test_teareddown(): + assert MyTestCase.x == 0 + """) + reprec = testdir.inline_run(testpath) + reprec.assertoutcome(passed=3)