Testing - Estrategia de Pruebas
Propósito y Alcance
Section titled “Propósito y Alcance”Este documento describe el enfoque y patrones de pruebas utilizados en el backend Orchestrator. Cubre pruebas unitarias, pruebas de integración y pruebas de endpoints API utilizando Jest como framework principal de pruebas. La estrategia enfatiza la organización de pruebas orientada al dominio, cobertura integral de la lógica de negocio y verificación del aislamiento multi-tenant.
Configuración del Framework de Pruebas
Section titled “Configuración del Framework de Pruebas”El sistema utiliza Jest versión 29.6.1 con ts-jest para soporte de TypeScript. El entorno de pruebas está configurado para Node.js con resolución de rutas de módulos personalizada.
Configuración de Jest
Section titled “Configuración de Jest”La configuración de Jest está definida en orchestrator/jest.orchestrator.config.js.
| Clave de Configuración | Valor | Propósito |
| :--------------------- | :------------------------------------- | :-------------------------------------------- | ------------------------------ |
| preset | ts-jest | Transformación de TypeScript |
| testEnvironment | node | Entorno de ejecución Node.js |
| roots | ['<rootDir>/src', '<rootDir>/tests'] | Rutas de descubrimiento de archivos de prueba |
| moduleNameMapper | { '^@/(.*)$': '<rootDir>/src/$1' } | Resolución de alias de ruta |
| testMatch | ['\\\*_/?(_.)+(spec | test).ts'] | Patrones de archivos de prueba |
| setupFiles | ['dotenv/config'] | Carga de variables de entorno |
Mapeo de Rutas de Módulos
Section titled “Mapeo de Rutas de Módulos”El alias de ruta TypeScript @/* se mapea a src/*, permitiendo importaciones limpias en todas las pruebas:
import { PayrollService } from "@/domain/payroll/PayrollService";import { getTenantPool } from "@/lib/db";Este mapeo está sincronizado entre orchestrator/tsconfig.json y la configuración de Jest.
Organización y Descubrimiento de Pruebas
Section titled “Organización y Descubrimiento de Pruebas”Estructura de Pruebas Basada en Dominios
Section titled “Estructura de Pruebas Basada en Dominios”Las pruebas están organizadas por dominio siguiendo la misma estructura que el código fuente:
flowchart TB
%% =========================
%% Estructura del Código
%% =========================
subgraph CODE["Estructura del Código"]
direction TB
SRC["src/"] --> DOMAIN["domain/"]
DOMAIN --> PAYROLL["payroll/"]
DOMAIN --> CONTRACTS["contracts/"]
DOMAIN --> COA["chart-of-accounts/"]
DOMAIN --> COMMAND["command/"]
end
%% =========================
%% Estructura de Pruebas
%% =========================
subgraph TESTS["Estructura de Pruebas"]
direction TB
TESTSDIR["tests/"]
TESTSDIR --> PTESTS["PayrollService.unit.test.ts<br/>PayrollService.integration.test.ts"]
TESTSDIR --> CTESTS["ContractHtmlGenerator.unit.test.ts"]
TESTSDIR --> COATESTS["ChartOfAccountsService.unit.test.ts"]
TESTSDIR --> STESTS["SessionService.test.ts"]
end
%% Relaciones código -> pruebas
PAYROLL --> TESTSDIR
CONTRACTS --> TESTSDIR
COA --> TESTSDIR
COMMAND --> TESTSDIR
Convenciones de Nomenclatura de Archivos de Prueba
Section titled “Convenciones de Nomenclatura de Archivos de Prueba”| Tipo de Prueba | Patrón de Nomenclatura | Ejemplo |
|---|---|---|
| Prueba Unitaria | *.unit.test.ts | PayrollService.unit.test.ts |
| Prueba de Integración | *.integration.test.ts | PayrollService.integration.test.ts |
| Prueba Genérica | *.test.ts | SessionService.test.ts |
Comandos de Descubrimiento de Pruebas
Section titled “Comandos de Descubrimiento de Pruebas”El package.json define scripts de ejecución de pruebas dirigidas en orchestrator\package.json.
| Script | Comando | Propósito |
|---|---|---|
npm test | Solo pruebas unitarias | Ciclo de retroalimentación rápida |
npm run test:all | Todas las pruebas | Validación completa |
npm run test:unit | Pruebas unitarias | Prueba de lógica aislada |
npm run test:integration | Pruebas de integración | Integración base de datos/servicios |
npm run test:domain | Pruebas específicas de dominio | Enfoque en lógica de dominio |
npm run test:payroll | Pruebas de dominio de remuneraciones | Validación del motor de cálculo |
npm run test:watch | Modo observador | Iteración de desarrollo |
Tipos de Pruebas y Patrones
Section titled “Tipos de Pruebas y Patrones”Pruebas Unitarias
Section titled “Pruebas Unitarias”Las pruebas unitarias validan métodos individuales de servicios y lógica de negocio en aislamiento. Las dependencias se simulan utilizando las capacidades de mocking de Jest.
Patrón de Prueba de Capa de Servicio
Section titled “Patrón de Prueba de Capa de Servicio”flowchart LR
TC["Caso de Prueba"]
SUT["Servicio Bajo Prueba (ej.,<br/>ChartOfAccountsService)"]
REPO["Repositorio Simulado<br/>jest.mock()"]
DB["Pool de Base de Datos Simulado<br/>jest.mock('@lib/db')"]
TC -- "llama" --> SUT
TC -- "verifica comportamiento" --> SUT
TC -- "verifica interacciones" --> REPO
SUT -- "usa (simulado)" --> REPO
SUT -- "usa (simulado)" --> DB
Ejemplo: Prueba Unitaria del Servicio de Plan Contable
La prueba en orchestrator/src/domain/chart-of-accounts/__tests__/ChartOfAccountsService.unit.test.ts demuestra:
- Simulación de Dependencias
- Pool de base de datos simulado en
@/lib/db - Clase de repositorio simulada con
jest.mock()
- Prueba de Validación
- Prueba regla de negocio: códigos de cuenta deben ser numéricos
- Verifica error lanzado para entrada inválida
- Prueba de Lógica de Negocio
- Prueba regla de eliminación: cuentas con hijos no pueden ser eliminadas
- Verifica verificaciones en cascada apropiadas
Patrón de Simulación para Servicios
Section titled “Patrón de Simulación para Servicios”// Mock database pooljest.mock("@/lib/db", () => ({ getTenantPool: jest.fn().mockReturnValue({ query: jest.fn(), connect: jest.fn().mockResolvedValue({ query: jest.fn(), release: jest.fn(), }), }),}));
// Mock repositoryjest.mock("../ChartOfAccountsRepository");Pruebas de Integración
Section titled “Pruebas de Integración”Las pruebas de integración verifican interacciones entre servicios, repositorios y la base de datos real. Estas pruebas utilizan bases de datos de prueba temporales para asegurar comportamiento realista.
sequenceDiagram
participant Suite as "Suite de Pruebas"
participant BeforeAll as "Hook beforeAll()"
participant DB as "Base de Datos de Prueba test_acc_xxxxx"
participant SUT as "Servicio Bajo Prueba"
participant AfterAll as "Hook afterAll()"
Suite->>BeforeAll: Inicializar suite de pruebas
BeforeAll->>DB: Crear base de datos temporal
BeforeAll->>DB: Ejecutar migraciones de esquema
BeforeAll->>DB: Sembrar datos de prueba
loop Para Cada Prueba
Suite->>SUT: Ejecutar escenario de prueba
SUT->>DB: Realizar operaciones
DB-->>SUT: Retornar resultados
SUT-->>Suite: Retornar respuesta
Suite->>Suite: Afirmar expectativas
end
Suite->>AfterAll: Limpieza
AfterAll->>DB: Eliminar base de datos temporal
Patrón de Nomenclatura de Base de Datos de Prueba
Section titled “Patrón de Nomenclatura de Base de Datos de Prueba”Las bases de datos de prueba usan el patrón test_acc_<randomId> como se ve en orchestrator/tests/logs/payroll.test.log:
test_acc_80f7ecc6test_acc_5a438ce3test_acc_ae9bb86b
Esto asegura el aislamiento de pruebas y permite la ejecución paralela de pruebas.
Pruebas de Endpoints API
Section titled “Pruebas de Endpoints API”Las pruebas de API validan endpoints HTTP, autenticación, autorización y flujos de solicitud de extremo a extremo utilizando supertest.
Stack de Pruebas de API
Section titled “Stack de Pruebas de API”flowchart TD
A["Caso de Prueba (supertest)"]
B[Solicitud HTTP POST<br/>/api/remuneraciones/payroll]
A -->|"supertest.post()"| B
subgraph MW[Cadena de Middleware]
M1[Aplicación HTTPS]
M2[authenticateToken]
M3[authorizeRoute]
M4[Middleware de Auditoría]
M1 --> M2 --> M3 --> M4
end
B --> M1
subgraph APP[Capa de Aplicación]
R1[Manejador de Ruta Express]
S1[Capa de Servicio]
P1[Capa de Repositorio]
R1 --> S1 --> P1
end
M4 --> R1
DB[(Base de Datos de Prueba)]
P1 --> DB
DB -->|Resultado| P1
P1 -->|Datos| S1
S1 -->|Respuesta| R1
R1 -->|HTTP 200/400/500| A
Pruebas de API con Supertest
Section titled “Pruebas de API con Supertest”Las dependencias de prueba en orchestrator/package.json incluyen:
supertest: Biblioteca de aserciones HTTP@types/supertest: Definiciones TypeScript
Patrón típico de prueba de API:
Section titled “Patrón típico de prueba de API:”import request from "supertest";import { app } from "@/app";
it("should authenticate and authorize endpoint", async () => { const response = await request(app) .post("/api/remuneraciones/payroll/generar") .set("Authorization", `Bearer ${validToken}`) .send({ contractId: "...", period: "..." }) .expect(200);
expect(response.body.success).toBe(true);});