Vitest Global Setup

Back to Blog Listing

Vitest Global Setup

Vitest's globalSetup feature runs code once before all tests execute, and optionally a cleanup function after all tests complete.

Ben HoustonNovember 19, 20254 min read

Vitest's globalSetup feature runs code once before all tests execute, and optionally a cleanup function after all tests complete. Tested on Vitest 2.x through 4.x.

How Global Setup Works#

Common uses:

  • Setting up database connections
  • Configuring environment variables
  • Starting test servers
  • Initializing shared resources

Setting Up the Global Setup File#

Create a file that exports a default async function. Vitest calls it before any tests run. The function receives a TestProject parameter that provides access to Vitest's project configuration.

Basic Structure#

// src/test-utils/beforeTests.ts
import type { TestProject } from 'vitest/node';

export default async function setup(project: TestProject): Promise<void> {
  console.log('Starting global setup for project:', project.name);
  // Your setup code here
  console.log('Global setup complete!');
}

With Cleanup Function#

The setup function can return a cleanup function that will be executed after all tests complete:

// src/test-utils/beforeTests.ts
import type { TestProject } from 'vitest/node';
import afterTests from './afterTests.js';

// the method name doesn't matter, just that it is the default export
export default async function beforeTests(project: TestProject): Promise<() => Promise<void>> {
  console.log('starting beforeTests for project:', project.name);

  // Perform setup tasks
  await new Promise((resolve) => setTimeout(resolve, 1000));

  console.log('finished beforeTests');

  // Return cleanup function that runs after all tests
  return afterTests;
}

The Teardown File#

Create a separate file for your cleanup logic (or you could combine it with the setup file):

// src/test-utils/afterTests.ts
export default async function afterTests(): Promise<void> {
  console.log('starting afterTests');

  // Perform cleanup tasks
  await new Promise((resolve) => setTimeout(resolve, 1000));

  console.log('finished afterTests');
}

Configuring Vitest#

Add the globalSetup option to your vitest.config.ts:

// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
    globalSetup: ['./src/test-utils/beforeTests.ts'],
  },
});

The globalSetup option accepts an array of file paths. Vitest runs these files in order before any tests start. If a setup file returns a cleanup function, Vitest calls it after all tests complete, in reverse order.

Passing Configuration to Tests#

Use process.env to pass values from global setup to your tests:

// src/test-utils/beforeTests.ts
import type { TestProject } from 'vitest/node';

export default async function setup(project: TestProject): Promise<() => Promise<void>> {
  console.log('Starting global setup for project:', project.name);

  // Set environment variables that tests can access
  const DATABASE_URL = 'postgresql://localhost:5432/test';
  process.env['DATABASE_URL'] = DATABASE_URL;
  console.log('DATABASE_URL', DATABASE_URL);

  // Set other configuration values
  process.env['API_KEY'] = 'test-api-key';
  process.env['NODE_ENV'] = 'test';

  // Your setup code here
  await new Promise((resolve) => setTimeout(resolve, 1000));

  console.log('Global setup complete!');

  return async () => {
    // Cleanup: optionally clear environment variables
    console.log('Cleanup complete!');
  };
}

Using Configuration in Tests#

Your tests can now access these environment variables:

// src/database.test.ts
import { describe, it, expect } from 'vitest';

describe('Database', () => {
  it('should connect using DATABASE_URL', () => {
    const dbUrl = process.env['DATABASE_URL'];
    expect(dbUrl).toBe('postgresql://localhost:5432/test');
    // Use dbUrl in your test...
  });
});

Common Use Cases#

Database Setup#

export default async function setup(): Promise<() => Promise<void>> {
  // Connect to test database
  const db = await connectToDatabase();
  process.env['DATABASE_URL'] = db.connectionString;

  // Run migrations
  await db.migrate();

  return async () => {
    // Clean up test data
    await db.cleanup();
    await db.close();
  };
}

API Server Setup#

export default async function setup(): Promise<() => Promise<void>> {
  // Start test server
  const server = await startTestServer();
  process.env['API_URL'] = `http://localhost:${server.port}`;

  return async () => {
    // Stop server
    await server.stop();
  };
}

Environment Configuration#

export default async function setup(): Promise<() => Promise<void>> {
  // Set all test environment variables
  process.env['NODE_ENV'] = 'test';
  process.env['LOG_LEVEL'] = 'error';
  process.env['API_TIMEOUT'] = '5000';

  return async () => {
    // Optionally restore original values
    delete process.env['NODE_ENV'];
  };
}

Conclusion#

Export a default async function from your setup file. Return a cleanup function if you need teardown. Vitest runs the setup before tests start and calls the cleanup when they finish.