Vitest 3.0 发布详解:内联工作区、多浏览器实例与全新的 Reporter 生命周期
【免费下载链接】vitestNext generation testing framework powered by Vite.项目地址: https://gitcode.com/GitHub_Trending/vi/vitest
Vitest 3.0 是 Vitest 继 2.0 之后的首个主版本,聚焦于提升大规模测试项目的输出稳定性、配置简洁度与浏览器测试性能。本文基于官方发布公告,并结合当前仓库中的文档与源码,逐一拆解 Reporter 生命周期重构、Inline Workspace、多浏览器instances配置、按行号过滤测试以及vitest/node公共 API 重新设计这五大核心更新,帮助你在升级到 Vitest 3 后快速掌握新配置方式与迁移要点。
版本背景:从 2.0 到 3.0 的半年
Vitest 2.0 发布于半年前,随后经历了大规模采用:官方发布公告记载,其周下载量从 4.8M 增长到 7.7M。生态方面,Storybook 的新测试能力 和 docs/guide/features.md 开始了解基础用法。
注意:上文下载量数据为官方发布公告(docs/blog/vitest-3.md)中记载的当时数据,仅作为历史背景参考。
Reporter 更新:更稳定的输出与更清晰的生命周期
重写测试报告流程
Vitest 3 重写了测试运行报告的底层实现,目标是消除终端输出的"闪烁"(flicker)现象,让报告更稳定。旧的onTaskUpdateAPI 基于任务级更新流,逆向工程它的语义非常困难;新实现用一个结构化的生命周期取而代之。
新的 reporter 生命周期方法定义在 docs/api/advanced/reporters.md 中,完整调用链如下:
onInit:Vitest 初始化后、测试过滤前调用,适合保存Vitest实例引用;onTestRunStart(specifications):新一轮测试运行开始,接收本次将要运行的 测试规格 数组;onTestModuleQueued→onTestModuleCollected→onTestModuleStart:测试模块排队、收集完成、开始执行的三个时点;onTestSuiteReady→onHookStart(beforeAll)…onTestCaseReady→onHookStart(beforeEach)→onTestCaseResult→onHookEnd(afterEach)→onTestSuiteResult:套件与用例级别的细粒度回调,beforeEach/afterEach钩子也被视为测试用例的一部分;onTestModuleEnd、onCoverage、onTestRunEnd(testModules, unhandledErrors, reason):模块结束、覆盖率处理完成以及整轮测试运行结束。
onTestRunEnd的第三个参数reason取值有三种:passed(正常结束无错误)、failed(存在收集或执行错误)、interrupted(被vitest.cancelCurrentRun或终端Ctrl+C中断)。同一模块内的测试按顺序上报,被跳过的测试统一在套件/模块末尾上报;由于测试模块可以并行运行,报告也会以并行方式输出。
通过继承 BaseReporter 快速接入
相比手写全部生命周期方法,更推荐的做法是继承BaseReporter(定义于 packages/vitest/src/node/reporters/base.ts),只覆盖关心的回调:
import { BaseReporter } from 'vitest/node' export default class CustomReporter extends BaseReporter { onTestRunEnd(testModules, errors) { console.log(testModules.length, 'tests finished running') super.onTestRunEnd(testModules, errors) } }这一重构同时简化了公开的reporters配置字段,让生命周期更直观、更容易在自定义 reporter 中定位到正确的挂载点。
Inline Workspace:告别独立工作区配置文件
在 Vitest 2 及更早版本中,定义 workspace(测试项目集合) 需要单独的vitest.workspace.ts文件。Vitest 3 允许直接在vitest.config中通过workspace字段声明一组项目:
import { defineConfig } from 'vitest/config' export default defineConfig({ test: { workspace: ['packages/*'], }, })如上配置会把packages目录下的每个文件夹都视为一个独立项目。后续版本中该字段已更名为projects(自 3.2 起workspace弃用,功能完全相同),两者在配置解析层共用同一套实现,核心逻辑位于 packages/vitest/src/node/projects/resolveProjects.ts。
更丰富的项目匹配语法
projects/workspace支持 glob 通配、取反排除与花括号扩展,例如:
import { defineConfig } from 'vitest/config' export default defineConfig({ test: { projects: [ 'packages/*', '!packages/excluded', ], }, })对于嵌套目录结构,可以用!(...)避免把中间目录误当作项目:
export default defineConfig({ test: { projects: [ 'packages/!(business)', 'packages/business/*', ], }, })项目也可以指向具体的配置文件(如vitest.config.{e2e,unit}.ts),或直接内联对象配置(内联项目默认继承根配置,可用extends: false关闭继承,推荐为内联项目显式指定name)。所有项目名称必须唯一,否则 Vitest 会抛出错误。需要注意:根vitest.config默认不作为项目参与测试,只提供reporters、coverage等全局选项。
Multi-Browser Configuration:单一 Vite 服务器的多浏览器测试
Vitest 3 引入了更高效的多浏览器测试方式:不再依赖 workspace,而是通过browser.instances数组声明多套浏览器/测试环境配置:
import { defineConfig } from 'vitest/config' export default defineConfig({ test: { browser: { provider: 'playwright', instances: [ { browser: 'chromium', launch: { devtools: true }, }, { browser: 'firefox', setupFiles: ['./setup.firefox.ts'], provide: { secret: 'my-secret', }, }, ], }, }, })instances相对 workspace 的核心优势在于缓存策略:Vitest 只创建一个 Vite 服务器来服务文件,无论测试多少个浏览器,文件变换与依赖预打包都只处理一次。从源码结构看,这些实例会在内部被转换为独立的测试项目并共享同一个 Vite 服务器,参见 docs/config/browser/instances.md 中"Under the hood"的说明。
每个 instance 必须至少指定browser字段,可配置项包括headless、locators、viewport、testerHtmlPath、screenshotDirectory、screenshotFailures、provider等,且每个实例都会继承根配置的选项。更完整的组合示例(如两个同名 chromium 实例配合provide注入不同数据)见 docs/guide/browser/multiple-setups.md。同时,本次发布还完善了浏览器模式文档,为 Playwright 与 WebdriverIO 提供了独立配置指南,降低了配置门槛。
Filtering by Location:按文件与行号过滤测试
Vitest 3 支持按行号过滤测试,这对定位特定测试、快速复现失败非常有用:
$ vitest basic/foo.js:10 $ vitest ./basic/foo.js:10该能力与--testNamePattern等现有过滤手段互补,可以在不修改源码的前提下,精确触发某个文件中指定行附近的用例。
Public API 重新设计:vitest/node走向稳定
Vitest 3 重新设计了从vitest/node导出的公共 API,并计划在下一个 minor 版本中移除其 experimental 标签。新的 API 文档覆盖了所有暴露的方法,核心对象包括:
Vitest:start()、standalone()、mergeReports()、runTestSpecifications()、cancelCurrentRun()、collect()等程序化入口,以及config、projects、snapshot、cache、watcher等属性;TestProject、TestModule、TestSuite、TestCase、TestSpecification等实体对象,配合新的 Reporter API 使用。
对于使用程序化 API 的开发者,需要注意在调用runTestSpecifications前,必须根据需求先调用start、standalone或mergeReports之一来正确初始化;内置 CLI 会自动保证方法调用顺序。
Breaking Changes 与迁移建议
Vitest 3 只有少量破坏性变更,预计不会影响大多数用户,但官方仍建议升级前完整阅读迁移指南(见 docs/guide/migration/index.md),完整的变更列表可查阅仓库中的 docs/releases.md 与各版本的发布记录。
结语
Vitest 3.0 通过重构 Reporter 生命周期、内联工作区配置、单一 Vite 服务器的多浏览器实例、按行号过滤以及公共 API 稳定化,显著改善了大型项目的测试体验。升级到 Vitest 3 后,建议优先将独立的 workspace 文件迁移为内联projects配置,并尝试用browser.instances替代浏览器测试的 workspace 方案,以获得更好的缓存性能与更简洁的配置结构。
【免费下载链接】vitestNext generation testing framework powered by Vite.项目地址: https://gitcode.com/GitHub_Trending/vi/vitest
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考