FastAPI Features Testing with unittest module
Table of Contents
Preface
Just examining by testing.
Prerequisites
The App & the Test Suite in a Single Block
import unittest from typing import Union from fastapi import FastAPI from fastapi.testclient import TestClient app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} # # # The Test Suite # client = TestClient(app) class TestFastAPI(unittest.TestCase): def test_read_root(self): response = client.get("/") self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), {"Hello": "World"}) def test_read_item_with_query(self): response = client.get("/items/42?q=somequery") self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), {"item_id": 42, "q": "somequery"}) def test_read_item_without_query(self): response = client.get("/items/42") self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), {"item_id": 42, "q": None}) unittest.main(exit=False)
... ---------------------------------------------------------------------- Ran 3 tests in 0.010s OK
TestClient module
Can you explanin the main features of TestClient module?
Certainly! The `TestClient` module in FastAPI is a powerful tool designed to facilitate testing applications built with FastAPI. It is built on top of Starlette's `TestClient`, which itself wraps around `requests`, a popular HTTP library in Python. The `TestClient` module is essential for running tests that simulate HTTP requests to your application without starting an actual server. Here are the main features of the `TestClient` module: ### Main Features of TestClient 1. **Simulating HTTP Requests**: - `TestClient` allows you to simulate HTTP requests (GET, POST, PUT, DELETE, etc.) to your FastAPI application endpoints. This helps in verifying the behavior of your API endpoints. 2. **Session Management**: - `TestClient` manages sessions, including cookies and headers, making it easier to test workflows that depend on session states. 3. **Response Validation**: - You can validate the response status codes, headers, and body content to ensure they meet the expected outcomes. This ensures your API behaves as expected under different conditions. 4. **Asynchronous Support**: - `TestClient` supports testing asynchronous endpoints. It seamlessly handles both synchronous and asynchronous requests, maintaining the same interface for simplicity. 5. **Context Management**: - It provides a context manager to handle setup and teardown, ensuring clean test environments. This is useful for initializing and cleaning up resources needed for tests. 6. **Integration with Testing Frameworks**: - `TestClient` can be used in conjunction with various testing frameworks like `unittest`, `pytest`, and others, providing flexibility in writing and organizing tests. 7. **API Documentation Testing**: - It can automatically check that the documentation URLs (like Swagger UI and ReDoc) load correctly and contain the expected content, ensuring that the API documentation is always up-to-date and functional. ### Example Usage of TestClient Here's a more detailed look at how you can use `TestClient` with FastAPI: #### FastAPI Application ```python from fastapi import FastAPI from typing import Union app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} ``` #### Unit Tests ```python import unittest from fastapi.testclient import TestClient from main import app # Assuming your FastAPI app is defined in main.py client = TestClient(app) class TestFastAPI(unittest.TestCase): def test_read_root(self): response = client.get("/") self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), {"Hello": "World"}) def test_read_item_with_query(self): response = client.get("/items/42?q=somequery") self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), {"item_id": 42, "q": "somequery"}) def test_read_item_without_query(self): response = client.get("/items/42") self.assertEqual(response.status_code, 200) self.assertDictEqual(response.json(), {"item_id": 42, "q": None}) if __name__ == "__main__": unittest.main() ``` ### Explanation of Example 1. **Importing TestClient**: - `TestClient` is imported from `fastapi.testclient`. This allows us to create a client instance to interact with our FastAPI application. 2. **Creating an Instance**: - We create an instance of `TestClient` by passing in the FastAPI `app`. This client will be used to simulate HTTP requests to the application. 3. **Simulating Requests**: - `GET`, `POST`, `PUT`, `DELETE`, and other HTTP methods are available to simulate requests to the application endpoints. 4. **Response Validation**: - The responses can be checked for status codes, headers, and JSON content using the methods and attributes provided by the `requests.Response` object returned by `TestClient`. 5. **Handling Asynchronous Endpoints**: - The same interface works seamlessly with asynchronous endpoints, allowing tests to be written without worrying about the underlying asynchronous nature. ### Advanced Features While the above example covers basic usage, here are some advanced features you can take advantage of: - **Context Management**: ```python with TestClient(app) as client: response = client.get("/items/") assert response.status_code == 200 ``` - **Custom Headers and Authentication**: ```python response = client.get("/items/", headers={"Authorization": "Bearer token"}) ``` - **Session Management**: ```python client.cookie_jar.set("session", "session-value") response = client.get("/items/") ``` ### Summary The `TestClient` module in FastAPI is a powerful and convenient tool for testing web applications. It provides easy-to-use interfaces to simulate HTTP requests, manage sessions, validate responses, and integrate with various testing frameworks, making it an indispensable part of the FastAPI testing workflow.