feat(tests): enhance test database setup and cleanup for improved isolation and performance

This commit is contained in:
Dries Augustyns
2026-05-22 21:01:03 +02:00
parent 71e2277643
commit 32dd7bba46
5 changed files with 137 additions and 104 deletions
+35 -22
View File
@@ -1,39 +1,52 @@
import { beforeAll, afterAll, afterEach, vi } from 'vitest';
import { testDatabase } from './helpers/database';
// IMPORTANT: this file runs before each test file's imports execute.
// We rewrite DATABASE_URL and REDIS_URL here so per-worker isolation is
// applied before any service module constructs a Prisma/Redis client.
import dotenv from 'dotenv';
import path from 'path';
import {afterAll, afterEach, beforeAll, vi} from 'vitest';
// Load environment variables from root .env file
dotenv.config({ path: path.resolve(__dirname, '../.env') });
dotenv.config({path: path.resolve(__dirname, '../.env')});
// Vitest assigns each worker a 1-based pool id; defaults to "1" for single-worker runs.
const workerId = process.env.VITEST_POOL_ID || '1';
if (process.env.DATABASE_URL) {
const url = new URL(process.env.DATABASE_URL);
const baseDb = url.pathname.replace(/^\//, '') || 'plunk_test';
url.pathname = `/${baseDb}_w${workerId}`;
process.env.DATABASE_URL = url.toString();
// Mirror onto DIRECT_DATABASE_URL so prisma migrate uses the same worker DB.
if (process.env.DIRECT_DATABASE_URL) {
const direct = new URL(process.env.DIRECT_DATABASE_URL);
direct.pathname = `/${baseDb}_w${workerId}`;
process.env.DIRECT_DATABASE_URL = direct.toString();
}
}
if (process.env.REDIS_URL) {
const url = new URL(process.env.REDIS_URL);
url.pathname = `/${(parseInt(workerId, 10) - 1) % 16}`;
process.env.REDIS_URL = url.toString();
}
process.env.NODE_ENV = 'test';
process.env.JWT_SECRET = process.env.JWT_SECRET || 'test-jwt-secret-key-for-testing';
// Static import is safe: database.ts only reads env in initialize(), which runs
// in beforeAll — well after the env mutations above.
import {testDatabase} from './helpers/database';
// Global test setup
beforeAll(async () => {
// Initialize test database
await testDatabase.initialize();
});
afterEach(async () => {
// Clear all mocks first
vi.clearAllMocks();
// Restore real timers
vi.useRealTimers();
// Clean up database after each test
// This must be last to ensure proper cleanup order
await testDatabase.cleanup();
// Force garbage collection hint (if available in test environment)
if (global.gc) {
global.gc();
}
});
afterAll(async () => {
// Disconnect from database
await testDatabase.disconnect();
});
// Set test environment variables
process.env.NODE_ENV = 'test';
process.env.JWT_SECRET = process.env.JWT_SECRET || 'test-jwt-secret-key-for-testing';