From 5a78b83d2aeb8b0d1416962a1e5dd36197d45231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelmer=20Vernoo=C4=B3?= Date: Mon, 16 Jun 2025 23:54:00 +0100 Subject: [PATCH] Remove deprecated Python26Result and Python27Result, replacing them with Python3Result --- doc/for-framework-folk.rst | 6 +- testtools/testresult/doubles.py | 58 ++++----- testtools/tests/test_testcase.py | 49 ++++---- testtools/tests/test_testresult.py | 195 ++++++++--------------------- 4 files changed, 103 insertions(+), 205 deletions(-) diff --git a/doc/for-framework-folk.rst b/doc/for-framework-folk.rst index fb55ce10..c289d739 100644 --- a/doc/for-framework-folk.rst +++ b/doc/for-framework-folk.rst @@ -361,9 +361,9 @@ meet the testtools ``TestResult`` API. Test Doubles ------------ -In testtools.testresult.doubles there are three test doubles that testtools -uses for its own testing: ``Python26TestResult``, ``Python27TestResult``, -``ExtendedTestResult``. These TestResult objects implement a single variation of +In testtools.testresult.doubles there are several test doubles that testtools +uses for its own testing: ``Python3TestResult``, and ``ExtendedTestResult``. +These TestResult objects implement a single variation of the TestResult API each, and log activity to a list ``self._events``. These are made available for the convenience of people writing their own extensions. diff --git a/testtools/testresult/doubles.py b/testtools/testresult/doubles.py index 5b326dbd..01e597a0 100644 --- a/testtools/testresult/doubles.py +++ b/testtools/testresult/doubles.py @@ -8,8 +8,7 @@ __all__ = [ "ExtendedTestResult", - "Python26TestResult", - "Python27TestResult", + "Python3TestResult", "StreamResult", "TwistedTestResult", ] @@ -24,56 +23,30 @@ def __init__(self, event_log=None): self._events = event_log -class Python26TestResult(LoggingBase): - """A precisely python 2.6 like test result, that logs.""" +class Python3TestResult(LoggingBase): + """A precisely python 3 like test result, that logs.""" def __init__(self, event_log=None): super().__init__(event_log=event_log) self.shouldStop = False self._was_successful = True self.testsRun = 0 + self.failfast = False def addError(self, test, err): self._was_successful = False self._events.append(("addError", test, err)) + if self.failfast: + self.stop() def addFailure(self, test, err): self._was_successful = False self._events.append(("addFailure", test, err)) - - def addSuccess(self, test): - self._events.append(("addSuccess", test)) - - def startTest(self, test): - self._events.append(("startTest", test)) - self.testsRun += 1 - - def stop(self): - self.shouldStop = True - - def stopTest(self, test): - self._events.append(("stopTest", test)) - - def wasSuccessful(self): - return self._was_successful - - -class Python27TestResult(Python26TestResult): - """A precisely python 2.7 like test result, that logs.""" - - def __init__(self, event_log=None): - super().__init__(event_log) - self.failfast = False - - def addError(self, test, err): - super().addError(test, err) if self.failfast: self.stop() - def addFailure(self, test, err): - super().addFailure(test, err) - if self.failfast: - self.stop() + def addSuccess(self, test): + self._events.append(("addSuccess", test)) def addExpectedFailure(self, test, err): self._events.append(("addExpectedFailure", test, err)) @@ -86,14 +59,27 @@ def addUnexpectedSuccess(self, test): if self.failfast: self.stop() + def startTest(self, test): + self._events.append(("startTest", test)) + self.testsRun += 1 + def startTestRun(self): self._events.append(("startTestRun",)) + def stop(self): + self.shouldStop = True + + def stopTest(self, test): + self._events.append(("stopTest", test)) + def stopTestRun(self): self._events.append(("stopTestRun",)) + def wasSuccessful(self): + return self._was_successful + -class ExtendedTestResult(Python27TestResult): +class ExtendedTestResult(Python3TestResult): """A test result like the proposed extended unittest result API.""" def __init__(self, event_log=None): diff --git a/testtools/tests/test_testcase.py b/testtools/tests/test_testcase.py index f07cc919..b4d41e59 100644 --- a/testtools/tests/test_testcase.py +++ b/testtools/tests/test_testcase.py @@ -44,8 +44,7 @@ ) from testtools.testresult.doubles import ( ExtendedTestResult, - Python26TestResult, - Python27TestResult, + Python3TestResult, ) from testtools.tests.helpers import ( AsText, @@ -1217,9 +1216,9 @@ def test(self): case = Case("test") return case - def test_raising__UnexpectedSuccess_py27(self): + def test_raising__UnexpectedSuccess_py3(self): case = self.make_unexpected_case() - result = Python27TestResult() + result = Python3TestResult() case.run(result) case = result._events[0][1] self.assertEqual( @@ -1720,7 +1719,7 @@ def test_that_raises_skipException(self): self.skipTest("skipping this test") events = [] - result = Python27TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_that_raises_skipException") test.run(result) case = result._events[0][1] @@ -1741,7 +1740,7 @@ def test_that_raises_skipException(self): self.skipTest("skipping this test") events = [] - result = Python27TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_that_raises_skipException") test.run(result) case = result._events[0][1] @@ -1764,10 +1763,10 @@ def test_that_raises_skipException(self): pass events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_that_raises_skipException") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def test_skip_with_old_result_object_calls_addError(self): class SkippingTest(TestCase): @@ -1775,10 +1774,10 @@ def test_that_raises_skipException(self): raise self.skipException("skipping this test") events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_that_raises_skipException") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def test_skip_decorator(self): class SkippingTest(TestCase): @@ -1787,10 +1786,10 @@ def test_that_is_decorated_with_skip(self): self.fail() events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_that_is_decorated_with_skip") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def test_skipIf_decorator(self): class SkippingTest(TestCase): @@ -1799,10 +1798,10 @@ def test_that_is_decorated_with_skipIf(self): self.fail() events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_that_is_decorated_with_skipIf") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def test_skipUnless_decorator(self): class SkippingTest(TestCase): @@ -1811,10 +1810,10 @@ def test_that_is_decorated_with_skipUnless(self): self.fail() events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_that_is_decorated_with_skipUnless") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def test_skip_decorator_shared(self): def shared(testcase): @@ -1827,13 +1826,13 @@ class NotSkippingTest(TestCase): test_no_skip = skipIf(False, "skipping this test")(shared) events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) test = SkippingTest("test_skip") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) events2 = [] - result2 = Python26TestResult(events2) + result2 = Python3TestResult(events2) test2 = NotSkippingTest("test_no_skip") test2.run(result2) self.assertEqual("addFailure", events2[1][0]) @@ -1845,13 +1844,13 @@ def test_that_is_decorated_with_skip(self): self.fail() events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) try: test = SkippingTest("test_that_is_decorated_with_skip") except unittest.SkipTest: self.fail("SkipTest raised") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def test_skipIf_class_decorator(self): @skipIf(True, "skipping this testcase") @@ -1860,13 +1859,13 @@ def test_that_is_decorated_with_skipIf(self): self.fail() events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) try: test = SkippingTest("test_that_is_decorated_with_skipIf") except unittest.SkipTest: self.fail("SkipTest raised") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def test_skipUnless_class_decorator(self): @skipUnless(False, "skipping this testcase") @@ -1875,13 +1874,13 @@ def test_that_is_decorated_with_skipUnless(self): self.fail() events = [] - result = Python26TestResult(events) + result = Python3TestResult(events) try: test = SkippingTest("test_that_is_decorated_with_skipUnless") except unittest.SkipTest: self.fail("SkipTest raised") test.run(result) - self.assertEqual("addSuccess", events[1][0]) + self.assertEqual("addSkip", events[1][0]) def check_skip_decorator_does_not_run_setup(self, decorator, reason): class SkippingTest(TestCase): diff --git a/testtools/tests/test_testresult.py b/testtools/tests/test_testresult.py index f77e6c78..a8c414b3 100644 --- a/testtools/tests/test_testresult.py +++ b/testtools/tests/test_testresult.py @@ -68,8 +68,7 @@ ) from testtools.testresult.doubles import ( ExtendedTestResult, - Python26TestResult, - Python27TestResult, + Python3TestResult, TwistedTestResult, ) from testtools.testresult.doubles import ( @@ -153,7 +152,7 @@ def test_stop_sets_shouldStop(self): self.assertTrue(result.shouldStop) -class Python26Contract(TestControlContract): +class Python3Contract(TestControlContract): def test_fresh_result_is_successful(self): # A result is considered successful before any tests are run. result = self.makeResult() @@ -183,8 +182,6 @@ def test_addSuccess_is_success(self): result.stopTest(self) self.assertTrue(result.wasSuccessful()) - -class Python27Contract(Python26Contract): def test_addExpectedFailure(self): # Calling addExpectedFailure(test, exc_info) completes ok. result = self.makeResult() @@ -248,7 +245,7 @@ def test_b(self): self.assertEqual(1, result.testsRun) -class TagsContract(Python27Contract): +class TagsContract(Python3Contract): """Tests to ensure correct tagging behaviour. See the subunit docs for guidelines on how this is supposed to work. @@ -448,24 +445,14 @@ def makeResult(self): return ExtendedTestResult() -class TestPython26TestResultContract(TestCase, Python26Contract): - def makeResult(self): - return Python26TestResult() - - -class TestAdaptedPython26TestResultContract(TestCase, FallbackContract): +class TestPython3TestResultContract(TestCase, Python3Contract): def makeResult(self): - return ExtendedToOriginalDecorator(Python26TestResult()) + return Python3TestResult() -class TestPython27TestResultContract(TestCase, Python27Contract): +class TestAdaptedPython3TestResultContract(TestCase, DetailsContract): def makeResult(self): - return Python27TestResult() - - -class TestAdaptedPython27TestResultContract(TestCase, DetailsContract): - def makeResult(self): - return ExtendedToOriginalDecorator(Python27TestResult()) + return ExtendedToOriginalDecorator(Python3TestResult()) class TestAdaptedTwistedTestResultContract(TestCase, DetailsContract): @@ -2395,12 +2382,8 @@ def testStopTestRun(self): class TestExtendedToOriginalResultDecoratorBase(TestCase): - def make_26_result(self): - self.result = Python26TestResult() - self.make_converter() - - def make_27_result(self): - self.result = Python27TestResult() + def make_result(self): + self.result = Python3TestResult() self.make_converter() def make_converter(self): @@ -2525,25 +2508,15 @@ def check_outcome_string(self, outcome): class TestExtendedToOriginalResultDecorator(TestExtendedToOriginalResultDecoratorBase): - def test_failfast_py26(self): - self.make_26_result() - self.assertEqual(False, self.converter.failfast) - self.converter.failfast = True - self.assertFalse(hasattr(self.converter.decorated, "failfast")) - - def test_failfast_py27(self): - self.make_27_result() + def test_failfast_py3(self): + self.make_result() self.assertEqual(False, self.converter.failfast) # setting it should write it to the backing result self.converter.failfast = True self.assertEqual(True, self.converter.decorated.failfast) - def test_progress_py26(self): - self.make_26_result() - self.converter.progress(1, 2) - - def test_progress_py27(self): - self.make_27_result() + def test_progress_py3(self): + self.make_result() self.converter.progress(1, 2) def test_progress_pyextended(self): @@ -2552,18 +2525,13 @@ def test_progress_pyextended(self): self.assertEqual([("progress", 1, 2)], self.result._events) def test_shouldStop(self): - self.make_26_result() + self.make_result() self.assertEqual(False, self.converter.shouldStop) self.converter.decorated.stop() self.assertEqual(True, self.converter.shouldStop) - def test_startTest_py26(self): - self.make_26_result() - self.converter.startTest(self) - self.assertEqual([("startTest", self)], self.result._events) - - def test_startTest_py27(self): - self.make_27_result() + def test_startTest_py3(self): + self.make_result() self.converter.startTest(self) self.assertEqual([("startTest", self)], self.result._events) @@ -2572,13 +2540,8 @@ def test_startTest_pyextended(self): self.converter.startTest(self) self.assertEqual([("startTest", self)], self.result._events) - def test_startTestRun_py26(self): - self.make_26_result() - self.converter.startTestRun() - self.assertEqual([], self.result._events) - - def test_startTestRun_py27(self): - self.make_27_result() + def test_startTestRun_py3(self): + self.make_result() self.converter.startTestRun() self.assertEqual([("startTestRun",)], self.result._events) @@ -2587,13 +2550,8 @@ def test_startTestRun_pyextended(self): self.converter.startTestRun() self.assertEqual([("startTestRun",)], self.result._events) - def test_stopTest_py26(self): - self.make_26_result() - self.converter.stopTest(self) - self.assertEqual([("stopTest", self)], self.result._events) - - def test_stopTest_py27(self): - self.make_27_result() + def test_stopTest_py3(self): + self.make_result() self.converter.stopTest(self) self.assertEqual([("stopTest", self)], self.result._events) @@ -2602,13 +2560,8 @@ def test_stopTest_pyextended(self): self.converter.stopTest(self) self.assertEqual([("stopTest", self)], self.result._events) - def test_stopTestRun_py26(self): - self.make_26_result() - self.converter.stopTestRun() - self.assertEqual([], self.result._events) - - def test_stopTestRun_py27(self): - self.make_27_result() + def test_stopTestRun_py3(self): + self.make_result() self.converter.stopTestRun() self.assertEqual([("stopTestRun",)], self.result._events) @@ -2617,12 +2570,8 @@ def test_stopTestRun_pyextended(self): self.converter.stopTestRun() self.assertEqual([("stopTestRun",)], self.result._events) - def test_tags_py26(self): - self.make_26_result() - self.converter.tags({1}, {2}) - - def test_tags_py27(self): - self.make_27_result() + def test_tags_py3(self): + self.make_result() self.converter.tags({1}, {2}) def test_tags_pyextended(self): @@ -2630,12 +2579,8 @@ def test_tags_pyextended(self): self.converter.tags({1}, {2}) self.assertEqual([("tags", {1}, {2})], self.result._events) - def test_time_py26(self): - self.make_26_result() - self.converter.time(1) - - def test_time_py27(self): - self.make_27_result() + def test_time_py3(self): + self.make_result() self.converter.time(1) def test_time_pyextended(self): @@ -2647,24 +2592,16 @@ def test_time_pyextended(self): class TestExtendedToOriginalAddError(TestExtendedToOriginalResultDecoratorBase): outcome = "addError" - def test_outcome_Original_py26(self): - self.make_26_result() - self.check_outcome_exc_info(self.outcome) - - def test_outcome_Original_py27(self): - self.make_27_result() + def test_outcome_Original_py3(self): + self.make_result() self.check_outcome_exc_info(self.outcome) def test_outcome_Original_pyextended(self): self.make_extended_result() self.check_outcome_exc_info(self.outcome) - def test_outcome_Extended_py26(self): - self.make_26_result() - self.check_outcome_details_to_exec_info(self.outcome) - - def test_outcome_Extended_py27(self): - self.make_27_result() + def test_outcome_Extended_py3(self): + self.make_result() self.check_outcome_details_to_exec_info(self.outcome) def test_outcome_Extended_pyextended(self): @@ -2686,40 +2623,36 @@ class TestExtendedToOriginalAddFailure(TestExtendedToOriginalAddError): class TestExtendedToOriginalAddExpectedFailure(TestExtendedToOriginalAddError): outcome = "addExpectedFailure" - def test_outcome_Original_py26(self): - self.make_26_result() - self.check_outcome_exc_info_to_nothing(self.outcome, "addSuccess") + def test_outcome_Original_py3(self): + self.make_result() + self.check_outcome_exc_info(self.outcome) - def test_outcome_Extended_py26(self): - self.make_26_result() - self.check_outcome_details_to_nothing(self.outcome, "addSuccess") + def test_outcome_Extended_py3(self): + self.make_result() + self.check_outcome_details_to_exec_info(self.outcome) class TestExtendedToOriginalAddSkip(TestExtendedToOriginalResultDecoratorBase): outcome = "addSkip" - def test_outcome_Original_py26(self): - self.make_26_result() - self.check_outcome_string_nothing(self.outcome, "addSuccess") - - def test_outcome_Original_py27(self): - self.make_27_result() + def test_outcome_Original_py3(self): + self.make_result() self.check_outcome_string(self.outcome) def test_outcome_Original_pyextended(self): self.make_extended_result() self.check_outcome_string(self.outcome) - def test_outcome_Extended_py26(self): - self.make_26_result() - self.check_outcome_string_nothing(self.outcome, "addSuccess") + def test_outcome_Extended_py3(self): + self.make_result() + self.check_outcome_string(self.outcome) - def test_outcome_Extended_py27_no_reason(self): - self.make_27_result() + def test_outcome_Extended_py3_no_reason(self): + self.make_result() self.check_outcome_details_to_string(self.outcome) - def test_outcome_Extended_py27_reason(self): - self.make_27_result() + def test_outcome_Extended_py3_reason(self): + self.make_result() self.check_outcome_details_to_arg( self.outcome, "foo", {"reason": Content(UTF8_TEXT, lambda: [_b("foo")])} ) @@ -2740,24 +2673,16 @@ class TestExtendedToOriginalAddSuccess(TestExtendedToOriginalResultDecoratorBase outcome = "addSuccess" expected = "addSuccess" - def test_outcome_Original_py26(self): - self.make_26_result() - self.check_outcome_nothing(self.outcome, self.expected) - - def test_outcome_Original_py27(self): - self.make_27_result() + def test_outcome_Original_py3(self): + self.make_result() self.check_outcome_nothing(self.outcome) def test_outcome_Original_pyextended(self): self.make_extended_result() self.check_outcome_nothing(self.outcome) - def test_outcome_Extended_py26(self): - self.make_26_result() - self.check_outcome_details_to_nothing(self.outcome, self.expected) - - def test_outcome_Extended_py27(self): - self.make_27_result() + def test_outcome_Extended_py3(self): + self.make_result() self.check_outcome_details_to_nothing(self.outcome) def test_outcome_Extended_pyextended(self): @@ -2769,30 +2694,18 @@ class TestExtendedToOriginalAddUnexpectedSuccess( TestExtendedToOriginalResultDecoratorBase ): outcome = "addUnexpectedSuccess" - expected = "addFailure" + expected = "addUnexpectedSuccess" - def test_outcome_Original_py26(self): - self.make_26_result() - getattr(self.converter, self.outcome)(self) - [event] = self.result._events - self.assertEqual((self.expected, self), event[:2]) - - def test_outcome_Original_py27(self): - self.make_27_result() + def test_outcome_Original_py3(self): + self.make_result() self.check_outcome_nothing(self.outcome) def test_outcome_Original_pyextended(self): self.make_extended_result() self.check_outcome_nothing(self.outcome) - def test_outcome_Extended_py26(self): - self.make_26_result() - getattr(self.converter, self.outcome)(self) - [event] = self.result._events - self.assertEqual((self.expected, self), event[:2]) - - def test_outcome_Extended_py27(self): - self.make_27_result() + def test_outcome_Extended_py3(self): + self.make_result() self.check_outcome_details_to_nothing(self.outcome) def test_outcome_Extended_pyextended(self):