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:
- La variable
POSTGRES_TEST_URLsi está definida. - Conexión directa a la URL por defecto (
...@localhost:5432/camarero_db). - Como último recurso, arranca un contenedor
postgres:15-alpinevíatestcontainers(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=trueactiva los gates de embeddings (omítelo o ponfalsepara correr sin el modelo Granite).POSTGRES_TEST_URL=...camarero_qtestdirige los tests a la base de datos desechable.venv/bin/python -m pytest tests/ -qlanza 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¶
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/¶
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.