Skip to content
On this page

Test Environment

Vitest provides environment option to run code inside a specific environment. You can modify how environment behaves with environmentOptions option.

By default, you can use these environments:

  • node is default environment
  • jsdom emulates browser environment by providing Browser API, uses jsdom package
  • happy-dom emulates browser environment by providing Browser API, and considered to be faster than jsdom, but lacks some API, uses happy-dom package
  • edge-runtime emulates Vercel's edge-runtime, uses @edge-runtime/vm package

Environments for specific files

When setting environment option in your config, it will apply to all the test files in your project. To have more fine-grained control, you can use control comments to specify environment for specific files. Control comments are comments that start with @vitest-environment and are followed by the environment name:

ts
// @vitest-environment jsdom

import { test } from 'vitest'

test('test', () => {
  expect(typeof window).not.toBe('undefined')
})
// @vitest-environment jsdom

import { test } from 'vitest'

test('test', () => {
  expect(typeof window).not.toBe('undefined')
})

Or you can also set environmentMatchGlobs option specifying the environment based on the glob patterns.

Custom Environment

Starting from 0.23.0, you can create your own package to extend Vitest environment. To do so, create package with the name vitest-environment-${name}. That package should export an object with the shape of Environment:

ts
import type { Environment } from 'vitest'

export default <Environment>{
  name: 'custom',
  setup() {
    // custom setup
    return {
      teardown() {
        // called after all tests with this env have been run
      }
    }
  }
}
import type { Environment } from 'vitest'

export default <Environment>{
  name: 'custom',
  setup() {
    // custom setup
    return {
      teardown() {
        // called after all tests with this env have been run
      }
    }
  }
}

You also have access to default Vitest environments through vitest/environments entry:

ts
import { builtinEnvironments, populateGlobal } from 'vitest/environments'

console.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime }
import { builtinEnvironments, populateGlobal } from 'vitest/environments'

console.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime }

Vitest also provides populateGlobal utility function, which can be used to move properties from object into the global namespace:

ts
interface PopulateOptions {
  // should non-class functions be bind to the global namespace
  bindFunctions?: boolean
}

interface PopulateResult {
  // a list of all keys that were copied, even if value doesn't exist on original object
  keys: Set<string>
  // a map of original object that might have been overridden with keys
  // you can return these values inside `teardown` function
  originals: Map<string | symbol, any>
}

export function populateGlobal(global: any, original: any, options: PopulateOptions): PopulateResult
interface PopulateOptions {
  // should non-class functions be bind to the global namespace
  bindFunctions?: boolean
}

interface PopulateResult {
  // a list of all keys that were copied, even if value doesn't exist on original object
  keys: Set<string>
  // a map of original object that might have been overridden with keys
  // you can return these values inside `teardown` function
  originals: Map<string | symbol, any>
}

export function populateGlobal(global: any, original: any, options: PopulateOptions): PopulateResult

Released under the MIT License.