- Python Falcon - Home
- Python Falcon - Introduction
- Python Falcon - Environment Setup
- Python Falcon - WSGI vs ASGI
- Python Falcon - Hello World(WSGI)
- Python Falcon - Waitress
- Python Falcon - ASGI
- Python Falcon - Uvicorn
- Python Falcon - API Testing Tools
- Request & Response
- Python Falcon - Resource Class
- Python Falcon - App Class
- Python Falcon - Routing
- Falcon - Suffixed Responders
- Python Falcon - Inspect Module
- Python Falcon - Jinja2 Template
- Python Falcon - Cookies
- Python Falcon - Status Codes
- Python Falcon - Error Handling
- Python Falcon - Hooks
- Python Falcon - Middleware
- Python Falcon - CORS
- Python Falcon - Websocket
- Python Falcon - Sqlalchemy Models
- Python Falcon - Testing
- Python Falcon - Deployment
- Python Falcon Useful Resources
- Python Falcon - Quick Guide
- Python Falcon - Useful Resources
- Python Falcon - Discussion
Python Falcon - Testing
Falcon's testing module is a Functional testing framework for Falcon apps. It contains various test classes and utility functions to support functional testing. The testing framework supports both unittest and pytest.
We shall use following the script (myapp.py) to demonstrate testing functionality. It contains a HelloResource class with an on_get() responder that renders a JSON response of Hello World. The create() function returns Falcon's Application object added with a route registered with '/' URL.
from waitress import serve
import falcon
import json
class HelloResource:
def on_get(self, req, resp):
"""Handles GET requests"""
resp.text=json.dumps({"message":"Hello World"})
# This is the default status
resp.status = falcon.HTTP_200
# Default is JSON, so override
resp.content_type = falcon.MEDIA_JSON
def create():
app = falcon.App()
hello = HelloResource()
app.add_route('/', hello)
return app
app=create()
if __name__ == '__main__':
serve(app, host='0.0.0.0', port=8000)
Using unittest
The testing.TestCase extends unittest to facilitate functional testing of WSGI/ASGI applications written with Falcon. We need to inherit from this base class and write the tests.
The test functions in the TestCase subclass are of the name simulate_*() where '*' stands for HTTP methods like GET, POST etc. It means, we have to fetch the result of simulate_get() function and compare it with the expected result by assertion functions.
The simulate_*() functions receive two arguments.
simulate_*(app, route)
Following is the code for test-myapp.py. It executes simulate_get() function and asserts its result with the anticipated result and indicates whether the test has failed or passed.
from falcon import testing
import myapp
class MyTestCase(testing.TestCase):
def setUp(self):
super(MyTestCase, self).setUp()
self.app = myapp.create()
class TestMyApp(MyTestCase):
def test_get_message(self):
doc = {'message': 'Hello world!'}
result = self.simulate_get('/')
self.assertEqual(result.json, doc)
if '__name__'=='__main__':
unittest.main()
Run the above test with the help of the following command −
python -m unittest test-myapp.py
F
==============================================================
FAIL: test_get_message (test-myapp.TestMyApp)
--------------------------------------------------------------
Traceback (most recent call last):
File "E:\falconenv\test-myapp.py", line 17, in test_get_message
self.assertEqual(result.json, doc)
AssertionError: {'message': 'Hello World'} != {'message':
'Hello world!'}
- {'message': 'Hello World'}
? ^
+ {'message': 'Hello world!'}
? ^ +
--------------------------------------------------------------
Ran 1 test in 0.019s
FAILED (failures=1)
Using Pytest
To perform testing using PyTest framework, you need to install it using PIP utility.
pip3 install pytest
To run a test function, we need an object of testing.TestClient class. It simulates the requests for WSGI and ASGI applications. This object is first obtained by giving Falcon application object as the argument.
We run the simulate_*() functions and assert its result with the anticipated output to decide whether the test has failed or passed. In both the examples, the test fails because of difference in case of 'W' in Hello World message. The responder returns it with uppercase 'W' whereas the test function has it in lowercase.
from falcon import testing
import pytest
import myapp
@pytest.fixture()
def client():
return testing.TestClient(myapp.create())
def test_get_message(client):
doc = {'message': 'Hello world!'}
result = client.simulate_get('/')
assert result.json == doc
Run the above test using the following command −
pytest test-myapp.py v
=========== test session starts ==========================
platform win32 -- Python 3.8.6, pytest-7.1.2, pluggy-1.0.0 --
e:\falconenv\scripts\python.exe
cachedir: .pytest_cache
rootdir: E:\falconenv
plugins: anyio-3.5.0
collected 1 item
test-myapp.py::test_get_message FAILED
[100%]
==================== FAILURES =======================
_____________________________________________________
test_get_message
_____________________________________________________
client = <falcon.testing.client.TestClient object at 0x0000000003EAA6A0>
def test_get_message(client):
doc = {'message': 'Hello world!'}
result = client.simulate_get('/')
> assert result.json == doc
E AssertionError: assert {'message': 'Hello World'} ==
{'message': 'Hello world!'}
E Differing items:
E {'message': 'Hello World'} != {'message': 'Hello world!'}
E Full diff:
E - {'message': 'Hello world!'}
E ? ^ -
E + {'message': 'Hello World'}
E ? ^
test-myapp.py:42: AssertionError
============ short test summary info ==================
FAILED test-myapp.py::test_get_message - AssertionError:
assert {'message': 'Hello World'} == {'message': 'Hello
world!'}
============ 1 failed in 4.11s ========================