Recommended resources
The freely available resources this lesson will direct you to.
Hello! Welcome to the fifth module of your advanced Claude Code course.
In the previous module, you mastered advanced MCP server integrations, culminating in a lesson where you connected Claude directly to a RAG pipeline's vector store. This gave Claude a powerful way to query and reason over external knowledge bases. Now, we'll pivot from external integrations to internal development workflows, focusing on how Claude can radically improve code quality and velocity.
This module is Test-Driven Development & Automated Debugging. We'll begin with the foundational skill of generating high-quality tests. The learning outcome for this lesson is to use Claude Code to generate comprehensive unit and integration tests for existing FastAPI endpoints.
For someone with your experience building and deploying full-stack AI applications, you know that robust testing is not a luxury—it's essential for creating reliable, maintainable systems. This lesson will show you how to offload the often tedious task of writing tests to Claude, allowing you to achieve higher test coverage with less effort.
The Power of Specificity: Prompting for Tests
The quality of the tests Claude generates is directly proportional to the quality of your prompt. A vague request like "write tests for this file" will produce generic results. To get comprehensive and useful tests, you must be specific.
A great prompt for test generation should include:
- The target: The specific file, class, or function to test.
- The framework: The testing library to use (e.g.,
pytestfor FastAPI). - The context: Any necessary setup, like using FastAPI's
TestClientor mocking dependencies. - The requirements: A clear list of scenarios to cover (happy paths, error cases, edge cases, different status codes).
The following resource provides excellent templates that we can adapt for our FastAPI projects.
Claude Code Prompt Library (2026) - 40+ Templates for CLI
This 'Claude Code Prompt Library' contains battle-tested prompt templates for various tasks, including testing. We'll focus on two key templates that provide a strong foundation for generating unit and integration tests.
Please review the two templates under the 'Testing Prompts' section: Unit Test Generator: Note how it specifies the framework, coverage goals (public functions, edge cases), and test structure (Arrange-Act-Assert). Integration Test Template: Observe the focus on API-specific concerns like test setup (database, mocks), HTTP status codes (200, 400, 401, etc.), and request variations (invalid bodies, missing fields).
These templates are your starting point. You will customize them with details specific to your FastAPI application's logic and architecture.
Generating Unit Tests for Business Logic
Unit tests focus on a small, isolated piece of code, like a single function. In a FastAPI application, this might be a helper function, a data transformation utility, or a piece of business logic within a service layer. The goal is to test its logic without involving the web framework or database.
Imagine you have the following utility function in app/utils.py:
# app/utils.py
def calculate_discount(price: float, percentage: int) -> float:
"""Calculates the final price after applying a discount."""
if not 0 <= percentage <= 100:
raise ValueError("Discount percentage must be between 0 and 100")
return price * (1 - percentage / 100)
To get comprehensive unit tests for this, you could use a prompt like this in Claude Code:
Generate unit tests for the
calculate_discountfunction in@app/utils.py.Requirements:
- Use the
pytestframework.- Follow the Arrange-Act-Assert pattern.
- Mock any external dependencies (none in this case).
Test Cases:
- Happy path: Test with a valid price and percentage.
- Boundary conditions: Test with percentages of 0 and 100.
- Error handling: Use
pytest.raisesto verify that aValueErroris raised for percentages less than 0 and greater than 100.Output the complete test file
tests/test_utils.py.
This prompt is specific, actionable, and leaves no room for ambiguity, ensuring Claude produces exactly the tests you need.
Generating Integration Tests for FastAPI Endpoints
Integration tests verify that different parts of your application work together correctly. For a FastAPI endpoint, this means testing the entire flow: receiving an HTTP request, processing it through the endpoint function, interacting with dependencies (like our calculate_discount function), and returning an HTTP response.
FastAPI makes this easy with its TestClient.
First, Claude needs to understand the endpoint it's testing. You'd start by providing the router file as context.

