Unit and Integration Testing with FastAPI
How to Write Tests for Your FastAPI Applications
Testing is a crucial aspect of software development, ensuring that your application works as expected and remains maintainable. FastAPI, being a modern web framework, supports comprehensive testing using popular testing libraries. In this article, we’ll explore how to write unit and integration tests for FastAPI applications, complete with code examples.
1. Setting Up Your Environment
First, you need to install the necessary packages for testing. We will use pytest
for testing, httpx
for making HTTP requests, and fastapi.testclient
for testing FastAPI applications.
pip install pytest httpx
2. Creating the Project Structure
Here’s a basic structure for your FastAPI project:
my_project/
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── models.py
│ ├── crud.py
│ ├── schemas.py
│ ├── database.py
│ └── tests/
│ ├── __init__.py
│ ├── test_main.py
│ └── test_crud.py
├── requirements.txt
└── README.md
3. Sample FastAPI Application
Let’s start with a simple FastAPI application. Create the main application file main.py
.
Example: main.py
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo": {"name": "Foo", "description": "A test item"}}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")
return items[item_id]
@app.post("/items/{item_id}")
async def create_item(item_id: str, item: dict):
if item_id in items:
raise HTTPException(status_code=400, detail="Item already exists")
items[item_id] = item
return item
4. Writing Unit Tests
Unit tests focus on testing individual components of your application in isolation. For example, you can test your CRUD functions without requiring the whole application to run.
Example: test_crud.py
import pytest
# Assuming you have a crud.py with get_item and create_item functions
from app.crud import get_item, create_item
items = {"foo": {"name": "Foo", "description": "A test item"}}
def test_get_item():
item = get_item(items, "foo")
assert item["name"] == "Foo"
assert item["description"] == "A test item"
def test_get_item_not_found():
with pytest.raises(KeyError):
get_item(items, "bar")
def test_create_item():
new_item = {"name": "Bar", "description": "Another test item"}
create_item(items, "bar", new_item)
assert "bar" in items
assert items["bar"] == new_item
def test_create_item_already_exists():
with pytest.raises(ValueError):
create_item(items, "foo", {"name": "Foo", "description": "Duplicate item"})
5. Writing Integration Tests
Integration tests ensure that different components of your application work together as expected. For FastAPI, you can use httpx
and fastapi.testclient
to make requests to your endpoints and verify the responses.
Example: test_main.py
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_read_item():
response = client.get("/items/foo")
assert response.status_code == 200
assert response.json() == {"name": "Foo", "description": "A test item"}
def test_read_item_not_found():
response = client.get("/items/bar")
assert response.status_code == 404
assert response.json() == {"detail": "Item not found"}
def test_create_item():
new_item = {"name": "Bar", "description": "Another test item"}
response = client.post("/items/bar", json=new_item)
assert response.status_code == 200
assert response.json() == new_item
def test_create_item_already_exists():
new_item = {"name": "Foo", "description": "Duplicate item"}
response = client.post("/items/foo", json=new_item)
assert response.status_code == 400
assert response.json() == {"detail": "Item already exists"}
6. Running Your Tests
You can run your tests using pytest
. Navigate to your project directory and run:
pytest
This will discover and run all the test files and functions prefixed with test_
.
7. Conclusion
Testing is essential for ensuring the reliability and maintainability of your applications. FastAPI, combined with pytest
and httpx
, provides a robust framework for writing both unit and integration tests. By following the steps outlined in this article, you can confidently write tests for your FastAPI applications, ensuring they perform as expected.