Pruebas unitarias con FastAPI y Pytest: Configuración y Ejecución

Clase 20 de 23Curso de FastAPI

Resumen

Aprender a configurar pruebas unitarias es esencial para desarrollar aplicaciones con FastAPI. Esto asegura que tus desarrollos tengan calidad y que puedas detectar errores rápidamente, agilizando tu flujo de trabajo. FastAPI, combinado con el framework PyTest, permite escribir y ejecutar pruebas automatizadas de manera sencilla y efectiva.

¿Qué necesitas para configurar las pruebas de FastAPI?

Las pruebas en FastAPI requieren configuración local inicial y una base de datos separada específica para testing. Con esto, puedes ejecutar pruebas repetidamente sin afectar tu entorno de producción. Las herramientas principales son:

  • PyTest: framework especializado en pruebas unitarias.
  • TestClient de FastAPI: facilita simular solicitudes HTTP (GET, POST) como si las realizara un navegador.
  • SQLAlchemy y SQLModel: para configurar motores y sesiones de base de datos.

¿Cómo configurar el entorno local?

Para poder correr pruebas efectivamente, sigue estos pasos:

1. Crear archivo de configuración para pruebas

Crea un archivo llamado convTest.py. Aquí estarán todas las configuraciones específicas de pruebas.

2. Ajuste en motor de base de datos

No se recomienda usar la base de datos de producción para pruebas. En cambio, crea un motor específico para testing:

from sqlalchemy import create_engine
from sqlalchemy.pool import StaticPool

engine = create_engine(
    "db_testing_url",
    connect_args={"check_same_thread": False},
    poolclass=StaticPool
)

La opción check_same_thread en False evita conflictos entre distintos hilos, y StaticPool mantiene la base de datos en memoria para facilitar pruebas rápidas.

3. Manejo de tablas con fixtures de PyTest

PyTest emplea fixtures, funciones reutilizables entre diferentes pruebas. Utiliza un fixture para crear y luego eliminar tablas automáticamente:

import pytest
from sqlmodel import SQLModel, Session

@pytest.fixture(name="session")
def session_fixture():
    SQLModel.metadata.create_all(engine)
    with Session(engine) as session:
        yield session
    SQLModel.metadata.drop_all(engine)

¿Cómo sobrescribir funcionalidades para testing correctamente?

Para aislar las pruebas y usar configuraciones específicas sin afectar producción, utiliza la sobreescritura de dependencias:

from fastapi.testclient import TestClient
from app.main import app

@pytest.fixture(name="client")
def client_fixture(session: Session):
    def get_session_override():
        return session

    app.dependency_overrides[get_session] = get_session_override

    with TestClient(app) as client:
        yield client
        app.dependency_overrides.clear()

Este enfoque te permite probar endpoints especificando comportamientos únicos en ambiente controlado.

¿Cómo validar tu configuración correctamente?

Realiza una prueba simple en un archivo test.py para diagnosticar si la configuración funcionó correctamente:

from fastapi.testclient import TestClient

def test_client(client):
    assert type(client).__name__ == TestClient.__name__

Al ejecutar:

pytest app/test

PyTest te indicará con un icono verde el éxito de la configuración.

¡Comenta más abajo cualquier duda o idea que quieras compartir sobre esta configuración para pruebas!