← Back to blog

May 18, 2026 • 2 min read

Vitest: One Framework, Two Test Types

Run unit and integration tests from the same codebase with separate Vitest configs and file suffix conventions.

TL;DR

Use separate config files with different include patterns to run unit and integration tests independently.

  • vitest
  • testing
  • typescript

Vitest doesn’t have a built-in way to run different test types with different settings. Jest has --testPathPattern. Vitest has something simpler: separate config files.

The setup

One base config:

// vitest.base.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    globals: true,
    passWithNoTests: true,
  },
});

Two project configs that extend it:

// vitest.unit.config.ts
import { defineConfig, mergeConfig } from "vitest/config";
import baseConfig from "./vitest.base";

export default mergeConfig(
  baseConfig,
  defineConfig({
    test: {
      include: ["src/**/*.unit.spec.ts"],
      environment: "node",
    },
  }),
);
// vitest.it.config.ts
import { defineConfig, mergeConfig } from "vitest/config";
import baseConfig from "./vitest.base";

export default mergeConfig(
  baseConfig,
  defineConfig({
    test: {
      include: ["test/**/*.it.spec.ts"],
      environment: "node",
      testTimeout: 120_000,
      pool: "forks",
    },
  }),
);

File names do the filtering. *.unit.spec.ts for unit tests, *.it.spec.ts for integration tests. No projects feature, no regex patterns — just include.

Scripts

{
  "test": "vitest run --config vitest.unit.config.ts && vitest run --config vitest.it.config.ts",
  "test:unit": "vitest run --config vitest.unit.config.ts",
  "test:it": "vitest run --config vitest.it.config.ts"
}

Why this works

Each config is a complete Vitest instance. The include pattern tells Vitest which files to pick up. Unit tests run fast in parallel. Integration tests run with pool: 'forks' and a longer timeout. They don’t interfere with each other.

When to use it

  • Unit tests need different globals, mocks, or environment than integration tests
  • Integration tests need longer timeouts or single-thread execution
  • You want to run one type without filtering with --testNamePattern