Testing API Endpoints
We've already used Pytest for unit tests against plain Python functions. Testing web endpoints is slightly different. We want to test our FastAPI application the way a real user would: by sending an HTTP request and verifying the HTTP response, but without spinning up a live web server on a port.
Introducing TestClient
FastAPI provides a built-in TestClient (which is actually based on the popular httpx library) specifically for this purpose. It allows you to simulate requests to your FastAPI app directly in memory.
Adding Pytest as a Dev Dependency
Pytest isn't needed at runtime, only when we're running tests. Add it to a separate development dependency group with the --dev flag:
uv add --dev pytest
This records pytest under [dependency-groups] in pyproject.toml, separate from the runtime dependencies. When we deploy the app later, the dev group can be excluded.
Writing your first Endpoint Test
Let's write a test for our /projects endpoint. Create a new file in the tests directory:
mkdir tests
touch tests/test_main.py
Add the following code to tests/test_main.py:
from fastapi.testclient import TestClient
# Import the FastAPI 'app' instance from our main code
from release_tracker.main import app
# Create a TestClient using our app
client = TestClient(app)
def test_list_projects():
# Simulate a GET request to the /projects URL
response = client.get("/projects")
# Assert that the HTTP status code is 200 (Success)
assert response.status_code == 200
# Assert that the JSON response body is a list with 1 item.
assert len(response.json()) == 3
Running the tests
To run the test, use the uv run pytest command we learned in the previous chapter:
uv run pytest
Pytest will automatically discover the tests/test_main.py file, execute the test_list_projects function, and report success!
Using TestClient, you can easily test complex endpoints, send simulated JSON payloads for POST requests, and verify exactly how your API behaves in an isolated, reliable environment.