Mario Alexander Vargas Celis
Realizar pruebas unitarias en FastAPI utilizando Pytest y SQLAlchemy permite validar el correcto funcionamiento de tus endpoints y la lógica de negocio, garantizando que tu aplicación se comporte como se espera. A continuación, te muestro cómo configurar un entorno de pruebas con estas herramientas:
Pasos para Configurar Pruebas Unitarias en FastAPI
1. Instalación de Dependencias
Asegúrate de instalar las librerías necesarias:
pip install pytest pytest-asyncio sqlalchemy
2. Configurar la Base de Datos para Pruebas
Crea una base de datos en memoria para que tus pruebas no afecten los datos reales de producción.
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker
Base = declarative_base()
# Base de datos en memoria para pruebas TEST_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(TEST_DATABASE_URL, connect_args={"check_same_thread": False}) TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Inicialización de la base de datos def init_test_db(): Base.metadata.create_all(bind=engine)
def drop_test_db(): Base.metadata.drop_all(bind=engine)
3. Crear un Cliente de Pruebas para FastAPI
FastAPI incluye un cliente de pruebas basado en Starlette para interactuar con la aplicación.
from fastapi.testclient import TestClient from myapp.main import app # Importa tu aplicación FastAPI
# Crea un cliente de pruebas client = TestClient(app)
4. Configuración de Sesiones de Base de Datos para Pruebas
Sobrescribe la dependencia de base de datos para que utilice la base de datos en memoria.
from fastapi import Depends from sqlalchemy.orm import Session from myapp.database import get_db # Tu dependencia real de la base de datos from myapp.models import Base
# Crea una sesión de prueba def override_get_db(): db = TestingSessionLocal() try: yield db finally: db.close()
# Sobrescribe la dependencia en tu aplicación app.dependency_overrides[get_db] = override_get_db
# Inicializa la base de datos de pruebas init_test_db()
5. Escribir Pruebas Unitarias
Crea un archivo de pruebas (por ejemplo,
test_app.pyEjemplo: Prueba de Creación de un Registro
from myapp.schemas import CustomerCreate
def test_create_customer(): # Datos de prueba data = {"name": "John Doe", "email": "johndoe@example.com"}
# Llama al endpoint para crear un cliente response = client.post("/customers/", json=data)
# Verifica el código de respuesta y los datos retornados assert response.status_code == 201 assert response.json()["name"] == data["name"] assert response.json()["email"] == data["email"]
Ejemplo: Prueba de Consulta de un Registro
def test_get_customer(): # Crea un cliente data = {"name": "Jane Doe", "email": "janedoe@example.com"} client.post("/customers/", json=data)
# Consulta el cliente creado response = client.get("/customers/1")
# Verifica que los datos sean correctos assert response.status_code == 200 assert response.json()["name"] == "Jane Doe" assert response.json()["email"] == "janedoe@example.com"
6. Ejecutar las Pruebas
Ejecuta las pruebas con Pytest desde la línea de comandos:
pytest -v
Prácticas Recomendadas
-
Usa Fixtures de Pytest: Define datos o configuraciones comunes que puedan reutilizarse entre múltiples pruebas.import pytest
@pytest.fixture def test_client(): init_test_db() yield client drop_test_db()
-
Aislar Pruebas: Asegúrate de que cada prueba se ejecute de manera independiente, sin depender del estado de otras pruebas.
-
Validar Errores: Además de probar casos exitosos, incluye pruebas para errores esperados (por ejemplo, registro no encontrado).
-
Limpiar la Base de Datos: Si no usas una base en memoria, asegúrate de limpiar los datos después de cada prueba.
Conclusión
Este enfoque asegura que tus endpoints en FastAPI sean robustos y se comporten correctamente. Puedes extender este modelo para probar funcionalidades más avanzadas, como autenticación, relaciones de modelos, y manejo de excepciones.
