TestProject 3.0.0+
- 别名:在 3.0.0 之前称为
WorkspaceProject
WARNING
本指南描述了高级的 Node.js API。如果我们只是想创建一个工作区,请遵循 Workspace 指南。
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'
]
export default [
'./packages/server', // 有 package.json,名称为 "@pkg/server"
'./utils', // 没有 package.json 文件
{
// 没有自定义名称
test: {
pool: 'threads',
},
},
{
// 自定义了名称
test: {
name: 'custom',
},
},
]
INFO
如果 根项目 不是用户工作区的一部分,则不会解析其 name
。
vitest
vitest
引用全局的 Vitest
进程。
serializedConfig
这是测试进程接收的配置。Vitest 通过手动 序列化配置,删除了所有无法序列化的函数和属性。由于此值在测试和节点中都可用,因此其类型从主入口点导出。
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
这是项目的已解析测试配置。
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
(可选)。测试 位置 是源代码中定义测试的代码行。如果提供了位置,Vitest 将仅运行在这些行上定义的测试。请注意,如果定义了 testNamePattern
,则它也将被应用。
import { resolve } from 'node:path/posix'
import { createVitest } from 'vitest/node'
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
全局匹配,Vitest 将同步读取文件,除非提供了 source
。
import { resolve } from 'node:path/posix'
import { createVitest } from 'vitest/node'
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 服务器,停止类型检查器服务,关闭浏览器(如果正在运行),删除保存源代码的临时目录,并重置提供的上下文。