-
-
Notifications
You must be signed in to change notification settings - Fork 944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(testing): deprecate testtools support in TestCase #2405
base: master
Are you sure you want to change the base?
Changes from 3 commits
c6e6559
59ed398
358bcb2
8952f71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,36 +18,79 @@ | |
utilities for simulating and validating HTTP requests. | ||
""" | ||
|
||
try: | ||
import testtools as unittest | ||
except ImportError: # pragma: nocover | ||
import unittest | ||
import os | ||
import unittest | ||
import warnings | ||
|
||
import falcon | ||
import falcon.request | ||
|
||
# TODO hoist for backwards compat. Remove in falcon 4. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove this note! |
||
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: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to actually import the specified module, not just support |
||
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.', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As requested before, please do not warn just because the package is importable! |
||
DeprecationWarning, | ||
) | ||
BaseTestCase = testtools.TestCase | ||
except ImportError: | ||
BaseTestCase = unittest.TestCase | ||
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: | ||
If available, uses :mod:`testtools` in lieu of | ||
:mod:`unittest`. | ||
This class uses ``unittest`` by default, but you may use ``pytest`` | ||
to run ``unittest.TestCase`` instances, allowing a hybrid approach. | ||
|
||
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`. | ||
Recommended: | ||
We recommend using **pytest** alongside **unittest** for testing. | ||
See our tutorial on using pytest. | ||
|
||
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` or :class:`testtools.TestCase`. | ||
``unittest.TestCase``. | ||
|
||
For example:: | ||
|
||
from falcon import testing | ||
import myapp | ||
|
||
class MyTestCase(testing.TestCase): | ||
def setUp(self): | ||
super(MyTestCase, self).setUp() | ||
|
||
# Assume the hypothetical `myapp` package has a | ||
# function called `create()` to initialize and | ||
# return a `falcon.App` instance. | ||
self.app = myapp.create() | ||
|
||
class TestMyApp(MyTestCase): | ||
def test_get_message(self): | ||
doc = {'message': 'Hello world!'} | ||
|
||
result = self.simulate_get('/messages/42') | ||
self.assertEqual(result.json, doc) | ||
""" | ||
|
||
# NOTE(vytas): Here we have to restore __test__ to allow collecting tests! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why have you removed my note? |
||
__test__ = True | ||
|
||
app: falcon.App | ||
|
@@ -60,7 +103,6 @@ | |
from falcon import testing | ||
import myapp | ||
|
||
|
||
class MyTestCase(testing.TestCase): | ||
def setUp(self): | ||
super(MyTestCase, self).setUp() | ||
|
@@ -69,14 +111,6 @@ | |
# function called `create()` to initialize and | ||
# return a `falcon.App` instance. | ||
self.app = myapp.create() | ||
|
||
|
||
class TestMyApp(MyTestCase): | ||
def test_get_message(self): | ||
doc = {'message': 'Hello world!'} | ||
|
||
result = self.simulate_get('/messages/42') | ||
self.assertEqual(result.json, doc) | ||
""" | ||
|
||
def setUp(self) -> None: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't name the newsfragment
.breakingchange.
, because we are not making any actual breaking changes until 5.0.Since we are adding a new way to configure the base test case, I suggest marketing this as new feature.