From 58933aac2ad48d8b7f65a31798f5a4e595192287 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Mon, 19 Mar 2012 22:53:52 -0700 Subject: [PATCH] try to better handle @unittest.expectedFailure decorator --- CHANGELOG | 2 ++ _pytest/__init__.py | 2 +- _pytest/skipping.py | 8 ++++++++ _pytest/unittest.py | 12 +++++++++--- setup.py | 2 +- testing/test_unittest.py | 21 +++++++++++++++++++++ 6 files changed, 42 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b44497b7d..82e218dba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,8 @@ Changese between 2.2.3 and ... - fix issue 126: correctly match all invalid xml characters for junitxml binary escape +- fix issue with unittest: now @unittest.expectedFailure markers should + be processed correctly (you can also use @pytest.mark markers) - document integration with the extended distribute/setuptools test commands diff --git a/_pytest/__init__.py b/_pytest/__init__.py index 2194bedd5..93eddeac5 100644 --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.4.dev1' +__version__ = '2.2.4.dev2' diff --git a/_pytest/skipping.py b/_pytest/skipping.py index 6098c81a4..46b15617d 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -132,6 +132,14 @@ def check_xfail_no_run(item): def pytest_runtest_makereport(__multicall__, item, call): if not isinstance(item, pytest.Function): return + # unitttest special case, see setting of _unexpectedsuccess + if hasattr(item, '_unexpectedsuccess'): + rep = __multicall__.execute() + if rep.when == "call": + # we need to translate into how py.test encodes xpass + rep.keywords['xfail'] = "reason: " + item._unexpectedsuccess + rep.outcome = "failed" + return rep if not (call.excinfo and call.excinfo.errisinstance(py.test.xfail.Exception)): evalxfail = getattr(item, '_evalxfail', None) diff --git a/_pytest/unittest.py b/_pytest/unittest.py index 024c2998d..903dc87a3 100644 --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -91,22 +91,28 @@ class TestCaseFunction(pytest.Function): self._addexcinfo(rawexcinfo) def addFailure(self, testcase, rawexcinfo): self._addexcinfo(rawexcinfo) + def addSkip(self, testcase, reason): try: pytest.skip(reason) except pytest.skip.Exception: self._addexcinfo(sys.exc_info()) - def addExpectedFailure(self, testcase, rawexcinfo, reason): + + def addExpectedFailure(self, testcase, rawexcinfo, reason=""): try: pytest.xfail(str(reason)) except pytest.xfail.Exception: self._addexcinfo(sys.exc_info()) - def addUnexpectedSuccess(self, testcase, reason): - pass + + def addUnexpectedSuccess(self, testcase, reason=""): + self._unexpectedsuccess = reason + def addSuccess(self, testcase): pass + def stopTest(self, testcase): pass + def runtest(self): self._testcase(result=self) diff --git a/setup.py b/setup.py index c03e113a2..51de90c28 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def main(): name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.4.dev1', + version='2.2.4.dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff --git a/testing/test_unittest.py b/testing/test_unittest.py index aba17cc7e..2ea227d35 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -459,3 +459,24 @@ def test_unittest_typerror_traceback(testdir): result = testdir.runpytest() assert "TypeError" in result.stdout.str() assert result.ret == 1 + +@pytest.mark.skipif("sys.version_info < (2,7)") +def test_unittest_unexpected_failure(testdir): + testdir.makepyfile(""" + import unittest + class MyTestCase(unittest.TestCase): + @unittest.expectedFailure + def test_func1(self): + assert 0 + @unittest.expectedFailure + def test_func2(self): + assert 1 + """) + result = testdir.runpytest("-rxX") + result.stdout.fnmatch_lines([ + "*XFAIL*MyTestCase*test_func1*", + "*XPASS*MyTestCase*test_func2*", + "*1 xfailed*1 xpass*", + ]) + +