From 59ed39809b278ab3a98f76de2dea1c35df33e774 Mon Sep 17 00:00:00 2001 From: "eric.goulart" Date: Mon, 11 Nov 2024 08:37:31 -0300 Subject: [PATCH] implementing requested improvements still missing test coverage --- docs/_newsfragments/2156.breakingchange.rst | 3 ++ falcon/testing/test_case.py | 51 +++++++++++---------- 2 files changed, 30 insertions(+), 24 deletions(-) create mode 100644 docs/_newsfragments/2156.breakingchange.rst diff --git a/docs/_newsfragments/2156.breakingchange.rst b/docs/_newsfragments/2156.breakingchange.rst new file mode 100644 index 000000000..50aaa8d8f --- /dev/null +++ b/docs/_newsfragments/2156.breakingchange.rst @@ -0,0 +1,3 @@ +- **Deprecation**: Support for `testtools` in `falcon.testing` is now deprecated and will be removed in Falcon 5.0. + If `testtools` is selected automatically (i.e., without explicit configuration via `FALCON_BASE_TEST_CASE`), a deprecation warning will be issued. + Explicit configuration using `FALCON_BASE_TEST_CASE=testtools.TestCase` will not emit a warning. diff --git a/falcon/testing/test_case.py b/falcon/testing/test_case.py index a1b9696ce..856961406 100644 --- a/falcon/testing/test_case.py +++ b/falcon/testing/test_case.py @@ -22,52 +22,58 @@ import unittest import warnings -if 'DISABLE_TESTTOOLS' not in os.environ: +import falcon +import falcon.request +from falcon.testing.client import Result # NOQA +from falcon.testing.client import TestClient + +base_case = os.environ.get('FALCON_BASE_TEST_CASE') + +if base_case and 'testtools.TestCase' in base_case: + try: + import testtools + + BaseTestCase = testtools.TestCase + except ImportError: + BaseTestCase = unittest.TestCase +elif base_case is None: try: import testtools warnings.warn( - 'Support for testtools is deprecated and will be removed in Falcon 5.0. ' - 'Please migrate to unittest or pytest.', + 'Support for testtools is deprecated and will be removed in Falcon 5.0.', DeprecationWarning, ) BaseTestCase = testtools.TestCase - except ImportError: # pragma: nocover + except ImportError: BaseTestCase = unittest.TestCase - -import falcon -import falcon.request -from falcon.testing.client import Result # NOQA -from falcon.testing.client import TestClient +else: + BaseTestCase = unittest.TestCase class TestCase(unittest.TestCase, TestClient): - """Extends :mod:`unittest` to support WSGI/ASGI functional testing. + """Extends ``unittest`` to support WSGI/ASGI functional testing. Note: - This class uses :mod:`unittest` by default. If :mod:`testtools` - is available and the environment variable - ``DISABLE_TESTTOOLS`` is **not** set, it will use :mod:`testtools` instead. - **Support for testtools is deprecated and will be removed in Falcon 5.0.** + This class uses ``unittest`` by default, but you may use ``pytest`` + to run ``unittest.TestCase`` instances, allowing a hybrid approach. Recommended: - We recommend using **pytest** for testing Falcon applications. + We recommend using **pytest** alongside **unittest** for testing. See our tutorial on using pytest. - This base class provides some extra plumbing for unittest-style - test cases, to help simulate WSGI or ASGI requests without having - to spin up an actual web server. Various simulation methods are - derived from :class:`falcon.testing.TestClient`. + This base class provides extra functionality for unittest-style test cases, + helping simulate WSGI or ASGI requests without spinning up a web server. Various + simulation methods are derived from :class:`falcon.testing.TestClient`. Simply inherit from this class in your test case classes instead of - :class:`unittest.TestCase`. + ``unittest.TestCase``. For example:: from falcon import testing import myapp - class MyTestCase(testing.TestCase): def setUp(self): super(MyTestCase, self).setUp() @@ -77,7 +83,6 @@ def setUp(self): # return a `falcon.App` instance. self.app = myapp.create() - class TestMyApp(MyTestCase): def test_get_message(self): doc = {'message': 'Hello world!'} @@ -86,7 +91,6 @@ def test_get_message(self): self.assertEqual(result.json, doc) """ - # NOTE(vytas): Here we have to restore __test__ to allow collecting tests! __test__ = True app: falcon.App @@ -99,7 +103,6 @@ def test_get_message(self): from falcon import testing import myapp - class MyTestCase(testing.TestCase): def setUp(self): super(MyTestCase, self).setUp()