TestArtifactBase interface structure
TestArtifactBase is the base interface for all test artifacts. It has two optional properties: attachments (an array of TestAttachment objects associated with the artifact) and location (a TestArtifactLocation indicating where the artifact was created). Vitest automatically manages the attachments array and injects the location property.
TestArtifactBase attachments array behavior with api.allowWrite disabled
When running with api.allowWrite disabled, Vitest empties the attachments array on every artifact before reporting it. If a custom artifact narrows the attachments type (for example to a tuple), include | [] in the union so the type reflects what actually happens at runtime.
TestProject name property resolution
The name is a unique string assigned by the user or interpreted by Vitest. If the user does not provide a name, Vitest tries to load package.json in the root of the project and takes the name property from there. If there is no package.json, Vitest uses the name of the folder by default. Inline projects use numbers as the name (converted to string). If the root project is not part of user projects, its name will not be resolved.
TestProject vitest property
The vitest property references the global Vitest process.
TestProject serializedConfig property
serializedConfig is the config that test processes receive. Vitest serializes config manually by removing all functions and properties that are not possible to serialize. This value is available in both tests and node. serializedConfig is a getter that serializes the config again each time it is accessed in case it was changed, which means it always returns a different reference. Accessing project.serializedConfig === project.serializedConfig will be false.
TestProject globalConfig property
globalConfig is the test config that Vitest was initialized with. If the project is the root project, globalConfig and config will reference the same object. This config is useful for values that cannot be set on the project level, like coverage or reporters.
TestProject config property
config is the project's resolved test config.
TestProject hash property
The hash property is the unique hash of the project, consistent between reruns. It is based on the root of the project and its name. The root path is not consistent between different operating systems, so the hash will also be different across systems.
TestProject vite property
The vite property is the project's ViteDevServer. The server is not necessarily exclusive to this project: other projects can reuse it when the sharedViteServer option applies, and browser instances of the same cluster share a single browser server.
TestProject sharedViteServer property
sharedViteServer is a boolean that is true when the project reuses the Vite server of the config that declared it instead of resolving its own. The project that owns the server reports false even when other projects reuse it. To detect any two projects sharing a server (including browser instances), compare their vite references.
TestProject browser property
The browser property will be set only if tests are running in the browser. If browser is enabled but tests did not run yet, this will be undefined. To check if the project supports browser tests, use the project.isBrowserEnabled() method instead.
TestProject provide method signature
The provide method has the signature: function provide<T extends keyof ProvidedContext & string>(key: T, value: ProvidedContext[T]): void. It provides a way to give custom values to tests in addition to the config.provide field. All values are validated with structuredClone before they are stored, but the values on providedContext themselves are not cloned. Values can be provided dynamically and will be updated on their next run in tests. This method is also available to global setup files.
TestProject getProvidedContext method signature
The getProvidedContext method has the signature: function getProvidedContext(): ProvidedContext. It returns the context object. Every project also inherits the global context set by vitest.provide. Project context values will always override root project's context.
TestProject createSpecification method signature
The createSpecification method has the signature: function createSpecification(moduleId: string, locations?: number[]): TestSpecification. It creates a test specification that can be used in vitest.runTestSpecifications. Specification scopes the test file to a specific project and test locations (optional). Test locations are code lines where the test is defined in the source code. If locations are provided, Vitest will only run tests defined on those lines. If testNamePattern is defined, it will also be applied. createSpecification expects resolved module ID and does not auto-resolve the file or check that it exists on the file system. project.createSpecification always returns a new instance.
TestProject isRootProject method signature
The isRootProject method has the signature: function isRootProject(): boolean. It checks if the current project is the root project. The root project can also be retrieved by calling vitest.getRootProject().
TestProject globTestFiles method signature
The globTestFiles method has the signature: function globTestFiles(filters?: string[]): { testFiles: string[], typecheckTestFiles: string[] }. It globs all test files and returns an object with regular tests and typecheck tests (which will be empty unless typecheck.enabled is true). Filters can only be a part of the file path. Vitest uses fast-glob to find test files with cwd defined by test.dir, test.root, root or process.cwd(). This method looks at test.include, test.exclude for regular test files; test.includeSource, test.exclude for in-source tests; and test.typecheck.include, test.typecheck.exclude for typecheck tests.
TestProject matchesTestGlob method signature
The matchesTestGlob method has the signature: function matchesTestGlob(moduleId: string, source?: () => string): boolean. It checks if the file is a regular test file using the same config properties that globTestFiles uses for validation. It also accepts a second parameter which is the source code, used to validate if the file is an in-source test. If calling this method several times for several projects, it is recommended to read the file once and pass it down directly. If the file is not a test file but matches the includeSource glob, Vitest will synchronously read the file unless the source is provided.
TestProject import method behavior
The import method imports a file using Vite module runner. The file will be transformed by Vite with the provided project's config and executed in a separate context. The moduleId will be relative to config.root. project.import reuses Vite's module graph, so importing the same module using a regular import will return a different module. Internally, Vitest uses this method to import global setups, custom coverage providers and custom reporters, meaning all of them share the same module graph as long as they belong to the same Vite server.
TestProject onTestsRerun method signature
The onTestsRerun method has the signature: function onTestsRerun(cb: OnTestsRerunHandler): void. It is a shorthand for project.vitest.onTestsRerun and accepts a callback that will be awaited when the tests have been scheduled to rerun, usually due to a file change.
TestProject isBrowserEnabled method signature
The isBrowserEnabled method has the signature: function isBrowserEnabled(): boolean. It returns true if the project runs tests in the browser.
TestProject close method signature
The close method has the signature: function close(): Promise<void>. It closes the project and all associated resources. This can only be called once; the closing promise is cached until the server restarts. If resources are needed again, create a new project. In detail, this method closes the Vite server, stops the typechecker service, closes the browser if it is running, deletes the temporary directory that holds the source code, and resets the provided context.
TestProject provide method example
Example of providing custom values to tests: In node.js code, import createVitest from 'vitest/node', create a vitest instance, find a project by name, and call project.provide('key', 'value'). Then in test.spec.js, import inject from 'vitest' and use const value = inject('key') to access the provided value.
TestProject getProvidedContext method example
Example of getting provided context: After calling vitest.provide('global', true) and project.provide('key', 'value'), calling project.getProvidedContext() returns { global: true, key: 'value' }. Project context values will always override root project's context.
TestProject createSpecification method example
Example of creating a test specification: import { createVitest } from 'vitest/node' and { resolve } from 'node:path/posix'. Create vitest instance, get first project, call project.createSpecification(resolve('./example.test.ts'), [20, 40]) with optional test lines, then pass the specification to vitest.runTestSpecifications([specification]).
TestProject matchesTestGlob method example
Example of matching test globs: project.matchesTestGlob(resolve('./basic.test.ts')) returns true; project.matchesTestGlob(resolve('./basic.ts')) returns false; project.matchesTestGlob(resolve('./basic.ts'), () => `if (import.meta.vitest) { // ... }`) returns true if includeSource is set.
TestProject name resolution example
Example of project name resolution: With projects at './packages/server' (has package.json with '@pkg/server'), './utils' (no package.json, uses folder name), an inline project without name customization (uses number '2' converted to string), and { test: { name: 'custom' } } (customized name), calling vitest.projects.map(p => p.name) returns ['@pkg/server', 'utils', '2', 'custom'].
TestProject serializedConfig pitfall
Do not compare serializedConfig references as they will always be different. project.serializedConfig === project.serializedConfig is false because serializedConfig is a getter that serializes the config fresh each time it is accessed.
TestProject import pitfall
project.import reuses Vite's module graph, so importing the same module using a regular import will return a different module. import * as staticExample from './example.js' and const dynamicExample = await project.import('./example.js') will have dynamicExample !== staticExample.
TestProject createSpecification pitfall
createSpecification expects resolved module ID. It does not auto-resolve the file or check that it exists on the file system. Always pass resolved paths to this method.
TestProject globTestFiles filter limitations
Filters passed to globTestFiles can only be a part of the file path, unlike in other methods on the Vitest instance. project.globTestFiles(['foo']) is valid, but project.globTestFiles(['basic/foo.js:10']) is not valid.