Skip to content

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:

shell
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:

shell
mkdir tests
touch tests/test_main.py

Add the following code to tests/test_main.py:

Python
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:

shell
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.