home / skills / eyadsibai / ltk / fastapi-testing

This skill helps you test FastAPI applications effectively by guiding dependency overrides, test clients, and common test patterns.

npx playbooks add skill eyadsibai/ltk --skill fastapi-testing

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.0 KB
---
name: FastAPI Testing
description: This skill should be used when the user asks about "testing FastAPI", "FastAPI tests", "API testing", "test FastAPI endpoints", "mock FastAPI dependencies", "TestClient", "async API tests"
version: 1.0.0
---

# FastAPI Testing

Patterns for testing FastAPI applications.

## Core Concepts

### Test Clients

| Client | Use Case | Async Support |
|--------|----------|---------------|
| **TestClient** | Sync tests (most cases) | No |
| **AsyncClient (httpx)** | Async endpoints, lifespan events | Yes |

**Key concept**: TestClient wraps the ASGI app - no server needed.

---

## Dependency Override Pattern

FastAPI's killer feature for testing: replace any dependency.

**How it works:**

1. Define test version of dependency
2. Add to `app.dependency_overrides[original] = test_version`
3. Run tests
4. Clear overrides after test

**Common overrides:**

- Database session → test database or mock
- Auth/current user → test user or bypassed auth
- External services → mocked responses

---

## Test Patterns

### CRUD Testing Checklist

| Operation | Happy Path | Error Cases |
|-----------|------------|-------------|
| **Create** | Returns 201, correct data | 400 validation, 409 duplicate |
| **Read** | Returns 200, correct data | 404 not found |
| **Update** | Returns 200, updated data | 404, 400 validation |
| **Delete** | Returns 204 | 404 not found |

### Validation Testing

Use parametrize for boundary conditions:

- Valid inputs → expected success
- Invalid email format → 422
- Missing required fields → 422
- Too short/long values → 422

---

## Database Testing Strategies

| Strategy | Pros | Cons |
|----------|------|------|
| **In-memory SQLite** | Fast, isolated | Different from prod DB |
| **Test database** | Realistic | Slower, needs setup |
| **Transactions + rollback** | Fast, realistic | Complex setup |
| **Mocked repository** | Fastest | Less integration coverage |

**Key concept**: Use function-scoped fixtures to ensure test isolation.

---

## Project Structure

```
tests/
├── conftest.py       # Shared fixtures (client, db, auth)
├── test_users.py     # Endpoint tests
├── test_auth.py      # Auth-specific tests
└── factories/        # Test data factories
```

---

## Common Pitfalls

| Pitfall | Solution |
|---------|----------|
| Shared state between tests | Use function-scoped fixtures |
| Forgetting to clear overrides | Use fixture with cleanup |
| Testing implementation not behavior | Focus on HTTP responses |
| Missing async marks | Add `@pytest.mark.asyncio` |
| SQLite vs Postgres differences | Use same DB type for important tests |

---

## Quick Reference

**Test client fixture pattern**: Create client, set overrides, yield, clear overrides

**Protected endpoint testing**: Override `get_current_user` dependency

**File upload testing**: Use `files={"file": (name, content, mimetype)}`

## Resources

- FastAPI Testing: <https://fastapi.tiangolo.com/tutorial/testing/>
- HTTPX AsyncClient: <https://www.python-httpx.org/>

Overview

This skill explains practical patterns for testing FastAPI applications, focusing on clients, dependency overrides, database strategies, and common test patterns. It favors reproducible, isolated tests that exercise HTTP behavior rather than internal implementation. The guidance covers both synchronous TestClient and async HTTPX AsyncClient usage, plus fixtures and cleanup practices.

How this skill works

It inspects common testing needs: endpoint responses, dependency injection overrides, database isolation, and async lifecycle events. The skill describes how to create test clients, override FastAPI dependencies via app.dependency_overrides, and choose a database strategy (in-memory, test DB, transactions, or mocks). It also outlines test patterns for CRUD, validation, auth-protected endpoints, and file uploads.

When to use it

  • When writing endpoint tests for FastAPI apps
  • When you need to mock or override dependencies (auth, DB, external services)
  • When testing async endpoints or lifespan events
  • When you want isolated, repeatable tests with fixtures
  • When validating input handling, status codes, and error cases

Best practices

  • Prefer TestClient for most sync tests; use httpx AsyncClient for async endpoints and lifespan events
  • Use app.dependency_overrides to inject test doubles for DB, auth, and external services
  • Scope fixtures to functions to avoid shared state and ensure isolation
  • Test HTTP behavior (status codes, payloads) rather than internal implementation details
  • Clear dependency overrides and clean up test resources in fixture teardown

Example use cases

  • Create a TestClient fixture that sets up a test database session and yields a client for CRUD tests
  • Override get_current_user to test protected endpoints without real auth tokens
  • Use httpx.AsyncClient with pytest.mark.asyncio to test websocket or async lifecycle behavior
  • Parametrize validation tests to assert 422 responses for invalid inputs and boundary cases
  • Use file upload tests with files={'file': (name, content, 'mimetype')} to verify multipart handling

FAQ

Should I use TestClient or AsyncClient?

Use TestClient for most sync endpoint tests; use httpx.AsyncClient when endpoints are async, or you need to test lifespan events or async middleware.

How do I isolate database state between tests?

Use function-scoped fixtures that create a fresh test DB or wrap each test in a transaction with rollback. In-memory SQLite is fast but may differ from production DB behavior.