运行测试
WARNING
本指南旨在说明如何通过 Node.js 脚本使用高级 API 运行测试。如果您只是想运行测试,可能无需阅读本指南。它主要面向库作者。
请注意,在使用实验性 API 时,重大变更可能不遵循语义版本控制(SemVer),因此请锁定 Vitest 的版本。
Vitest 提供了两种启动方式:
startVitest
:启动 Vitest,检查所需依赖包是否已安装,并立即运行测试。createVitest
:仅启动 Vitest 实例,而不运行任何测试。
startVitest
import { startVitest } from 'vitest/node';
const vitest = await startVitest(
'test',
[], // CLI 过滤器
{}, // 覆盖测试配置
{}, // 覆盖 Vite 配置
{} // 自定义 Vitest 选项
);
const testModules = vitest.state.getTestModules();
for (const testModule of testModules) {
console.log(testModule.moduleId, testModule.ok() ? 'passed' : 'failed');
}
TIP
TestModule
、TestSuite
和 TestCase
API 并非实验性功能,自 Vitest 2.1 起遵循 SemVer 规范。
createVitest
此方法创建 Vitest 实例,但不运行测试。
createVitest
方法不会验证所需依赖包是否已安装,也不遵循 config.standalone
或 config.mergeReports
配置。即使禁用了 watch
模式,Vitest 也不会自动关闭。
import { createVitest } from 'vitest/node';
const vitest = await createVitest(
'test',
{}, // 覆盖测试配置
{}, // 覆盖 Vite 配置
{} // 自定义 Vitest 选项
);
// 当 `vitest.cancelCurrentRun()` 被调用时执行
vitest.onCancel(() => {});
// 在 `vitest.close()` 调用期间执行
vitest.onClose(() => {});
// 当 Vitest 重新运行测试文件时执行
vitest.onTestsRerun(files => {});
try {
// 如果测试失败,此操作会将 process.exitCode 设置为 1,且不会自动关闭进程。
await vitest.start(['my-filter']);
} catch (err) {
// 这可能会抛出以下错误:
// 如果没有找到文件,则抛出 "FilesNotFoundError"
// 如果使用 `--changed` 且仓库未初始化,则抛出 "GitNotFoundError"
} finally {
await vitest.close();
}
如果您打算保留 Vitest
实例,请确保至少调用 init
。这将初始化报告器和覆盖率提供者,但不会运行任何测试。即使您不打算使用 Vitest 观察器,但希望保持实例运行,也建议启用 watch
模式。Vitest 依赖此标志,以确保其某些功能在连续进程中正常工作。
报告器初始化完成后,如果需要手动运行测试,请使用 runTestSpecifications
或 rerunTestSpecifications
。
watcher.on('change', async file => {
const specifications = vitest.getModuleSpecifications(file);
if (specifications.length) {
vitest.invalidateFile(file);
// 如果不希望调用 "reporter.onWatcher*" 钩子函数,则可以使用 `runTestSpecifications`。
await vitest.rerunTestSpecifications(specifications);
}
});
WARNING
上述示例展示了禁用默认观察行为的潜在用例。默认情况下,如果文件更改,Vitest 已经会自动重新运行测试。
另请注意,getModuleSpecifications
不会解析测试文件,除非它们已被 globTestSpecifications
处理。如果文件是新创建的,请改用 project.matchesGlobPattern
:
watcher.on('add', async file => {
const specifications = [];
for (const project of vitest.projects) {
if (project.matchesGlobPattern(file)) {
specifications.push(project.createSpecification(file));
}
}
if (specifications.length) {
await vitest.rerunTestSpecifications(specifications);
}
});
在需要禁用观察器时,您可以从 Vite 5.3 开始传递 server.watch: null
,或者将 server.watch: { ignored: ['*/*'] }
传递给 Vite 配置:
await createVitest(
'test',
{},
{
plugins: [
{
name: 'stop-watcher',
async configureServer(server) {
await server.watcher.close();
},
},
],
server: {
watch: null,
},
}
);