Concepto clave
Escribir tests y documentar una API para producción son dos pilares fundamentales que transforman un proyecto de desarrollo en un producto profesional. Imagina que estás construyendo un puente: los tests son las pruebas de carga y estrés que garantizan que la estructura soportará el tráfico real, mientras que la documentación es el manual de mantenimiento y las señales de tráfico que permiten a otros ingenieros entender y utilizar el puente de forma segura. En el contexto de FastAPI, estas prácticas no son opcionales para entornos de producción; son lo que separa una API funcional de una API confiable y mantenible.
Los tests en FastAPI se centran en verificar que los endpoints responden correctamente bajo diferentes condiciones: datos válidos, datos inválidos, autenticación, autorización y casos límite. La documentación, por otro lado, se genera automáticamente gracias a las capacidades integradas de FastAPI (como OpenAPI y Swagger UI), pero requiere una configuración cuidadosa para ser útil en producción. Juntas, estas prácticas reducen los bugs en producción, facilitan la colaboración en equipos y mejoran la experiencia del desarrollador que consume tu API.
Cómo funciona en la práctica
Para implementar tests y documentación en un proyecto de FastAPI, sigue este flujo paso a paso. Primero, estructura tu proyecto con una carpeta dedicada a tests (por ejemplo, tests/) y configura un entorno virtual con las dependencias necesarias, incluyendo pytest, pytest-asyncio, y httpx para testing asíncrono. Luego, escribe tests que simulen peticiones HTTP a tu API, verificando respuestas, códigos de estado y esquemas de datos. En paralelo, mejora la documentación automática añadiendo descripciones detalladas en los decoradores de rutas, usando modelos Pydantic para validación y documentación de datos, y configurando metadatos del proyecto.
Un ejemplo práctico: supón que tienes un endpoint POST /articles para crear artículos en tu API de gestión de contenidos. Antes de escribir tests, define un modelo Pydantic para el artículo con campos como title, content, y author_id. Luego, escribe un test que envíe una petición con datos válidos y verifique que la respuesta tenga un código 201 y contenga el artículo creado. Para la documentación, añade una descripción en el decorador @app.post y usa el modelo Pydantic como parámetro, lo que generará automáticamente la documentación en Swagger UI. Este proceso asegura que tanto la funcionalidad como la documentación estén alineadas y sean mantenibles.
Codigo en accion
A continuación, un ejemplo funcional de un test para el endpoint de creación de artículos y la configuración de documentación en FastAPI. Este código es copiable y ejecutable en un entorno configurado.
# app/main.py - Configuración de la API y documentación
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional
import uuid
app = FastAPI(
title="API de Gestión de Contenidos",
description="Una API profesional para gestionar artículos y contenido, con autenticación y autorización.",
version="1.0.0",
openapi_url="/api/v1/openapi.json",
docs_url="/api/v1/docs",
)
class ArticleCreate(BaseModel):
title: str
content: str
author_id: str
tags: Optional[list[str]] = None
class Config:
schema_extra = {
"example": {
"title": "Introducción a FastAPI",
"content": "FastAPI es un framework moderno...",
"author_id": "user-123",
"tags": ["python", "api", "backend"]
}
}
articles_db = {}
@app.post(
"/articles/",
response_model=ArticleCreate,
status_code=201,
summary="Crear un nuevo artículo",
description="Endpoint para crear un artículo en la base de datos. Requiere autenticación en producción."
)
async def create_article(article: ArticleCreate):
article_id = str(uuid.uuid4())
articles_db[article_id] = article.dict()
return article# tests/test_articles.py - Tests para el endpoint de artículos
import pytest
from httpx import AsyncClient
from app.main import app
@pytest.mark.asyncio
async def test_create_article_success():
"""Test para crear un artículo con datos válidos."""
async with AsyncClient(app=app, base_url="http://test") as ac:
payload = {
"title": "Test Article",
"content": "This is a test content.",
"author_id": "test-author",
"tags": ["test", "fastapi"]
}
response = await ac.post("/articles/", json=payload)
assert response.status_code == 201
data = response.json()
assert data["title"] == "Test Article"
assert "tags" in data
@pytest.mark.asyncio
async def test_create_article_invalid_data():
"""Test para manejar datos inválidos (falta título)."""
async with AsyncClient(app=app, base_url="http://test") as ac:
payload = {
"content": "Content without title",
"author_id": "test-author"
}
response = await ac.post("/articles/", json=payload)
assert response.status_code == 422 # Unprocessable Entity por validación de PydanticErrores comunes
- No mockear dependencias externas en tests: Si tu API depende de una base de datos o servicios externos, no uses la base real en tests. En su lugar, usa mocks o bases de datos en memoria (como SQLite para pruebas) para aislar los tests y hacerlos rápidos y confiables. Por ejemplo, mockea la conexión a MongoDB con un cliente de prueba.
- Documentación genérica o incompleta: Dejar la documentación automática con descripciones por defecto o sin ejemplos hace que sea difícil de usar. Siempre añade
summary,description, y ejemplos en modelos Pydantic (usandoConfig.schema_extra) para claridad. - Tests que no cubren casos límite: Escribir tests solo para el "happy path" (datos válidos) deja la API vulnerable a errores en producción. Incluye tests para datos inválidos, errores de autenticación, y límites de tasa (rate limiting) si aplica.
- Ignorar la configuración de CORS y seguridad en documentación: En producción, la documentación debe reflejar las configuraciones de seguridad, como CORS o autenticación. Asegúrate de que los ejemplos en Swagger UI incluyan headers de autenticación si son requeridos.
- No versionar la API en la documentación: Si cambias la API, la documentación debe reflejar la versión actual. Usa parámetros como
openapi_urlydocs_urlcon rutas versionadas (e.g.,/api/v1/docs) para evitar confusiones.
Checklist de dominio
- ¿Tienes una suite de tests que cubre al menos el 80% de los endpoints, incluyendo casos de éxito, error y validación?
- ¿La documentación automática (Swagger UI) muestra ejemplos reales y descripciones claras para cada operación?
- ¿Los tests son independientes y no dependen del estado de una ejecución anterior (usando fixtures de pytest para resetear datos)?
- ¿Has configurado la documentación con metadatos del proyecto (título, descripción, versión) y rutas versionadas?
- ¿Incluyes tests de integración que simulan interacciones complejas, como autenticación seguida de una operación CRUD?
- ¿La documentación refleja los requisitos de seguridad, como esquemas de autenticación (e.g., OAuth2) en los endpoints protegidos?
- ¿Ejecutas los tests automáticamente en un pipeline de CI/CD (como GitHub Actions) antes de desplegar a producción?
Implementar Tests y Documentación para un Endpoint de Búsqueda de Artículos
En este ejercicio, extenderás la API de gestión de contenidos añadiendo un endpoint de búsqueda de artículos y asegurándolo con tests y documentación profesional. Sigue estos pasos:
- Define un nuevo endpoint: En tu archivo
app/main.py, añade un endpointGET /articles/searchque acepte un parámetro de consultaq(para término de búsqueda) y opcionalmentetag(para filtrar por etiqueta). Devuelve una lista de artículos que coincidan con la búsqueda, simulando una base de datos con al menos 5 artículos de ejemplo. - Mejora la documentación: Añade una descripción detallada al decorador del endpoint, incluyendo ejemplos de uso en la documentación automática. Usa modelos Pydantic para la respuesta y parámetros de consulta.
- Escribe tests exhaustivos: En
tests/test_search.py, crea tests que cubran: búsqueda con término encontrado, búsqueda sin resultados, búsqueda con filtro de etiqueta, y manejo de parámetros inválidos (e.g.,qvacío). UsaAsyncClientde httpx para las peticiones. - Verifica la cobertura: Ejecuta los tests con
pytest --cov=appy asegúrate de que el endpoint de búsqueda tenga al menos un 90% de cobertura de código. Ajusta los tests si es necesario. - Revisa la documentación generada: Inicia la API localmente y navega a
/api/v1/docspara verificar que el nuevo endpoint aparezca con ejemplos claros y sea probado desde la interfaz Swagger UI.
Entrega: Un archivo ZIP con los archivos modificados (app/main.py, tests/test_search.py) y un screenshot de la documentación en Swagger UI mostrando el endpoint de búsqueda.
- Usa el parámetro
Queryde FastAPI para definir parámetros de consulta con valores por defecto y validación, e.g.,q: str = Query(..., min_length=1)para requerir al menos un carácter en la búsqueda. - En los tests, simula la base de datos de artículos usando un diccionario global en el archivo de tests o un fixture de pytest que se reinicie antes de cada test para evitar interferencias.
- Para mejorar la documentación, añade un ejemplo en el modelo de respuesta usando
Config.schema_extrao en el decorador con el parámetroresponsespara mostrar códigos de estado comunes como 200 y 404.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.