Saltar a contenido

Ejecutar los tests

Esta guía explica cómo lanzar las suites de tests del proyecto sin pisar tu base de datos de desarrollo, qué papel juega la variable EMBEDDINGS_ENABLED, y cuáles son los gates que CI exige antes de mergear.

A quién va dirigida

Guía orientada a la tarea (how-to): asume que ya tienes el backend instalado (venv) y un PostgreSQL accesible en localhost:5432. Para el detalle de la arquitectura de los módulos, consulta la documentación relacionada al final.

Backend: pytest con base de datos desechable

Los tests del backend usan PostgreSQL real (no mocks ni sqlite): los tests e2e y de módulo crean y destruyen el esquema en cada test (DROP SCHEMA public CASCADE / CREATE SCHEMA public).

Aísla la base de datos con POSTGRES_TEST_URL

Para no tocar tu base de datos de desarrollo, apunta los tests a una base de datos desechable mediante la variable de entorno POSTGRES_TEST_URL:

POSTGRES_TEST_URL=postgresql+asyncpg://camarero_user:camarero_password@localhost:5432/camarero_qtest

Por qué importa la URL

tests/conftest.py resuelve la URL de la base de datos con esta prioridad:

  1. La variable POSTGRES_TEST_URL si está definida.
  2. Conexión directa a la URL por defecto (...@localhost:5432/camarero_db).
  3. Como último recurso, arranca un contenedor postgres:15-alpine vía testcontainers (requiere socket de podman/Docker).

Si no fijas POSTGRES_TEST_URL, los tests caen en el paso 2 y operan sobre camarero_db (tu base de datos de dev), cuyo esquema se borra en cada test. Usa siempre una base distinta como camarero_qtest.

EMBEDDINGS_ENABLED en tests

Los embeddings (modelo Granite, ~390 MB) están desactivados por defecto en tests: tests/conftest.py fija EMBEDDINGS_ENABLED=false antes de importar app.main, de modo que las suites nunca descargan el modelo. Los tests que necesitan el clasificador de intents o el recomendador stubean IntentClassifier.classify o usan embeddings falsos.

Para los gates de embeddings (las suites que sí ejercitan ese camino), fija explícitamente EMBEDDINGS_ENABLED=true.

Comando

EMBEDDINGS_ENABLED=true POSTGRES_TEST_URL=postgresql+asyncpg://camarero_user:camarero_password@localhost:5432/camarero_qtest venv/bin/python -m pytest tests/ -q
  • EMBEDDINGS_ENABLED=true activa los gates de embeddings (omítelo o pon false para correr sin el modelo Granite).
  • POSTGRES_TEST_URL=...camarero_qtest dirige los tests a la base de datos desechable.
  • venv/bin/python -m pytest tests/ -q lanza pytest desde el venv del repo en modo silencioso (-q).

Subconjuntos

Puedes acotar la ejecución a un módulo o paquete, por ejemplo pytest tests/contract/ o pytest tests/comanda/e2e/, manteniendo las mismas variables de entorno.

Gates de CI

Los gates duros que bloquean el merge son dos:

Gate Comando Qué comprueba
Arquitectura make lint-arch Contratos de import (import-linter, ADR-004): sin imports cross-module directos.
Contrato pytest tests/contract/ El contrato OpenAPI/SSE hacia el frontend no se rompe.

make lint-arch

make lint-arch

Ejecuta lint-imports --config .importlinter (usa la copia del venv si existe, venv/bin/lint-imports, o la del PATH). Hace cumplir la regla ADR-004 de no imports cross-module.

Baseline con contratos grandfathered

El baseline de lint-arch arrastra 2 contratos rotos grandfathered (heredados). El criterio NO es "cero violaciones", sino no introducir violaciones nuevas respecto al baseline.

pytest tests/contract/

pytest tests/contract/

Verifica el contrato hacia el frontend:

  • tests/contract/openapi_snapshot.json — regla dura: solo puede CRECER en paths nuevos.
  • tests/contract/sse_events_inventory.md — inventario de eventos SSE.

Adiciones sí, removals/renames con cuidado

Las adiciones aditivas al contrato (campos nuevos en respuestas, regenerar el snapshot, ampliar el contrato SSE) están autorizadas siempre que en el mismo cambio se cablee el frontend para consumirlas. Los removals, renames o type-changes de campos existentes rompen clientes desplegados y requieren cuidado / sign-off.

typecheck es no-bloqueante

make typecheck (mypy) existe y es la convención normativa, pero el gate en CI queda no-bloqueante mientras el baseline tenga errores pre-existentes. Los gates duros son make lint-arch y pytest tests/contract/.

Frontend: vitest

Los tests del frontend se ejecutan con vitest.

Baselines rojos preexistentes

El frontend parte de baselines rojos preexistentes. Por eso el criterio de aceptación NO es "todo verde", sino 0 findings nuevos: tu cambio no debe introducir fallos adicionales respecto al baseline.

Páginas relacionadas