Let's assume you have this endpoint in app/main.py that uses the utility function we defined earlier:
# app/main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from .utils import calculate_discount
app = FastAPI()
class Item(BaseModel):
name: str
price: float
discount_percent: int
@app.post("/items/")
async def create_item_with_discount(item: Item):
try:
final_price = calculate_discount(item.price, item.discount_percent)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
return {"name": item.name, "final_price": final_price}
A good prompt to generate integration tests would be:
Generate integration tests for the
POST /items/endpoint in@app/main.py.Test Setup:
- Use
pytest.- Use
TestClientfromfastapi.testclientto make requests to the app.Test Cases:
- Happy path (200 OK): Send a valid request body and assert the response contains the correct
final_price.- Validation Error (422 Unprocessable Entity): Send a request body with an invalid type (e.g.,
priceas a string) and assert the status code is 422.- Business Logic Error (400 Bad Request): Send a request with a
discount_percentgreater than 100 and assert the status code is 400 and the detail message is correct.Output the complete test file
tests/test_main.py.
This prompt guides Claude to test the integration between the web layer (FastAPI), the data validation layer (Pydantic), and your custom business logic.
Seeing It in Action
Theory is great, but seeing is believing. The following video clip demonstrates this exact process. While it uses the Claude API via a Python script, the core interaction—prompting Claude with code and getting pytest tests back—is identical to what you would do in the Claude Code CLI.
Claude 3.5 API in Python • Explore AWESOME Use Cases!
This segment from a tutorial by pixegami shows Claude generating pytest unit tests for existing Python files. It's a perfect visual demonstration of the workflow we're discussing.
Watch the section 'Generating Unit Tests' (00:15:03 - 00:16:22). Observe how the user provides a prompt asking for pytest tests for all Python files in a directory. Notice that Claude first lists the files, then reads them, and finally writes new test_*.py files containing the generated tests, which are then successfully executed.
As you saw, Claude can not only generate the test code but also correctly structure it into separate test files, ready to be picked up by your test runner.

Your Turn: Craft the Prompts
Now, let's put this into practice. Below is a self-contained FastAPI application. Your task is not to write the tests yourself, but to write the two prompts you would give to Claude Code to generate the necessary unit and integration tests.
Code to Test:
# file: services/user_service.py
import re
def is_valid_username(username: str) -> bool:
"""
Validates a username.
- Must be 5-20 characters long.
- Can only contain alphanumeric characters and underscores.
"""
if not 5 <= len(username) <= 20:
return False
if not re.match(r"^\w+$", username):
return False
return True
# file: main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from services.user_service import is_valid_username
app = FastAPI()
class UserCreate(BaseModel):
username: str = Field(..., description="The desired username.")
email: str
@app.post("/users/", status_code=201)
def create_user(user: UserCreate):
if not is_valid_username(user.username):
raise HTTPException(
status_code=400,
detail="Invalid username format."
)
# In a real app, you would save the user to a database here.
return {"message": f"User '{user.username}' created successfully."}
Your Task:
- Write a prompt for Claude Code to generate unit tests for the
is_valid_usernamefunction inservices/user_service.py. Be sure to include test cases for length constraints and allowed characters (both valid and invalid cases). - Write a prompt for Claude Code to generate integration tests for the
POST /users/endpoint inmain.py. Include tests for a successful creation (201 status), a bad request due to an invalid username (400 status), and a validation error from Pydantic (422 status, e.g., missing email).
Think about the specific instructions Claude needs for each task. This exercise will solidify your ability to direct Claude effectively.
Conclusion
You have now learned how to leverage Claude Code to accelerate one of the most critical parts of software development: testing. By writing specific, detailed prompts, you can generate comprehensive unit and integration tests for your FastAPI applications, ensuring code quality and freeing up your time to focus on building features.
Key Takeaways:
- Effective test generation with Claude hinges on specific and structured prompts.
- Unit tests focus on isolated functions; your prompt should specify edge cases, boundary conditions, and error handling for that function.
- Integration tests for FastAPI endpoints test the entire request-response cycle; your prompt should specify the use of
TestClientand cover various HTTP status codes and request body variations. - Always state the testing framework (
pytest) and any other relevant tools in your prompt.
Next Up:
Now that you can generate tests for existing code, we'll flip the script. In the next lesson, you will learn to apply a Test-Driven Development (TDD) workflow by first writing a failing test and then prompting Claude to write the implementation code that makes it pass. This powerful technique ensures your code is built correctly from the start.