TestProject 3.0.0+
WARNING
本指南介绍的是高级 Node.js API。如果您只是想定义项目,请遵循 "测试项目" 指南。
name
name
是一个由用户指定或 Vitest 自动解析的唯一字符串。如果用户未提供名称,Vitest 会尝试加载项目根目录下的 package.json
文件并从中获取 name
属性。如果没有 package.json
,Vitest 默认使用文件夹的名称。内联项目将使用数字作为名称(自动转换为字符串)。
import { createVitest } from 'vitest/node';
const vitest = await createVitest('test');
vitest.projects.map(p => p.name) === ['@pkg/server', 'utils', '2', 'custom'];
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
'./packages/server', // 包含 package.json,其 name 为 "@pkg/server"
'./utils', // 不包含 package.json 文件
{
// 未自定义名称
test: {
pool: 'threads',
},
},
{
// 自定义了名称
test: {
name: 'custom',
},
},
],
},
});
INFO
如果 根项目 不属于用户项目,则其 name
将不会被解析。
vitest
vitest
引用全局 Vitest
进程。
serializedConfig
这是测试进程接收的配置。Vitest 会手动序列化配置,移除所有无法序列化的函数和属性,以序列化配置。由于此值在测试和 Node 环境中都可用,因此其类型从主入口点导出。
import type { SerializedConfig } from 'vitest';
const config: SerializedConfig = vitest.projects[0].serializedConfig;
WARNING
serializedConfig
属性是一个 getter。每次访问时,Vitest 都会重新序列化配置,以防其内容发生变化。这也意味着它总是返回不同的引用:
project.serializedConfig === project.serializedConfig; // ❌
globalConfig
Vitest
初始化时使用的测试配置。如果这是根项目,globalConfig
和 config
将引用同一个对象。此配置可用于设置项目级别无法设置的选项(例如 coverage
或 reporters
)。
import type { ResolvedConfig } from 'vitest/node';
vitest.config === vitest.projects[0].globalConfig;
config
这是项目最终解析的测试配置。
hash 3.2.0+
此项目的唯一哈希值。此值在多次运行中保持一致。
它基于项目的根目录及其名称。请注意,根路径在不同操作系统之间可能不一致,因此哈希值也会有所不同。
vite
这是项目的 ViteDevServer
。每个项目都有独立的 Vite 服务器。
browser
此值仅在测试运行于浏览器时设置。如果 browser
已启用,但测试尚未运行,则此值将为 undefined
。如果您需要检查项目是否支持浏览器测试,请使用 project.isBrowserEnabled()
方法。
WARNING
浏览器 API 仍处于实验阶段,且不遵循 SemVer 规范。浏览器 API 将与其余 API 分开标准化。
provide
function provide<T extends keyof ProvidedContext & string>(
key: T,
value: ProvidedContext[T]
): void;
除了 config.provide
字段外,此方法还可用于向测试提供自定义值。所有值在存储之前都会通过 structuredClone
进行验证,但 providedContext
中的值本身不会被克隆。
import { createVitest } from 'vitest/node';
const vitest = await createVitest('test');
const project = vitest.projects.find(p => p.name === 'custom');
project.provide('key', 'value');
await vitest.start();
import { inject } from 'vitest';
const value = inject('key');
这些值支持动态提供。测试中提供的值将在其下次运行时更新。
TIP
此方法也适用于全局设置文件,以应对无法使用公共 API 的情况:
export default function setup({ provide }) {
provide('wsPort', 3000);
}
getProvidedContext
function getProvidedContext(): ProvidedContext;
此方法返回上下文对象。每个项目也继承由 vitest.provide
设置的全局上下文。
import { createVitest } from 'vitest/node';
const vitest = await createVitest('test');
vitest.provide('global', true);
const project = vitest.projects.find(p => p.name === 'custom');
project.provide('key', 'value');
// { global: true, key: 'value' }
const context = project.getProvidedContext();
TIP
项目上下文值会覆盖根项目的上下文。
createSpecification
function createSpecification(
moduleId: string,
locations?: number[]
): TestSpecification;
创建可用于 vitest.runTestSpecifications
的 测试规范。此规范将测试文件限定到特定的 project
和测试 locations
(可选)。测试 locations 是源代码中定义测试的代码行位置。如果提供了 locations,Vitest 将只运行在这些行上定义的测试。请注意,如果定义了 testNamePattern
,则它也将被应用。
import { createVitest } from 'vitest/node';
import { resolve } from 'node:path/posix';
const vitest = await createVitest('test');
const project = vitest.projects[0];
const specification = project.createSpecification(
resolve('./example.test.ts'),
[20, 40] // 可选的测试行号
);
await vitest.runTestSpecifications([specification]);
WARNING
createSpecification
需要已解析的 模块 ID。它不会自动解析文件,也不会检查文件系统上是否存在。
另请注意,project.createSpecification
总是返回一个新实例。
isRootProject
function isRootProject(): boolean;
检查当前项目是否是根项目。您也可以通过调用 vitest.getRootProject()
获取根项目。
globTestFiles
function globTestFiles(filters?: string[]): {
/**
* 匹配过滤器的测试文件。
*/
testFiles: string[];
/**
* 匹配过滤器的类型检查测试文件。除非 `typecheck.enabled` 为 `true`,否则此数组将为空。
*/
typecheckTestFiles: string[];
};
查找所有测试文件。此函数返回一个包含常规测试和类型检查测试的对象。
此方法接受 filters
参数。与 Vitest
实例上的其他方法不同,过滤器只能是文件路径的部分内容:
project.globTestFiles(['foo']); // ✅
project.globTestFiles(['basic/foo.js:10']); // ❌
TIP
Vitest 使用 fast-glob 来查找测试文件。test.dir
、test.root
、root
或 process.cwd()
定义 cwd
选项。
此方法查看几个配置选项:
test.include
、test.exclude
用于查找常规测试文件test.includeSource
、test.exclude
用于查找源内测试test.typecheck.include
、test.typecheck.exclude
用于查找类型检查测试
matchesTestGlob
function matchesTestGlob(moduleId: string, source?: () => string): boolean;
此方法用于检查文件是否为常规测试文件。它使用与 globTestFiles
相同的配置属性进行验证。
此方法还接受第二个参数,即文件源代码。这用于验证文件是否是源内测试。如需为多个项目多次调用此方法,建议一次性读取文件内容再直接传递。如果文件不是测试文件,但与 includeSource
glob 匹配,Vitest 将同步读取该文件,除非提供了 source
。
import { createVitest } from 'vitest/node';
import { resolve } from 'node:path/posix';
const vitest = await createVitest('test');
const project = vitest.projects[0];
project.matchesTestGlob(resolve('./basic.test.ts')); // true
project.matchesTestGlob(resolve('./basic.ts')); // false
project.matchesTestGlob(
resolve('./basic.ts'),
() => `
if (import.meta.vitest) {
// ...
}
`
); // 如果设置了 `includeSource` 则为 true
import
function import<T>(moduleId: string): Promise<T>
使用 Vite 模块运行器来导入文件。文件会通过 Vite 使用所提供的项目配置进行转换,并在独立上下文中执行。请注意,moduleId
是相对于 config.root
的。
DANGER
project.import
会复用 Vite 的模块图,因此使用常规导入导入相同的模块将返回不同的模块:
import * as staticExample from './example.js';
const dynamicExample = await project.import('./example.js');
dynamicExample !== staticExample; // ✅
INFO
Vitest 内部使用此方法来导入全局设置、自定义覆盖率提供程序和自定义报告器,这意味着只要它们属于同一个 Vite 服务器,它们就共享相同的模块图。
onTestsRerun
function onTestsRerun(cb: OnTestsRerunHandler): void;
此方法是 project.vitest.onTestsRerun
的快捷方式。它接受一个回调函数,当测试被安排重新运行时(通常是由于文件更改),该回调函数将被执行。
project.onTestsRerun(specs => {
console.log(specs);
});
isBrowserEnabled
function isBrowserEnabled(): boolean;
如果此项目在浏览器中运行测试,则返回 true
。
close
function close(): Promise<void>;
关闭项目及其所有关联资源。此方法只能调用一次;关闭的 Promise 将被缓存直到服务器重启。如果需要再次使用资源,请创建一个新项目。
具体包括:关闭 Vite 服务器、停止类型检查服务、关闭运行中的浏览器、删除存放源代码的临时目录以及重置已提供的上下文。