# How to Configure and Execute Vitest Tests Using Vite+'s Bundled Testing Framework

> Learn how to configure and execute Vitest tests with Vite+ using the unified `vp test` command. Streamline your testing workflow without extra package installs for effortless development.

- Repository: [VoidZero/vite-plus](https://github.com/voidzero-dev/vite-plus)
- Tags: how-to-guide
- Published: 2026-03-16

---

**Vite+ bundles Vitest directly into its CLI distribution, enabling developers to configure and run tests via the unified `vp test` command without installing a separate `vitest` package.**

The `voidzero-dev/vite-plus` project integrates Vitest—the official Vite testing framework—into a single binary that handles development, building, and testing. This consolidation eliminates version skew between Vite and Vitest while providing a consistent configuration experience through the standard [`vite.config.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/vite.config.ts) file.

## Configuring the Test Environment in Vite+

Vite+ re-exports Vitest’s configuration types, allowing you to declare test settings within the same configuration object used for your build and development server.

### Declaring Test Configuration in vite.config.ts

Add a `test` field to the object exported by `defineConfig` to configure Vitest options. This field accepts all standard Vitest configuration parameters, including test patterns, coverage settings, and environment options.

```typescript
// vite.config.ts
import { defineConfig } from 'vite-plus';

export default defineConfig({
  plugins: [],
  test: {
    include: ['src/**/*.spec.ts', 'src/**/*.test.ts'],
    environment: 'jsdom',
    coverage: {
      reporter: ['text', 'html'],
    },
  },
});

```

*Source:* [README example lines 56-60](https://github.com/voidzero-dev/vite-plus/blob/main/README.md#L56-L60)

### TypeScript Type Merging for Test Options

The `UserConfig` interface in **[`packages/cli/src/index.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/index.ts)** uses declaration merging to include the `test` field, providing full TypeScript autocomplete and type checking for Vitest options within your Vite+ configuration.

```typescript
// packages/cli/src/index.ts – declaration merging
declare module '@voidzero-dev/vite-plus-core' {
  interface UserConfig {
    test?: VitestConfig;   // imported from Vitest
  }
}

```

*Source:* [index.ts lines 10-30](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/index.ts#L10-L30)

## Executing Tests with the VP CLI

The `vp test` command invokes the bundled Vitest binary through a Rust-based execution layer, handling environment setup and process spawning automatically.

### Resolving the Bundled Vitest Binary

When you run `vp test`, the CLI handler calls **[`resolve-test.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/resolve-test.ts)**, which constructs the absolute path to the Vitest entry point located at [`dist/cli.js`](https://github.com/voidzero-dev/vite-plus/blob/main/dist/cli.js) inside the `@voidzero-dev/vite-plus-test` package. The function returns both the binary path and a set of required environment variables to the Rust core.

```typescript
// packages/cli/src/resolve-test.ts
export async function test(): Promise<{ binPath: string; envs: Record<string,string> }> {
  const binPath = join(dirname(resolve('@voidzero-dev/vite-plus-test')), 'dist', 'cli.js');
  // ...
}

```

*Source:* [resolve-test.ts line 30-34](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/resolve-test.ts#L30-L34)

### Passing CLI Flags and Arguments

Pass any standard Vitest CLI flags after a double-dash (`--`) to the `vp test` command. The Rust core forwards these arguments directly to the spawned Vitest process.

```bash

# Run all tests once

vp test

# Enable watch mode

vp test -- --watch

# Generate coverage reports

vp test -- --coverage

# Run a specific test file

vp test -- tests/unit/example.test.ts

```

## Environment Variables and Test Execution

Vite+ automatically injects specific environment variables when spawning Vitest. These defaults are defined in **[`packages/cli/src/utils/constants.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/utils/constants.ts)** and include `VITE_TEST_MODE=1` to signal test execution context.

```typescript
// packages/cli/src/utils/constants.ts
export const DEFAULT_ENVS = {
  VITE_TEST_MODE: '1',
  // ...other defaults
};

```

*Source:* [constants.ts line 1-5](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/utils/constants.ts#L1-L5)

You can override behavior using additional environment variables. For example, setting `DEBUG_DISABLE_SOURCE_MAP` disables source map generation for faster debugging sessions.

```bash
DEBUG_DISABLE_SOURCE_MAP=1 vp test -- --verbose

```

## The Execution Flow Under the Hood

The test execution follows a specific orchestration between the Rust core and JavaScript resolver:

1. **CLI Entry** – `vp test` invokes the Rust core (`vite_task`) with the `test` sub-command.
2. **Resolution** – The Rust core calls [`resolve-test.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/resolve-test.ts) to retrieve the `binPath` and environment variables.
3. **Process Spawn** – The core spawns a Node.js process pointing at the bundled Vitest CLI ([`cli.js`](https://github.com/voidzero-dev/vite-plus/blob/main/cli.js)).
4. **Config Loading** – Vitest reads the `test` section from your Vite+ config file, treating it identically to a standalone [`vitest.config.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/vitest.config.ts).
5. **Output** – Test results report through Vite+'s unified output utilities (`vite_shared::output`).

This architecture provides a **single binary** (`vp`) that manages dev servers, linting, formatting, building, and testing.

## Summary

- **Unified Configuration**: Define Vitest settings within [`vite.config.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/vite.config.ts) using the `test` field, with full TypeScript support via declaration merging in [`packages/cli/src/index.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/index.ts).
- **Bundled Binary**: Vite+ includes Vitest internally; `vp test` resolves the binary path via [`packages/cli/src/resolve-test.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/resolve-test.ts) without requiring a separate installation.
- **CLI Flexibility**: Pass Vitest-specific flags after `--` to `vp test` for watch mode, coverage, or file-specific execution.
- **Environment Injection**: The CLI automatically sets `VITE_TEST_MODE=1` and other defaults from [`packages/cli/src/utils/constants.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/utils/constants.ts) when spawning test processes.

## Frequently Asked Questions

### Do I need to install Vitest separately when using Vite+?

No. Vite+ bundles Vitest inside the `@voidzero-dev/vite-plus-test` package and resolves it automatically through the `vp test` command. The binary path is located at [`dist/cli.js`](https://github.com/voidzero-dev/vite-plus/blob/main/dist/cli.js) within the bundled package, eliminating the need for a separate `vitest` dependency in your [`package.json`](https://github.com/voidzero-dev/vite-plus/blob/main/package.json).

### Can I use a separate [`vitest.config.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/vitest.config.ts) file instead of the `test` field in [`vite.config.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/vite.config.ts)?

While Vite+ reads Vitest configuration from the `test` field in your unified config, Vitest itself will still recognize a dedicated [`vitest.config.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/vitest.config.ts) if present. However, using the unified [`vite.config.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/vite.config.ts) approach is recommended to maintain a single source of configuration truth and leverage the type definitions in [`packages/cli/src/index.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/index.ts).

### How do I enable watch mode or coverage reporting?

Pass the appropriate flags after a double-dash: `vp test -- --watch` enables file watching, while `vp test -- --coverage` generates coverage reports. These arguments are forwarded directly to the bundled Vitest process by the Rust core, behaving identically to running standalone Vitest.

### What happens if the bundled Vitest version differs from my project's expectations?

Vite+ pins a specific Vitest version within its bundle to ensure compatibility with the `vp` CLI's Rust core and resolver logic. This eliminates version skew issues common when managing separate Vite and Vitest installations, guaranteeing that the [`resolve-test.ts`](https://github.com/voidzero-dev/vite-plus/blob/main/resolve-test.ts) resolver and `DEFAULT_ENVS` constants remain synchronized with the test runner.