diff --git a/.vitepress/components.d.ts b/.vitepress/components.d.ts
index 2977c6af..04e66fb9 100644
--- a/.vitepress/components.d.ts
+++ b/.vitepress/components.d.ts
@@ -2,21 +2,23 @@
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
-// biome-ignore lint: disable
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
+ Advanced: typeof import('./components/Advanced.vue')['default']
ArrowDown: typeof import('./components/ArrowDown.vue')['default']
BlogIndex: typeof import('./components/BlogIndex.vue')['default']
Box: typeof import('./components/Box.vue')['default']
Contributors: typeof import('./components/Contributors.vue')['default']
CourseLink: typeof import('./components/CourseLink.vue')['default']
+ CRoot: typeof import('./components/CRoot.vue')['default']
+ Deprecated: typeof import('./components/Deprecated.vue')['default']
+ Experimental: typeof import('./components/Experimental.vue')['default']
FeaturesList: typeof import('./components/FeaturesList.vue')['default']
HomePage: typeof import('./components/HomePage.vue')['default']
ListItem: typeof import('./components/ListItem.vue')['default']
- NonProjectOption: typeof import('./components/NonProjectOption.vue')['default']
Version: typeof import('./components/Version.vue')['default']
}
}
diff --git a/.vitepress/components/Advanced.vue b/.vitepress/components/Advanced.vue
new file mode 100644
index 00000000..7bc97ede
--- /dev/null
+++ b/.vitepress/components/Advanced.vue
@@ -0,0 +1,5 @@
+
+
+ advanced
+
+
diff --git a/.vitepress/components/CRoot.vue b/.vitepress/components/CRoot.vue
new file mode 100644
index 00000000..31a5f0bf
--- /dev/null
+++ b/.vitepress/components/CRoot.vue
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.vitepress/components/Deprecated.vue b/.vitepress/components/Deprecated.vue
new file mode 100644
index 00000000..9ae99627
--- /dev/null
+++ b/.vitepress/components/Deprecated.vue
@@ -0,0 +1,5 @@
+
+
+ deprecated
+
+
diff --git a/.vitepress/components/Experimental.vue b/.vitepress/components/Experimental.vue
new file mode 100644
index 00000000..18681c68
--- /dev/null
+++ b/.vitepress/components/Experimental.vue
@@ -0,0 +1,5 @@
+
+
+ experimental
+
+
diff --git a/.vitepress/components/FeaturesList.vue b/.vitepress/components/FeaturesList.vue
index dd43d850..716523f9 100644
--- a/.vitepress/components/FeaturesList.vue
+++ b/.vitepress/components/FeaturesList.vue
@@ -33,7 +33,8 @@
内置
- Tinyspy 用于对象 Mock
+ Tinyspy 用于对象
+ Mock
使用
diff --git a/.vitepress/components/NonProjectOption.vue b/.vitepress/components/NonProjectOption.vue
deleted file mode 100644
index 87e1ae66..00000000
--- a/.vitepress/components/NonProjectOption.vue
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- *
-
-
diff --git a/.vitepress/components/Version.vue b/.vitepress/components/Version.vue
index a0742ce9..da9c803e 100644
--- a/.vitepress/components/Version.vue
+++ b/.vitepress/components/Version.vue
@@ -1,9 +1,16 @@
-
+
+
diff --git a/.vitepress/config.ts b/.vitepress/config.ts
index dc3b7f0a..56f778e0 100644
--- a/.vitepress/config.ts
+++ b/.vitepress/config.ts
@@ -1,5 +1,3 @@
-import type { DefaultTheme } from 'vitepress'
-import process from 'node:process'
import { transformerNotationWordHighlight } from '@shikijs/transformers'
import { transformerTwoslash } from '@shikijs/vitepress-twoslash'
import { withPwa } from '@vite-pwa/vitepress'
@@ -8,6 +6,7 @@ import {
groupIconMdPlugin,
groupIconVitePlugin,
} from 'vitepress-plugin-group-icons'
+import llmstxt from 'vitepress-plugin-llms'
import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
import { version } from '../package.json'
import { teamMembers } from './contributors'
@@ -28,696 +27,1064 @@ import { pwa } from './scripts/pwa'
import { transformHead } from './scripts/transformHead'
export default ({ mode }: { mode: string }) => {
- return withPwa(
- defineConfig({
- lang: 'en-US',
- title: vitestName,
- description: vitestDescription,
- srcExclude: ['**/guide/examples/*', '**/guide/cli-generated.md'],
- locales: {
- root: {
- label: '简体中文',
- lang: 'zh',
- },
- zh: {
- label: 'English',
- lang: 'en-US',
- link: 'https://vitest.dev/',
- },
+ return withPwa(defineConfig({
+ lang: 'en-US',
+ title: vitestName,
+ description: vitestDescription,
+ srcExclude: [
+ '**/guide/examples/*',
+ '**/guide/cli-generated.md',
+ ],
+ locales: {
+ root: {
+ label: '简体中文',
+ lang: 'zh',
},
- head: [
- ['meta', { name: 'theme-color', content: '#729b1a' }],
- ['link', { rel: 'icon', href: '/favicon.ico', sizes: '48x48' }],
- [
- 'link',
- {
- rel: 'icon',
- href: '/logo.svg',
- sizes: 'any',
- type: 'image/svg+xml',
- },
- ],
- [
- 'meta',
- {
- name: 'author',
- content: `${teamMembers
- .map(c => c.name)
- .join(', ')} and ${vitestName} contributors`,
- },
- ],
- [
- 'meta',
- {
- name: 'keywords',
- content:
- 'vitest, vite, test, coverage, snapshot, react, vue, preact, svelte, solid, lit, marko, ruby, cypress, puppeteer, jsdom, happy-dom, test-runner, jest, typescript, esm, tinypool, tinyspy, node',
- },
- ],
- ['meta', { property: 'og:title', content: vitestName }],
- ['meta', { property: 'og:description', content: vitestDescription }],
- ['meta', { property: 'og:url', content: ogUrl }],
- ['meta', { property: 'og:image', content: ogImage }],
- ['meta', { name: 'twitter:card', content: 'summary_large_image' }],
- [
- 'link',
- {
- rel: 'preload',
- as: 'style',
- onload: 'this.onload=null;this.rel=\'stylesheet\'',
- href: font,
- },
- ],
- [
- 'noscript',
- {},
- ``,
- ],
- ['link', { rel: 'me', href: 'https://m.webtoo.ls/@vitest' }],
- ['link', { rel: 'mask-icon', href: '/logo.svg', color: '#ffffff' }],
- [
- 'link',
- {
- rel: 'apple-touch-icon',
- href: '/apple-touch-icon.png',
- sizes: '180x180',
+ zh: {
+ label: 'English',
+ lang: 'en-US',
+ link: 'https://vitest.dev/',
+ },
+ },
+ head: [
+ ['meta', { name: 'theme-color', content: '#729b1a' }],
+ ['link', { rel: 'icon', href: '/favicon.ico', sizes: '48x48' }],
+ ['link', { rel: 'icon', href: '/logo.svg', sizes: 'any', type: 'image/svg+xml' }],
+ ['meta', { name: 'author', content: `${teamMembers.map(c => c.name).join(', ')} and ${vitestName} contributors` }],
+ ['meta', { name: 'keywords', content: 'vitest, vite, test, coverage, snapshot, react, vue, preact, svelte, solid, lit, marko, ruby, cypress, puppeteer, jsdom, happy-dom, test-runner, jest, typescript, esm, tinyspy, node' }],
+ ['meta', { property: 'og:title', content: vitestName }],
+ ['meta', { property: 'og:description', content: vitestDescription }],
+ ['meta', { property: 'og:url', content: ogUrl }],
+ ['meta', { property: 'og:image', content: ogImage }],
+ ['meta', { name: 'twitter:card', content: 'summary_large_image' }],
+ ['link', { rel: 'preload', as: 'style', onload: 'this.onload=null;this.rel=\'stylesheet\'', href: font }],
+ ['noscript', {}, ``],
+ ['link', { rel: 'me', href: 'https://m.webtoo.ls/@vitest' }],
+ ['link', { rel: 'mask-icon', href: '/logo.svg', color: '#ffffff' }],
+ ['link', { rel: 'apple-touch-icon', href: '/apple-touch-icon.png', sizes: '180x180' }],
+ ],
+ lastUpdated: true,
+ vite: {
+ plugins: [
+ groupIconVitePlugin({
+ customIcon: {
+ 'CLI': 'vscode-icons:file-type-shell',
+ 'vitest.shims': 'vscode-icons:file-type-vitest',
+ 'vitest.config': 'vscode-icons:file-type-vitest',
+ 'vitest.workspace': 'vscode-icons:file-type-vitest',
+ '.spec.ts': 'vscode-icons:file-type-testts',
+ '.test.ts': 'vscode-icons:file-type-testts',
+ '.spec.js': 'vscode-icons:file-type-testjs',
+ '.test.js': 'vscode-icons:file-type-testjs',
+ 'marko': 'vscode-icons:file-type-marko',
+ 'qwik': 'logos:qwik-icon',
+ 'next': '',
},
- ],
+ }) as any,
+ llmstxt(),
],
- lastUpdated: true,
- vite: {
- plugins: [
- groupIconVitePlugin({
- customIcon: {
- 'CLI': 'vscode-icons:file-type-shell',
- 'vitest.shims': 'vscode-icons:file-type-vitest',
- 'vitest.config': 'vscode-icons:file-type-vitest',
- 'vitest.workspace': 'vscode-icons:file-type-vitest',
- '.spec.ts': 'vscode-icons:file-type-testts',
- '.test.ts': 'vscode-icons:file-type-testts',
- '.spec.js': 'vscode-icons:file-type-testjs',
- '.test.js': 'vscode-icons:file-type-testjs',
- 'marko': 'vscode-icons:file-type-marko',
- 'qwik': 'logos:qwik-icon',
- 'next': '',
- },
- }) as any,
- ],
+ },
+ markdown: {
+ config(md) {
+ md.use(tabsMarkdownPlugin)
+ md.use(groupIconMdPlugin)
},
- markdown: {
- config(md) {
- md.use(tabsMarkdownPlugin)
- md.use(groupIconMdPlugin)
- },
- theme: {
- light: 'github-light',
- dark: 'github-dark',
- },
- codeTransformers:
- mode === 'development'
- ? [transformerNotationWordHighlight()]
- : [
- transformerNotationWordHighlight(),
- transformerTwoslash({
- processHoverInfo: (info) => {
- if (info.includes(process.cwd())) {
- return info.replace(new RegExp(process.cwd(), 'g'), '')
- }
- return info
- },
- }),
- ],
- languages: ['js', 'jsx', 'ts', 'tsx'],
+ theme: {
+ light: 'github-light',
+ dark: 'github-dark',
},
- themeConfig: {
- logo: '/logo.svg',
-
- outline: {
- label: '页面导航',
- },
-
- editLink: {
- pattern: 'https://github.com/vitest-dev/docs-cn/edit/dev/:path',
- text: '在 GitHub 上编辑此页面',
- },
+ codeTransformers: mode === 'development'
+ ? [transformerNotationWordHighlight()]
+ : [
+ transformerNotationWordHighlight(),
+ transformerTwoslash({
+ processHoverInfo: (info) => {
+ if (info.includes(process.cwd())) {
+ return info.replace(new RegExp(process.cwd(), 'g'), '')
+ }
+ return info
+ },
+ }),
+ ],
+ languages: ['js', 'jsx', 'ts', 'tsx'],
+ },
+ themeConfig: {
+ logo: '/logo.svg',
- lastUpdated: {
- text: '最后更新于',
- formatOptions: {
- dateStyle: 'full',
- timeStyle: 'medium',
- },
- },
+ editLink: {
+ pattern: 'https://github.com/vitest-dev/docs-cn/edit/dev/:path',
+ text: '在 GitHub 上编辑此页面',
+ },
- search: {
- provider: 'local',
- },
+ search: {
+ provider: 'local',
+ /* provider: 'algolia',
+ options: {
+ appId: 'ZTF29HGJ69',
+ apiKey: '9c3ced6fed60d2670bb36ab7e8bed8bc',
+ indexName: 'vitest',
+ // searchParameters: {
+ // facetFilters: ['tags:en'],
+ // },
+ }, */
+ },
- docFooter: {
- prev: '上一页',
- next: '下一页',
- },
+ carbonAds: {
+ code: 'CW7DVKJE',
+ placement: 'vitestdev',
+ },
- carbonAds: {
- code: 'CW7DVKJE',
- placement: 'vitestdev',
- },
+ socialLinks: [
+ { icon: 'bluesky', link: bluesky },
+ { icon: 'mastodon', link: mastodon },
+ { icon: 'discord', link: discord },
+ { icon: 'github', link: github },
+ ],
- socialLinks: [
- { icon: 'bluesky', link: bluesky },
- { icon: 'mastodon', link: mastodon },
- { icon: 'discord', link: discord },
- { icon: 'github', link: github },
- ],
+ footer: {
+ message: 'Released under the MIT License.',
+ copyright: 'Copyright © 2021-PRESENT VoidZero Inc. and Vitest contributors',
+ },
- footer: {
- message: 'Released under the MIT License.',
- copyright:
- 'Copyright © 2021-PRESENT VoidZero Inc. and Vitest contributors',
+ nav: [
+ { text: '指南', link: '/guide/', activeMatch: '^/guide/' },
+ { text: 'API', link: '/api/', activeMatch: '^/api/' },
+ { text: '配置', link: '/config/', activeMatch: '^/config/' },
+ {
+ text: '博客',
+ link: '/blog',
},
-
- nav: [
- {
- text: '指南 & API',
- link: '/guide/',
- activeMatch: '^/(guide|api)/(?!browser)',
- },
- { text: '配置', link: '/config/', activeMatch: '^/config/' },
- {
- text: '浏览器模式',
- link: '/guide/browser',
- activeMatch: '^/guide/browser/',
- },
- {
- text: '相关链接',
- items: [
- {
- text: '高级 API',
- link: '/advanced/api/',
- activeMatch: '^/advanced/',
- },
- {
- items: [
- {
- text: '博客',
- link: '/blog',
- },
- {
- text: '团队',
- link: '/team',
- },
- ],
- },
- ],
- },
- {
- text: `v${version}`,
- items: [
- {
- items: [
- {
- text: `v${version}`,
- link: `https://github.com/vitest-dev/vitest/releases/tag/v${version}`,
- },
- {
- text: '更新日志',
- link: releases,
- },
- {
- text: '贡献指南',
- link: contributing,
- },
- ],
- },
- {
- items: [
- {
- text: '未发布',
- link: 'https://main.vitest.dev/',
- },
- {
- text: 'v0.x',
- link: 'https://v0.vitest.dev/',
- },
- {
- text: 'v1.x',
- link: 'https://v1.vitest.dev/',
- },
- {
- text: 'v2.x',
- link: 'https://v2.vitest.dev/',
- },
- {
- text: 'v3.x',
- link: 'https://v3.cn.vitest.dev/',
- },
- ],
- },
- ],
- },
- ],
-
- sidebar: {
- '/guide/browser': [
- {
- text: '介绍',
- collapsed: false,
- items: [
- {
- text: '什么是浏览器模式',
- link: '/guide/browser/why',
- docFooterText: '什么是浏览器模式 | 浏览器模式',
- },
- {
- text: '快速起步',
- link: '/guide/browser/',
- docFooterText: '快速起步 | 浏览器模式',
- },
- ],
- },
- {
- text: '配置',
- collapsed: false,
- items: [
- {
- text: '浏览器配置',
- link: '/guide/browser/config',
- docFooterText: '浏览器配置 | 浏览器模式',
- },
- {
- text: '配置 Playwright',
- link: '/guide/browser/playwright',
- docFooterText: '配置 Playwright | 浏览器模式',
- },
- {
- text: '配置 WebdriverIO',
- link: '/guide/browser/webdriverio',
- docFooterText: '配置 WebdriverIO | 浏览器模式',
- },
- {
- text: 'Configuring Preview',
- link: '/guide/browser/preview',
- docFooterText: 'Configuring Preview | 浏览器模式',
- },
- ],
- },
- {
- text: 'API',
- collapsed: false,
- items: [
- {
- text: 'Context API',
- link: '/guide/browser/context',
- docFooterText: 'Context API | 浏览器模式',
- },
- {
- text: 'Interactivity API',
- link: '/guide/browser/interactivity-api',
- docFooterText: 'Interactivity API | 浏览器模式',
- },
- {
- text: 'Locators',
- link: '/guide/browser/locators',
- docFooterText: 'Locators | 浏览器模式',
- },
- {
- text: 'Assertion API',
- link: '/guide/browser/assertion-api',
- docFooterText: 'Assertion API | 浏览器模式',
- },
- {
- text: 'Commands API',
- link: '/guide/browser/commands',
- docFooterText: 'Commands API | 浏览器模式',
- },
- ],
- },
- {
- text: '指南',
- collapsed: false,
- items: [
- {
- text: '多环境配置',
- link: '/guide/browser/multiple-setups',
- docFooterText: '多环境配置 | 浏览器模式',
- },
- {
- text: '组件测试',
- link: '/guide/browser/component-testing',
- docFooterText: '组件测试 | 浏览器模式',
- },
- {
- text: '可视化回归测试',
- link: '/guide/browser/visual-regression-testing',
- docFooterText: '可视化回归测试 | 浏览器模式',
- },
- {
- text: '跟踪查看器',
- link: '/guide/browser/trace-view',
- docFooterText: '跟踪查看器 | 浏览器模式',
- },
- ],
- },
- {
- items: [
- ...footer(),
- {
- text: 'Node API',
- link: '/advanced/api/',
- },
- ],
- },
- ],
- '/advanced': [
+ {
+ text: `v${version}`,
+ items: [
{
- text: 'API',
- collapsed: false,
items: [
{
- text: 'Node API',
- items: [
- {
- text: '快速起步',
- link: '/advanced/api/',
- },
- {
- text: 'Vitest',
- link: '/advanced/api/vitest',
- },
- {
- text: 'TestProject',
- link: '/advanced/api/test-project',
- },
- {
- text: 'TestSpecification',
- link: '/advanced/api/test-specification',
- },
- ],
- },
- {
- text: 'Test Task API',
- items: [
- {
- text: 'TestCase',
- link: '/advanced/api/test-case',
- },
- {
- text: 'TestSuite',
- link: '/advanced/api/test-suite',
- },
- {
- text: 'TestModule',
- link: '/advanced/api/test-module',
- },
- {
- text: 'TestCollection',
- link: '/advanced/api/test-collection',
- },
- ],
- },
- {
- text: '插件 API',
- link: '/advanced/api/plugin',
+ text: `v${version}`,
+ link: `https://github.com/vitest-dev/vitest/releases/tag/v${version}`,
},
{
- text: '运行器 API',
- link: '/advanced/runner',
+ text: '更新日志',
+ link: releases,
},
{
- text: '报告器 API',
- link: '/advanced/api/reporters',
+ text: '贡献指南',
+ link: contributing,
},
{
- text: '任务元数据',
- link: '/advanced/metadata',
+ text: '团队',
+ link: '/team',
},
],
},
{
- text: '指南',
- collapsed: false,
items: [
{
- text: '运行测试',
- link: '/advanced/guide/tests',
- },
- {
- text: '扩展报告器',
- link: '/advanced/reporters',
+ text: '未发布',
+ link: 'https://main.vitest.dev/',
},
{
- text: '自定义运行池',
- link: '/advanced/pool',
+ text: 'v0.x',
+ link: 'https://v0.vitest.dev/',
},
- ],
- },
- {
- items: footer(),
- },
- ],
- '/team': [],
- '/blog': [],
- '/': [
- {
- text: '简介',
- collapsed: false,
- items: introduction(),
- },
- {
- text: 'API',
- collapsed: false,
- items: api(),
- },
- {
- text: '指南',
- collapsed: false,
- items: guide(),
- },
- {
- items: [
{
- text: '浏览器模式',
- link: '/guide/browser',
+ text: 'v1.x',
+ link: 'https://v1.vitest.dev/',
},
{
- text: 'Node API',
- link: '/advanced/api',
+ text: 'v2.x',
+ link: 'https://v2.vitest.dev/',
},
{
- text: '测试框架对比',
- link: '/guide/comparisons',
+ text: 'v3.x',
+ link: 'https://v3.cn.vitest.dev/',
},
],
},
],
},
- },
- pwa,
- transformHead,
- }),
- )
-}
-
-function footer(): DefaultTheme.SidebarItem[] {
- return [
- {
- text: '配置索引',
- link: '/config/',
- },
- {
- text: 'Test API',
- link: '/api/',
- },
- ]
-}
-
-function introduction(): DefaultTheme.SidebarItem[] {
- return [
- {
- text: '为什么是vitest?',
- link: '/guide/why',
- },
- {
- text: '快速起步',
- link: '/guide/',
- },
- {
- text: '主要功能',
- link: '/guide/features',
- },
- {
- text: '配置索引',
- link: '/config/',
- },
- ]
-}
-
-function guide(): DefaultTheme.SidebarItem[] {
- return [
- {
- text: '命令行界面',
- link: '/guide/cli',
- },
- {
- text: '测试筛选',
- link: '/guide/filtering',
- },
- {
- text: '测试项目',
- link: '/guide/projects',
- },
- {
- text: '报告器',
- link: '/guide/reporters',
- },
- {
- text: '覆盖率',
- link: '/guide/coverage',
- },
- {
- text: '快照',
- link: '/guide/snapshot',
- },
- {
- text: '模拟对象',
- link: '/guide/mocking',
- collapsed: true,
- items: [
- {
- text: '模拟日期',
- link: '/guide/mocking/dates',
- },
- {
- text: '模拟函数',
- link: '/guide/mocking/functions',
- },
- {
- text: '模拟全局对象',
- link: '/guide/mocking/globals',
- },
- {
- text: '模拟模块',
- link: '/guide/mocking/modules',
- },
- {
- text: '模拟文件系统',
- link: '/guide/mocking/file-system',
- },
- {
- text: '模拟请求',
- link: '/guide/mocking/requests',
- },
- {
- text: '模拟计时器',
- link: '/guide/mocking/timers',
- },
- {
- text: '模拟类',
- link: '/guide/mocking/classes',
- },
- ],
- },
- {
- text: '并行性',
- link: '/guide/parallelism',
- },
- {
- text: '类型测试',
- link: '/guide/testing-types',
- },
- {
- text: 'UI 模式',
- link: '/guide/ui',
- },
- {
- text: '源码内联测试',
- link: '/guide/in-source',
- },
- {
- text: '测试上下文',
- link: '/guide/test-context',
- },
- {
- text: '测试环境',
- link: '/guide/environment',
- },
- {
- text: '扩展断言',
- link: '/guide/extending-matchers',
- },
- {
- text: 'IDE 插件',
- link: '/guide/ide',
- },
- {
- text: '调试',
- link: '/guide/debugging',
- },
- {
- text: '常见错误',
- link: '/guide/common-errors',
- },
- {
- text: '迁移指南',
- link: '/guide/migration',
- collapsed: false,
- items: [
- {
- text: '迁移到 Vitest 4.0',
- link: '/guide/migration#vitest-4',
- },
- {
- text: '从 Jest 迁移',
- link: '/guide/migration#jest',
- },
- ],
- },
- {
- text: '性能',
- collapsed: false,
- items: [
- {
- text: '性能测试分析',
- link: '/guide/profiling-test-performance',
- },
- {
- text: '性能优化',
- link: '/guide/improving-performance',
- },
],
- },
- ]
-}
-function api(): DefaultTheme.SidebarItem[] {
- return [
- {
- text: 'Test API',
- link: '/api/',
- },
- {
- text: 'Mocks',
- link: '/api/mock',
- },
- {
- text: 'Vi Utility',
- link: '/api/vi',
- },
- {
- text: 'Expect',
- link: '/api/expect',
- },
- {
- text: 'ExpectTypeOf',
- link: '/api/expect-typeof',
- },
- {
- text: 'Assert',
- link: '/api/assert',
- },
- {
- text: 'AssertType',
- link: '/api/assert-type',
+ sidebar: {
+ '/config': [
+ {
+ text: 'Config Reference',
+ collapsed: false,
+ items: [
+ {
+ text: 'Config File',
+ link: '/config/',
+ },
+ {
+ text: 'include',
+ link: '/config/include',
+ },
+ {
+ text: 'exclude',
+ link: '/config/exclude',
+ },
+ {
+ text: 'includeSource',
+ link: '/config/include-source',
+ },
+ {
+ text: 'name',
+ link: '/config/name',
+ },
+ {
+ text: 'server',
+ link: '/config/server',
+ },
+ {
+ text: 'deps',
+ link: '/config/deps',
+ },
+ {
+ text: 'runner',
+ link: '/config/runner',
+ },
+ {
+ text: 'benchmark',
+ link: '/config/benchmark',
+ },
+ {
+ text: 'alias',
+ link: '/config/alias',
+ },
+ {
+ text: 'globals',
+ link: '/config/globals',
+ },
+ {
+ text: 'environment',
+ link: '/config/environment',
+ },
+ {
+ text: 'environmentOptions',
+ link: '/config/environmentoptions',
+ },
+ {
+ text: 'watch',
+ link: '/config/watch',
+ },
+ {
+ text: 'watchTriggerPatterns',
+ link: '/config/watchtriggerpatterns',
+ },
+ {
+ text: 'root',
+ link: '/config/root',
+ },
+ {
+ text: 'dir',
+ link: '/config/dir',
+ },
+ {
+ text: 'reporters',
+ link: '/config/reporters',
+ },
+ {
+ text: 'outputFile',
+ link: '/config/outputfile',
+ },
+ {
+ text: 'pool',
+ link: '/config/pool',
+ },
+ {
+ text: 'execArgv',
+ link: '/config/execargv',
+ },
+ {
+ text: 'vmMemoryLimit',
+ link: '/config/vmmemorylimit',
+ },
+ {
+ text: 'fileParallelism',
+ link: '/config/fileparallelism',
+ },
+ {
+ text: 'maxWorkers',
+ link: '/config/maxworkers',
+ },
+ {
+ text: 'testTimeout',
+ link: '/config/testtimeout',
+ },
+ {
+ text: 'hookTimeout',
+ link: '/config/hooktimeout',
+ },
+ {
+ text: 'teardownTimeout',
+ link: '/config/teardowntimeout',
+ },
+ {
+ text: 'silent',
+ link: '/config/silent',
+ },
+ {
+ text: 'setupFiles',
+ link: '/config/setupfiles',
+ },
+ {
+ text: 'provide',
+ link: '/config/provide',
+ },
+ {
+ text: 'globalSetup',
+ link: '/config/globalsetup',
+ },
+ {
+ text: 'forceRerunTriggers',
+ link: '/config/forcereruntriggers',
+ },
+ {
+ text: 'coverage',
+ link: '/config/coverage',
+ },
+ {
+ text: 'testNamePattern',
+ link: '/config/testnamepattern',
+ },
+ {
+ text: 'ui',
+ link: '/config/ui',
+ },
+ {
+ text: 'open',
+ link: '/config/open',
+ },
+ {
+ text: 'api',
+ link: '/config/api',
+ },
+ {
+ text: 'clearMocks',
+ link: '/config/clearmocks',
+ },
+ {
+ text: 'mockReset',
+ link: '/config/mockreset',
+ },
+ {
+ text: 'restoreMocks',
+ link: '/config/restoremocks',
+ },
+ {
+ text: 'unstubEnvs',
+ link: '/config/unstubenvs',
+ },
+ {
+ text: 'unstubGlobals',
+ link: '/config/unstubglobals',
+ },
+ {
+ text: 'snapshotFormat',
+ link: '/config/snapshotformat',
+ },
+ {
+ text: 'snapshotSerializers',
+ link: '/config/snapshotserializers',
+ },
+ {
+ text: 'resolveSnapshotPath',
+ link: '/config/resolvesnapshotpath',
+ },
+ {
+ text: 'allowOnly',
+ link: '/config/allowonly',
+ },
+ {
+ text: 'passWithNoTests',
+ link: '/config/passwithnotests',
+ },
+ {
+ text: 'logHeapUsage',
+ link: '/config/logheapusage',
+ },
+ {
+ text: 'css',
+ link: '/config/css',
+ },
+ {
+ text: 'maxConcurrency',
+ link: '/config/maxconcurrency',
+ },
+ {
+ text: 'cache',
+ link: '/config/cache',
+ },
+ {
+ text: 'sequence',
+ link: '/config/sequence',
+ },
+ {
+ text: 'typecheck',
+ link: '/config/typecheck',
+ },
+ {
+ text: 'slowTestThreshold',
+ link: '/config/slowtestthreshold',
+ },
+ {
+ text: 'chaiConfig',
+ link: '/config/chaiconfig',
+ },
+ {
+ text: 'bail',
+ link: '/config/bail',
+ },
+ {
+ text: 'retry',
+ link: '/config/retry',
+ },
+ {
+ text: 'onConsoleLog',
+ link: '/config/onconsolelog',
+ },
+ {
+ text: 'onStackTrace',
+ link: '/config/onstacktrace',
+ },
+ {
+ text: 'onUnhandledError',
+ link: '/config/onunhandlederror',
+ },
+ {
+ text: 'dangerouslyIgnoreUnhandled...',
+ link: '/config/dangerouslyignoreunhandlederrors',
+ },
+ {
+ text: 'diff',
+ link: '/config/diff',
+ },
+ {
+ text: 'fakeTimers',
+ link: '/config/faketimers',
+ },
+ {
+ text: 'projects',
+ link: '/config/projects',
+ },
+ {
+ text: 'isolate',
+ link: '/config/isolate',
+ },
+ {
+ text: 'includeTaskLocation',
+ link: '/config/includetasklocation',
+ },
+ {
+ text: 'snapshotEnvironment',
+ link: '/config/snapshotenvironment',
+ },
+ {
+ text: 'env',
+ link: '/config/env',
+ },
+ {
+ text: 'expect',
+ link: '/config/expect',
+ },
+ {
+ text: 'printConsoleTrace',
+ link: '/config/printconsoletrace',
+ },
+ {
+ text: 'attachmentsDir',
+ link: '/config/attachmentsdir',
+ },
+ {
+ text: 'hideSkippedTests',
+ link: '/config/hideskippedtests',
+ },
+ {
+ text: 'mode',
+ link: '/config/mode',
+ },
+ {
+ text: 'expandSnapshotDiff',
+ link: '/config/expandsnapshotdiff',
+ },
+ {
+ text: 'disableConsoleIntercept',
+ link: '/config/disableconsoleintercept',
+ },
+ {
+ text: 'experimental',
+ link: '/config/experimental',
+ },
+ ],
+ },
+ {
+ text: 'Browser Mode',
+ collapsed: false,
+ items: [
+ {
+ text: 'Providers',
+ collapsed: false,
+ items: [
+ {
+ text: 'playwright',
+ link: '/config/browser/playwright',
+ },
+ {
+ text: 'webdriverio',
+ link: '/config/browser/webdriverio',
+ },
+ {
+ text: 'preview',
+ link: '/config/browser/preview',
+ },
+ ],
+ },
+ // {
+ // text: 'Render Function',
+ // collapsed: true,
+ // items: [
+ // {
+ // text: 'react',
+ // link: '/config/browser/react',
+ // },
+ // {
+ // text: 'vue',
+ // link: '/config/browser/vue',
+ // },
+ // {
+ // text: 'svelte',
+ // link: '/config/browser/svelte',
+ // },
+ // ],
+ // },
+ {
+ text: 'browser.enabled',
+ link: '/config/browser/enabled',
+ },
+ {
+ text: 'browser.instances',
+ link: '/config/browser/instances',
+ },
+ {
+ text: 'browser.headless',
+ link: '/config/browser/headless',
+ },
+ {
+ text: 'browser.isolate',
+ link: '/config/browser/isolate',
+ },
+ {
+ text: 'browser.testerHtmlPath',
+ link: '/config/browser/testerhtmlpath',
+ },
+ {
+ text: 'browser.api',
+ link: '/config/browser/api',
+ },
+ {
+ text: 'browser.provider',
+ link: '/config/browser/provider',
+ },
+ {
+ text: 'browser.ui',
+ link: '/config/browser/ui',
+ },
+ {
+ text: 'browser.viewport',
+ link: '/config/browser/viewport',
+ },
+ {
+ text: 'browser.locators',
+ link: '/config/browser/locators',
+ },
+ {
+ text: 'browser.screenshotDirectory',
+ link: '/config/browser/screenshotdirectory',
+ },
+ {
+ text: 'browser.screenshotFailures',
+ link: '/config/browser/screenshotfailures',
+ },
+ {
+ text: 'browser.orchestratorScripts',
+ link: '/config/browser/orchestratorscripts',
+ },
+ {
+ text: 'browser.commands',
+ link: '/config/browser/commands',
+ },
+ {
+ text: 'browser.connectTimeout',
+ link: '/config/browser/connecttimeout',
+ },
+ {
+ text: 'browser.trace',
+ link: '/config/browser/trace',
+ },
+ {
+ text: 'browser.trackUnhandledErrors',
+ link: '/config/browser/trackunhandlederrors',
+ },
+ {
+ text: 'browser.expect',
+ link: '/config/browser/expect',
+ },
+ ],
+ },
+ // {
+ // text: '@vitest/plugin-eslint',
+ // collapsed: true,
+ // items: [
+ // {
+ // text: 'Lints',
+ // link: '/config/eslint',
+ // },
+ // // TODO: generate
+ // {
+ // text: 'consistent-test-filename',
+ // link: '/config/eslint/consistent-test-filename',
+ // },
+ // {
+ // text: 'consistent-test-it',
+ // link: '/config/eslint/consistent-test-it',
+ // },
+ // ],
+ // },
+ // {
+ // text: 'vscode',
+ // link: '/config/vscode',
+ // },
+ ],
+ '/guide': [
+ {
+ text: '简介',
+ collapsed: false,
+ items: [
+ {
+ text: '为什么是 Vitest?',
+ link: '/guide/why',
+ },
+ {
+ text: '快速起步',
+ link: '/guide/',
+ },
+ {
+ text: '主要功能',
+ link: '/guide/features',
+ },
+ ],
+ },
+ {
+ text: '浏览器模式',
+ collapsed: false,
+ items: [
+ {
+ text: '什么是浏览器模式?',
+ link: '/guide/browser/why',
+ docFooterText: '什么是浏览器模式? | 浏览器模式',
+ },
+ {
+ text: '快速起步',
+ link: '/guide/browser/',
+ docFooterText: '快速起步 | 浏览器模式',
+ },
+ {
+ text: '多环境配置',
+ link: '/guide/browser/multiple-setups',
+ docFooterText: '多环境配置 | 浏览器模式',
+ },
+ {
+ text: '组件测试',
+ link: '/guide/browser/component-testing',
+ docFooterText: '组件测试 | 浏览器模式',
+ },
+ {
+ text: '可视化回归测试',
+ link: '/guide/browser/visual-regression-testing',
+ docFooterText: '可视化回归测试 | 浏览器模式',
+ },
+ {
+ text: '追踪查看器',
+ link: '/guide/browser/trace-view',
+ docFooterText: '追踪查看器 | 浏览器模式',
+ },
+ ],
+ },
+ {
+ text: '指南',
+ collapsed: false,
+ items: [
+ {
+ text: '命令行界面',
+ link: '/guide/cli',
+ },
+ {
+ text: '测试筛选',
+ link: '/guide/filtering',
+ },
+ {
+ text: '测试上下文',
+ link: '/guide/test-context',
+ },
+ {
+ text: '测试环境',
+ link: '/guide/environment',
+ },
+ {
+ text: '快照',
+ link: '/guide/snapshot',
+ },
+ {
+ text: '模拟对象',
+ link: '/guide/mocking',
+ collapsed: true,
+ items: [
+ {
+ text: '模拟日期',
+ link: '/guide/mocking/dates',
+ },
+ {
+ text: '模拟函数',
+ link: '/guide/mocking/functions',
+ },
+ {
+ text: '模拟全局对象',
+ link: '/guide/mocking/globals',
+ },
+ {
+ text: '模拟模块',
+ link: '/guide/mocking/modules',
+ },
+ {
+ text: '模拟文件系统',
+ link: '/guide/mocking/file-system',
+ },
+ {
+ text: '模拟请求',
+ link: '/guide/mocking/requests',
+ },
+ {
+ text: '模拟计时器',
+ link: '/guide/mocking/timers',
+ },
+ {
+ text: '模拟类',
+ link: '/guide/mocking/classes',
+ },
+ ],
+ },
+ {
+ text: '并行测试',
+ link: '/guide/parallelism',
+ },
+ {
+ text: '测试项目',
+ link: '/guide/projects',
+ },
+ {
+ text: '报告器',
+ link: '/guide/reporters',
+ },
+ {
+ text: '覆盖率',
+ link: '/guide/coverage',
+ },
+ {
+ text: '类型测试',
+ link: '/guide/testing-types',
+ },
+ {
+ text: 'UI 模式',
+ link: '/guide/ui',
+ },
+ {
+ text: '内联测试',
+ link: '/guide/in-source',
+ },
+ {
+ text: '测试注释',
+ link: '/guide/test-annotations',
+ },
+ {
+ text: '扩展断言',
+ link: '/guide/extending-matchers',
+ },
+ {
+ text: 'IDE 插件',
+ link: '/guide/ide',
+ },
+ {
+ text: '调试',
+ link: '/guide/debugging',
+ },
+ {
+ text: '常见错误',
+ link: '/guide/common-errors',
+ },
+ {
+ text: '迁移指南',
+ link: '/guide/migration',
+ collapsed: false,
+ items: [
+ {
+ text: '迁移到 Vitest 4',
+ link: '/guide/migration#vitest-4',
+ },
+ {
+ text: '从 Jest 迁移',
+ link: '/guide/migration#jest',
+ },
+ ],
+ },
+ {
+ text: '性能',
+ collapsed: false,
+ items: [
+ {
+ text: '性能测试分析',
+ link: '/guide/profiling-test-performance',
+ },
+ {
+ text: '性能优化',
+ link: '/guide/improving-performance',
+ },
+ ],
+ },
+ {
+ text: 'OpenTelemetry',
+ link: '/guide/open-telemetry',
+ },
+ ],
+ },
+ {
+ text: '高级指南',
+ collapsed: true,
+ items: [
+ {
+ text: '快速开始',
+ link: '/guide/advanced/',
+ },
+ {
+ text: '运行测试 API',
+ link: '/guide/advanced/tests',
+ },
+ {
+ text: '扩展报告器',
+ link: '/guide/advanced/reporters',
+ },
+ {
+ text: '自定义运行池',
+ link: '/guide/advanced/pool',
+ },
+ ],
+ },
+ {
+ items: [
+ {
+ text: 'Recipes',
+ link: '/guide/recipes',
+ },
+ {
+ text: '测试框架比较',
+ link: '/guide/comparisons',
+ },
+ ],
+ },
+ ],
+ '/api': [
+ {
+ text: 'Test API',
+ link: '/api/',
+ },
+ {
+ text: 'Mocks',
+ link: '/api/mock',
+ },
+ {
+ text: 'Vi Utility',
+ link: '/api/vi',
+ },
+ {
+ text: 'Expect',
+ link: '/api/expect',
+ },
+ {
+ text: 'ExpectTypeOf',
+ link: '/api/expect-typeof',
+ },
+ {
+ text: 'Assert',
+ link: '/api/assert',
+ },
+ {
+ text: 'AssertType',
+ link: '/api/assert-type',
+ },
+ {
+ text: '浏览器模式',
+ items: [
+ {
+ text: 'Context API',
+ link: '/api/browser/context',
+ },
+ {
+ text: 'Interactivity API',
+ link: '/api/browser/interactivity',
+ },
+ {
+ text: 'Locators',
+ link: '/api/browser/locators',
+ },
+ {
+ text: 'Assertions API',
+ link: '/api/browser/assertions',
+ },
+ {
+ text: 'Commands API',
+ link: '/api/browser/commands',
+ },
+ ],
+ },
+ {
+ text: '高级 API',
+ collapsed: true,
+ items: [
+ {
+ text: 'Vitest',
+ link: '/api/advanced/vitest',
+ },
+ {
+ text: 'TestProject',
+ link: '/api/advanced/test-project',
+ },
+ {
+ text: 'TestSpecification',
+ link: '/api/advanced/test-specification',
+ },
+ {
+ text: 'TestCase',
+ link: '/api/advanced/test-case',
+ },
+ {
+ text: 'TestSuite',
+ link: '/api/advanced/test-suite',
+ },
+ {
+ text: 'TestModule',
+ link: '/api/advanced/test-module',
+ },
+ {
+ text: 'TestCollection',
+ link: '/api/advanced/test-collection',
+ },
+ {
+ text: 'VitestPlugin',
+ link: '/api/advanced/plugin',
+ },
+ {
+ text: 'VitestRunner',
+ link: '/api/advanced/runner',
+ },
+ {
+ text: 'Reporter',
+ link: '/api/advanced/reporters',
+ },
+ {
+ text: 'TaskMeta',
+ link: '/api/advanced/metadata',
+ },
+ {
+ text: 'TestArtifact',
+ link: '/api/advanced/artifacts',
+ },
+ ],
+ },
+ // {
+ // text: 'Text Runner',
+ // collapsed: false,
+ // items: [
+ // // TODO: generate
+ // {
+ // text: 'test',
+ // link: '/api/test',
+ // },
+ // {
+ // text: 'describe',
+ // link: '/api/describe',
+ // },
+ // {
+ // text: 'beforeEach',
+ // link: '/api/before-each',
+ // },
+ // {
+ // text: 'afterEach',
+ // link: '/api/after-each',
+ // },
+ // ],
+ // },
+ // {
+ // text: 'Assertion API',
+ // collapsed: false,
+ // items: [
+ // {
+ // text: 'expect',
+ // link: '/api/expect',
+ // },
+ // {
+ // text: 'assert',
+ // link: '/api/assert',
+ // },
+ // {
+ // text: 'expectTypeOf',
+ // link: '/api/expect-typeof',
+ // },
+ // {
+ // text: 'assertType',
+ // link: '/api/assert-type',
+ // },
+ // ],
+ // },
+ // {
+ // text: 'Vi Utility API',
+ // collapsed: false,
+ // items: [
+ // {
+ // text: 'Mock Modules',
+ // link: '/api/vi/mock-modiles',
+ // },
+ // {
+ // text: 'Mock Functions',
+ // link: '/api/vi/mock-functions',
+ // },
+ // {
+ // text: 'Mock Timers',
+ // link: '/api/vi/mock-timers',
+ // },
+ // {
+ // text: 'Miscellaneous',
+ // link: '/api/vi/miscellaneous',
+ // },
+ // ],
+ // },
+ // {
+ // text: 'Browser Mode',
+ // collapsed: false,
+ // items: [
+ // // TODO: generate
+ // {
+ // text: 'page',
+ // link: '/api/browser/page',
+ // },
+ // {
+ // text: 'locators',
+ // link: '/api/browser/locators',
+ // },
+ // ],
+ // },
+ ],
+ },
},
- ]
+ pwa,
+ transformHead,
+ }))
}
diff --git a/.vitepress/scripts/cli-generator.ts b/.vitepress/scripts/cli-generator.ts
index bea3ade8..1e82a8bd 100644
--- a/.vitepress/scripts/cli-generator.ts
+++ b/.vitepress/scripts/cli-generator.ts
@@ -35,6 +35,13 @@ const skipConfig = new Set([
'run',
'hideSkippedTests',
'dom',
+ 'inspect',
+ 'inspectBrk',
+ 'project',
+ 'ui',
+ 'browser.name',
+ 'browser.fileParallelism',
+ 'clearCache',
])
function resolveOptions(options: CLIOptions, parentName?: string) {
@@ -76,8 +83,9 @@ const options = resolveOptions(cliOptionsConfig)
const template = options.map((option) => {
const title = option.title
const cli = option.cli
- const config = skipConfig.has(title) ? '' : `[${title}](${title.includes('browser.') ? '/guide/browser/config' : '/config/'}#${title.toLowerCase().replace(/\./g, '-')})`
- return `### ${title}\n\n- **CLI:** ${cli}\n${config ? `- **Config:** ${config}\n` : ''}\n${option.description}\n`
+ const [page, ...hash] = (title.startsWith('browser.') ? title.slice(8) : title).toLowerCase().split('.')
+ const config = skipConfig.has(title) ? '' : `[${title}](${title.includes('browser.') ? '/config/browser/' : '/config/'}${page}${hash.length ? `#${[page, ...hash].join('-')}` : ''})`
+ return `### ${title}\n\n- **CLI:** ${cli}\n${config ? `- **Config:** ${config}\n` : ''}\n${option.description.replace(/https:\/\/vitest\.dev\//g, '/')}\n`
}).join('\n')
writeFileSync(cliTablePath, template, 'utf-8')
diff --git a/.vitepress/sponsors.ts b/.vitepress/sponsors.ts
index 7bf17112..79fe4ab2 100644
--- a/.vitepress/sponsors.ts
+++ b/.vitepress/sponsors.ts
@@ -51,6 +51,11 @@ const vitestSponsors = {
url: 'https://www.liminity.se/',
img: '/liminity.svg',
},
+ {
+ name: 'Bytebase',
+ url: 'https://www.bytebase.com/',
+ img: '/bytebase.svg',
+ },
],
} satisfies Record
diff --git a/.vitepress/style/main.css b/.vitepress/style/main.css
index 251138d1..d46ffcd6 100644
--- a/.vitepress/style/main.css
+++ b/.vitepress/style/main.css
@@ -37,31 +37,37 @@ button:focus:not(:focus-visible) {
html:not(.dark) .custom-block.tip code {
color: var(--vitest-custom-block-tip-code-text) !important;
}
+
html:not(.dark) .custom-block.info code {
color: var(--vitest-custom-block-info-code-text) !important;
}
+
.custom-block.tip a:hover,
-.vp-doc .custom-block.tip a:hover > code {
+.vp-doc .custom-block.tip a:hover>code {
color: var(--vp-c-brand-1) !important;
opacity: 1;
}
+
.custom-block.info a:hover,
-.vp-doc .custom-block.info a:hover > code {
+.vp-doc .custom-block.info a:hover>code {
color: var(--vp-c-brand-1) !important;
opacity: 1;
}
+
html:not(.dark) .custom-block.info a:hover,
-html:not(.dark) .vp-doc .custom-block.info a:hover > code {
+html:not(.dark) .vp-doc .custom-block.info a:hover>code {
color: var(--vitest-custom-block-info-code-text) !important;
opacity: 1;
}
+
.custom-block.warning a:hover,
-.vp-doc .custom-block.warning a:hover > code {
+.vp-doc .custom-block.warning a:hover>code {
color: var(--vp-c-warning-1) !important;
opacity: 1;
}
+
.custom-block.danger a:hover,
-.vp-doc .custom-block.danger a:hover > code {
+.vp-doc .custom-block.danger a:hover>code {
color: var(--vp-c-danger-1) !important;
opacity: 1;
}
@@ -70,6 +76,7 @@ html:not(.dark) .vp-doc .custom-block.info a:hover > code {
:not(.dark) .title-icon {
opacity: 1 !important;
}
+
.dark .title-icon {
opacity: 0.67 !important;
}
@@ -81,6 +88,7 @@ html:not(.dark) .vp-doc .custom-block.info a:hover > code {
.vp-doc a {
text-decoration-style: dotted;
}
+
.custom-block a:focus,
.custom-block a:active,
.custom-block a:hover,
@@ -92,7 +100,8 @@ html:not(.dark) .vp-doc .custom-block.info a:hover > code {
text-decoration: underline;
}
-.vp-doc th, .vp-doc td {
+.vp-doc th,
+.vp-doc td {
padding: 6px 10px;
border: 1px solid #8882;
}
@@ -113,14 +122,17 @@ img.resizable-img {
.VPTeamMembersItem.medium .profile .data .affiliation {
min-height: unset;
}
+
.VPTeamMembersItem.medium .profile .data .desc {
min-height: unset;
}
+
/* fix height ~ 2 lines of text: 3 cards per row */
@media (min-width: 648px) {
.VPTeamMembersItem.medium .profile .data .affiliation {
min-height: 4rem;
}
+
.VPTeamMembersItem.medium .profile .data .desc {
min-height: 4rem;
}
@@ -130,6 +142,7 @@ img.resizable-img {
.VPTeamMembersItem.small .profile .data .affiliation {
min-height: 3rem;
}
+
.VPTeamMembersItem.small .profile .data .desc {
min-height: 3rem;
}
@@ -139,33 +152,40 @@ img.resizable-img {
.VPTeamMembersItem.small .profile .data .affiliation {
min-height: 4rem;
}
+
.VPTeamMembersItem.small .profile .data .desc {
min-height: 4rem;
}
}
+
/* fix height ~ 3 lines of text: 3 cards per row */
@media (min-width: 815px) and (max-width: 875px) {
.VPTeamMembersItem.small .profile .data .affiliation {
min-height: 4rem;
}
+
.VPTeamMembersItem.small .profile .data .desc {
min-height: 4rem;
}
}
+
/* fix height ~ 3 lines of text: 2 cards per row */
@media (max-width: 612px) {
.VPTeamMembersItem.small .profile .data .affiliation {
min-height: 4rem;
}
+
.VPTeamMembersItem.small .profile .data .desc {
min-height: 4rem;
}
}
+
/* fix height: one card per row */
@media (max-width: 568px) {
.VPTeamMembersItem.small .profile .data .affiliation {
min-height: unset;
}
+
.VPTeamMembersItem.small .profile .data .desc {
min-height: unset;
}
@@ -176,3 +196,30 @@ img.resizable-img {
transition: background-color 0.5s;
display: inline-block;
}
+
+/* credit goes to https://dylanatsmith.com/wrote/styling-the-kbd-element */
+html:not(.dark) kbd {
+ --kbd-color-background: #f7f7f7;
+ --kbd-color-border: #cbcccd;
+ --kbd-color-text: #222325;
+}
+
+kbd {
+ --kbd-color-background: #898b90;
+ --kbd-color-border: #3d3e42;
+ --kbd-color-text: #222325;
+
+ background-color: var(--kbd-color-background);
+ color: var(--kbd-color-text);
+ border-radius: 0.25rem;
+ border: 1px solid var(--kbd-color-border);
+ box-shadow: 0 2px 0 1px var(--kbd-color-border);
+ font-family: var(--font-family-sans-serif);
+ font-size: 0.75em;
+ line-height: 1;
+ min-width: 0.75rem;
+ text-align: center;
+ padding: 2px 5px;
+ position: relative;
+ top: -1px;
+}
\ No newline at end of file
diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts
index 916db6de..92b2d06b 100644
--- a/.vitepress/theme/index.ts
+++ b/.vitepress/theme/index.ts
@@ -4,6 +4,9 @@ import { inBrowser } from 'vitepress'
import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client'
import DefaultTheme from 'vitepress/theme'
import { h } from 'vue'
+import CRoot from '../components/CRoot.vue'
+import Deprecated from '../components/Deprecated.vue'
+import Experimental from '../components/Experimental.vue'
import HomePage from '../components/HomePage.vue'
import Version from '../components/Version.vue'
import '../style/main.css'
@@ -23,8 +26,30 @@ export default {
'home-features-after': () => h(HomePage),
})
},
- enhanceApp({ app }) {
+ enhanceApp({ app, router }) {
+ router.onBeforeRouteChange = (to) => {
+ if (typeof location === 'undefined') {
+ return true
+ }
+ const url = new URL(to, location.href)
+ if (!url.hash) {
+ return true
+ }
+ if (url.pathname === '/config' || url.pathname === '/config/' || url.pathname === '/config.html') {
+ const [page, ...hash] = (url.hash.startsWith('#browser.') ? url.hash.slice(9) : url.hash.slice(1)).toLowerCase().split('-')
+ setTimeout(() => { router.go(`/config/${page}${hash.length ? `#${[page, ...hash].join('-')}` : ''}`) })
+ return false
+ }
+ if (url.pathname === '/guide/browser/config' || url.pathname === '/guide/browser/config/' || url.pathname === '/guide/browser/config.html') {
+ const [page, ...hash] = url.hash.slice('#browser.'.length).toLowerCase().split('-')
+ setTimeout(() => { router.go(`/config/browser/${page}${hash.length ? `#${[page, ...hash].join('-')}` : ''}`) })
+ return false
+ }
+ }
app.component('Version', Version)
+ app.component('CRoot', CRoot)
+ app.component('Experimental', Experimental)
+ app.component('Deprecated', Deprecated)
app.use(TwoslashFloatingVue)
enhanceAppWithTabs(app)
},
diff --git a/advanced/pool.md b/advanced/pool.md
index 76c16560..e38ec185 100644
--- a/advanced/pool.md
+++ b/advanced/pool.md
@@ -65,9 +65,9 @@ export interface ProcessPool {
这个函数只会被调用一次(除非服务器配置被更新),通常最好在这个函数内初始化测试所需的一切,并在调用 `runTests` 时重复使用它。
-Vitest 会在安排新的测试任务时调用 runTest 方法;如果 files 为空,则不会调用。该方法的第一个参数是 [TestSpecifications](/advanced/api/test-specification) 组成的数组。在执行 runTests 前,这些文件会先经过 [sequencer](/config/#sequence-sequencer) 排序。虽然比较少见,但同一个文件可能会被多次包含在列表里,不过它们总是归属于不同的项目——这是通过 [projects](/guide/projects) 配置机制实现的。
+Vitest 会在安排新的测试任务时调用 runTest 方法;如果 files 为空,则不会调用。该方法的第一个参数是 [TestSpecifications](/api/advanced/test-specification) 组成的数组。在执行 runTests 前,这些文件会先经过 [sequencer](/config/#sequence-sequencer) 排序。虽然比较少见,但同一个文件可能会被多次包含在列表里,不过它们总是归属于不同的项目——这是通过 [projects](/guide/projects) 配置机制实现的。
-在 `runTests` 函数执行完毕之前, Vitest 会一直“挂起”当前测试流程;只有当 `runTests` 成功返回, Vitest 才会把 [`onTestRunEnd`](/advanced/reporters) 事件发出来,宣告本轮测试正式结束。
+在 `runTests` 函数执行完毕之前, Vitest 会一直“挂起”当前测试流程;只有当 `runTests` 成功返回, Vitest 才会把 [`onTestRunEnd`](/api/advanced/reporters) 事件发出来,宣告本轮测试正式结束。
如果你正在使用自定义运行池,需要自行提供测试文件及其结果 - 可以参考 [`vitest.state`](https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/node/state.ts)(最重要的是 `collectFiles` 和 `updateTasks`)。Vitest 使用 `@vitest/runner` 包中的 `startTests` 函数来执行这些操作。
diff --git a/api/advanced/artifacts.md b/api/advanced/artifacts.md
new file mode 100644
index 00000000..67b121f9
--- /dev/null
+++ b/api/advanced/artifacts.md
@@ -0,0 +1,176 @@
+---
+outline: deep
+title: Test Artifacts
+---
+
+# Test Artifacts 4.0.11
+
+::: warning
+This is an advanced API. As a user, you most likely want to use [test annotations](/guide/test-annotations) to add notes or context to your tests instead. This is primarily used internally and by library authors.
+:::
+
+Test artifacts allow attaching or recording structured data, files, or metadata during test execution. This is a low-level feature primarily designed for:
+
+- Internal use ([`annotate`](/guide/test-annotations) is built on top of the artifact system)
+- Framework authors creating custom testing tools on top of Vitest
+
+Each artifact includes:
+
+- A type discriminator which is a unique identifier for the artifact type
+- Custom data, can be any relevant information
+- Optional attachments, either files or inline content associated with the artifact
+- A source code location indicating where the artifact was created
+
+Vitest automatically manages attachment serialization (files are copied to [`attachmentsDir`](/config/#attachmentsdir)) and injects source location metadata, so you can focus on the data you want to record. All artifacts **must** extend from [`TestArtifactBase`](#testartifactbase) and all attachments from [`TestAttachment`](#testattachment) to be correctly handled internally.
+
+## API
+
+### `recordArtifact` {#recordartifact}
+
+::: warning
+`recordArtifact` is an experimental API. Breaking changes might not follow SemVer, please pin Vitest's version when using it.
+
+The API surface may change based on feedback. We encourage you to try it out and share your experience with the team.
+:::
+
+```ts
+function recordArtifact(task: Test, artifact: Artifact): Promise
+```
+
+The `recordArtifact` function records an artifact during test execution and returns it. It expects a [task](/api/advanced/runner#tasks) as the first parameter and an object assignable to [`TestArtifact`](#testartifact) as the second.
+
+This function has to be used within a test, and the test has to still be running. Recording after test completion will throw an error.
+
+When an artifact is recorded on a test, it emits an `onTestArtifactRecord` runner event and a [`onTestCaseArtifactRecord` reporter event](/api/advanced/reporters#ontestcaseartifactrecord). To retrieve recorded artifacts from a test case, use the [`artifacts()`](/api/advanced/test-case#artifacts) method.
+
+Note: annotations, [even though they're built on top of this feature](#relationship-with-annotations), won't appear in the `task.artifacts` array for backwards compatibility reasons until the next major version.
+
+### `TestArtifact`
+
+The `TestArtifact` type is a union containing all artifacts Vitest can produce, including custom ones. All artifacts extend from [`TestArtifactBase`](#testartifactbase)
+
+### `TestArtifactBase` {#testartifactbase}
+
+```ts
+export interface TestArtifactBase {
+ /** File or data attachments associated with this artifact */
+ attachments?: TestAttachment[]
+ /** Source location where this artifact was created */
+ location?: TestArtifactLocation
+}
+```
+
+The `TestArtifactBase` interface is the base for all test artifacts.
+
+Extend this interface when creating custom test artifacts. Vitest automatically manages the `attachments` array and injects the `location` property to indicate where the artifact was created in your test code.
+
+### `TestAttachment`
+
+```ts
+export interface TestAttachment {
+ /** MIME type of the attachment (e.g., 'image/png', 'text/plain') */
+ contentType?: string
+ /** File system path to the attachment */
+ path?: string
+ /** Inline attachment content as a string or raw binary data */
+ body?: string | Uint8Array
+}
+```
+
+The `TestAttachment` interface represents a file or data attachment associated with a test artifact.
+
+Attachments can be either file-based (via `path`) or inline content (via `body`). The `contentType` helps consumers understand how to interpret the attachment data.
+
+### `TestArtifactLocation`
+
+```ts
+export interface TestArtifactLocation {
+ /** Line number in the source file (1-indexed) */
+ line: number
+ /** Column number in the line (1-indexed) */
+ column: number
+ /** Path to the source file */
+ file: string
+}
+```
+
+The `TestArtifactLocation` interface represents the source code location information for a test artifact. It indicates where in the source code the artifact originated from.
+
+### `TestArtifactRegistry`
+
+The `TestArtifactRegistry` interface is a registry for custom test artifact types.
+
+Augmenting this interface using [TypeScript's module augmentation feature](https://typescriptlang.org/docs/handbook/declaration-merging#module-augmentation) allows registering custom artifact types that tests can produce.
+
+Each custom artifact should extend [`TestArtifactBase`](#testartifactbase) and include a unique `type` discriminator property.
+
+Here are a few guidelines or best practices to follow:
+
+- Try using a `Symbol` as the **registry key** to guarantee uniqueness
+- The `type` property should follow the pattern `'package-name:artifact-name'`, **`'internal:'` is a reserved prefix**
+- Use `attachments` to include files or data; extend [`TestAttachment`](#testattachment) for custom metadata
+- `location` property is automatically injected
+
+## Custom Artifacts
+
+To use and manage artifacts in a type-safe manner, you need to create its type and register it:
+
+```ts
+import type { TestArtifactBase, TestAttachment } from 'vitest'
+
+interface A11yReportAttachment extends TestAttachment {
+ contentType: 'text/html'
+ path: string
+}
+
+interface AccessibilityArtifact extends TestArtifactBase {
+ type: 'a11y:report'
+ passed: boolean
+ wcagLevel: 'A' | 'AA' | 'AAA'
+ attachments: [A11yReportAttachment]
+}
+
+const a11yReportKey = Symbol('report')
+
+declare module 'vitest' {
+ interface TestArtifactRegistry {
+ [a11yReportKey]: AccessibilityArtifact
+ }
+}
+```
+
+As long as the types are assignable to their bases and don't have errors, everything should work fine and you should be able to record artifacts using [`recordArtifact`](#recordartifact):
+
+```ts
+async function toBeAccessible(
+ this: MatcherState,
+ actual: Element,
+ wcagLevel: 'A' | 'AA' | 'AAA' = 'AA'
+): AsyncExpectationResult {
+ const report = await runAccessibilityAudit(actual, wcagLevel)
+
+ await recordArtifact(this.task, {
+ type: 'a11y:report',
+ passed: report.violations.length === 0,
+ wcagLevel,
+ attachments: [{
+ contentType: 'text/html',
+ path: report.path,
+ }],
+ })
+
+ return {
+ pass: violations.length === 0,
+ message: () => `Found ${report.violations.length} accessibility violation(s)`
+ }
+}
+```
+
+## Relationship with Annotations
+
+Test annotations are built on top of the artifact system. When using annotations in tests, they create `internal:annotation` artifacts under the hood. However, annotations are:
+
+- Simpler to use
+- Designed for end-users, not developers
+
+Use annotations if you just want to add notes to your tests. Use artifacts if you need custom data.
diff --git a/advanced/api/import-example.md b/api/advanced/import-example.md
similarity index 100%
rename from advanced/api/import-example.md
rename to api/advanced/import-example.md
diff --git a/advanced/metadata.md b/api/advanced/metadata.md
similarity index 94%
rename from advanced/metadata.md
rename to api/advanced/metadata.md
index d0b1a7e1..5dd96a0b 100644
--- a/advanced/metadata.md
+++ b/api/advanced/metadata.md
@@ -1,8 +1,4 @@
-# 任务元数据 {#task-metadata}
-
-::: warning
-Vitest 导出了实验性私有 API。重大更改可能不遵循 semver,使用时请固定 Vitest 的版本。
-:::
+# 任务元数据 advanced
如果你正在开发自定义报告器或使用 Vitest Node.js API,你可能会发现将在各种上下文中执行的测试中的数据传递给报告器或自定义 Vitest 处理程序很有用。
diff --git a/advanced/api/plugin.md b/api/advanced/plugin.md
similarity index 73%
rename from advanced/api/plugin.md
rename to api/advanced/plugin.md
index 709554e8..07303230 100644
--- a/advanced/api/plugin.md
+++ b/api/advanced/plugin.md
@@ -11,7 +11,7 @@ outline: deep
本指南假设我们知道如何使用 [Vite 插件](https://vite.dev/guide/api-plugin.html)。
:::
-Vitest 自 3.1 版起支持实验性的 `configureVitest` [插件](https://cn.vite.dev/guide/api-plugin) hook。欢迎在 [GitHub](https://github.com/vitest-dev/vitest/discussions/7104) 中提供有关此 API 的任何反馈。
+Vitest 自 3.1 版起支持实验性的 `configureVitest` [插件](https://cn.vite.dev/guide/api-plugin) hook。
::: code-group
```ts [only vitest]
@@ -53,7 +53,7 @@ Vitest 通过 `Vite` namespace 重新导出所有仅 Vite 类型的导入,我
```
:::
-与 [`reporter.onInit`](/advanced/api/reporters#oninit) 不同,此 hooks 在 Vitest 生命周期的早期运行,允许我们更改 `coverage` 和 `reporters` 等配置。更值得注意的变化是,如果我们的插件是在项目中定义而不是在全局配置中定义的,我们可以从 [工作区项目](/guide/projects) 操作全局配置。
+与 [`reporter.onInit`](/api/advanced/reporters#oninit) 不同,此 hooks 在 Vitest 生命周期的早期运行,允许我们更改 `coverage` 和 `reporters` 等配置。更值得注意的变化是,如果我们的插件是在项目中定义而不是在全局配置中定义的,我们可以从 [工作区项目](/guide/projects) 操作全局配置。
## Context
@@ -123,3 +123,52 @@ vitest.config.project.push('my-project-name')
请注意,这也将继承 `name` - Vitest 不允许多个项目使用相同的名称,因此这将引发错误。请确保我们指定了不同的名称。我们可以通过 `project.name` 属性访问当前名称,并且所有使用的名称都可以在 `vitest.projects` 数组中找到。
:::
+
+
+### experimental_defineCacheKeyGenerator 4.0.11 {#definecachekeygenerator}
+
+```ts
+interface CacheKeyIdGeneratorContext {
+ environment: DevEnvironment
+ id: string
+ sourceCode: string
+}
+
+function experimental_defineCacheKeyGenerator(
+ callback: (context: CacheKeyIdGeneratorContext) => string | undefined | null | false
+): void
+```
+
+Define a generator that will be applied before hashing the cache key.
+
+Use this to make sure Vitest generates correct hash. It is a good idea to define this function if your plugin can be registered with different options.
+
+This is called only if [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache) is defined.
+
+```ts
+interface PluginOptions {
+ replacePropertyKey: string
+ replacePropertyValue: string
+}
+
+export function plugin(options: PluginOptions) {
+ return {
+ name: 'plugin-that-replaces-property',
+ transform(code) {
+ return code.replace(
+ options.replacePropertyKey,
+ options.replacePropertyValue
+ )
+ },
+ configureVitest({ experimental_defineCacheKeyGenerator }) {
+ experimental_defineCacheKeyGenerator(() => {
+ // since these options affect the transform result,
+ // return them together as a unique string
+ return options.replacePropertyKey + options.replacePropertyValue
+ })
+ }
+ }
+}
+```
+
+If `false` is returned, the module will not be cached on the file system.
diff --git a/advanced/api/reporters.md b/api/advanced/reporters.md
similarity index 75%
rename from advanced/api/reporters.md
rename to api/advanced/reporters.md
index 632376fe..a76397e3 100644
--- a/advanced/api/reporters.md
+++ b/api/advanced/reporters.md
@@ -6,33 +6,30 @@
Vitest 拥有自己的测试运行生命周期。这些生命周期通过报告器的方法来表示:
-- [`onInit`](#oninit)
-- [`onTestRunStart`](#ontestrunstart)
- - [`onTestModuleQueued`](#ontestmodulequeued)
- - [`onTestModuleCollected`](#ontestmodulecollected)
- - [`onTestModuleStart`](#ontestmodulestart)
- - [`onTestSuiteReady`](#ontestsuiteready)
- - [`onHookStart(beforeAll)`](#onhookstart)
- - [`onHookEnd(beforeAll)`](#onhookend)
- - [`onTestCaseReady`](#ontestcaseready)
- - [`onTestAnnotate`](#ontestannotate) 3.2.0
- - [`onHookStart(beforeEach)`](#onhookstart)
- - [`onHookEnd(beforeEach)`](#onhookend)
- - [`onHookStart(afterEach)`](#onhookstart)
- - [`onHookEnd(afterEach)`](#onhookend)
- - [`onTestCaseResult`](#ontestcaseresult)
- - [`onHookStart(afterAll)`](#onhookstart)
- - [`onHookEnd(afterAll)`](#onhookend)
- - [`onTestSuiteResult`](#ontestsuiteresult)
- - [`onTestModuleEnd`](#ontestmoduleend)
- - [`onCoverage`](#oncoverage)
-- [`onTestRunEnd`](#ontestrunend)
+- [报告器 {#reporters}](#报告器-reporters)
+ - [onInit](#oninit)
+ - [onBrowserInit {#onbrowserinit}](#onbrowserinit-onbrowserinit)
+ - [onTestRunStart](#ontestrunstart)
+ - [onTestRunEnd](#ontestrunend)
+ - [onCoverage](#oncoverage)
+ - [onTestModuleQueued](#ontestmodulequeued)
+ - [onTestModuleCollected](#ontestmodulecollected)
+ - [onTestModuleStart](#ontestmodulestart)
+ - [onTestModuleEnd](#ontestmoduleend)
+ - [onHookStart](#onhookstart)
+ - [onHookEnd](#onhookend)
+ - [onTestSuiteReady](#ontestsuiteready)
+ - [onTestSuiteResult](#ontestsuiteresult)
+ - [onTestCaseReady](#ontestcaseready)
+ - [onTestCaseResult](#ontestcaseresult)
+ - [onTestAnnotate 3.2.0 {#ontestannotate}](#ontestannotate-320-ontestannotate)
+ - [onTestCaseArtifactRecord 4.0.11 {#ontestcaseartifactrecord}](#ontestcaseartifactrecord-4011-ontestcaseartifactrecord)
除非被跳过,否则单个模块中的测试和 reporters 将按顺序报告。所有跳过的测试将在 reporters /模块的末尾报告。
请注意,由于测试模块可以并行运行,Vitest 将并行报告它们。
-本指南列出了所有支持的报告器方法。不过,别忘了,与其创建自己的 报告器 ,我们可以 [扩展现有的报告器](/advanced/reporters):
+本指南列出了所有支持的报告器方法。不过,别忘了,与其创建自己的 报告器 ,我们可以 [扩展现有的报告器](/guide/advanced/reporters):
```ts [custom-reporter.js]
import { BaseReporter } from 'vitest/reporters'
@@ -51,13 +48,13 @@ export default class CustomReporter extends BaseReporter {
function onInit(vitest: Vitest): Awaitable
```
-当 [Vitest](/advanced/api/vitest) 初始化或启动时,但在测试被过滤之前,会调用此方法。
+当 [Vitest](/api/advanced/vitest) 初始化或启动时,但在测试被过滤之前,会调用此方法。
::: info
-在内部,这个方法在 [`vitest.start`](/advanced/api/vitest#start)、[`vitest.init`](/advanced/api/vitest#init) 或 [`vitest.mergeReports`](/advanced/api/vitest#mergereports) 中调用。例如,如果我们使用 API,请确保根据我们的需要调用其中一个,然后再调用 [`vitest.runTestSpecifications`](/advanced/api/vitest#runtestspecifications)。内置的 CLI 将始终按正确的顺序运行方法。
+在内部,这个方法在 [`vitest.start`](/api/advanced/vitest#start)、[`vitest.init`](/api/advanced/vitest#init) 或 [`vitest.mergeReports`](/api/advanced/vitest#mergereports) 中调用。例如,如果我们使用 API,请确保根据我们的需要调用其中一个,然后再调用 [`vitest.runTestSpecifications`](/api/advanced/vitest#runtestspecifications)。内置的 CLI 将始终按正确的顺序运行方法。
:::
-请注意,我们还可以通过 [`project`](/advanced/api/test-project) 属性从测试用例、套件和测试模块中访问 `vitest` 实例,但在此方法中存储对 `vitest` 的引用也可能有用。
+请注意,我们还可以通过 [`project`](/api/advanced/test-project) 属性从测试用例、套件和测试模块中访问 `vitest` 实例,但在此方法中存储对 `vitest` 的引用也可能有用。
::: details 示例
```ts
@@ -83,7 +80,7 @@ export default new MyReporter()
```
:::
-## onBrowserInit 实验性 {#onbrowserinit}
+## onBrowserInit {#onbrowserinit}
```ts
function onBrowserInit(project: TestProject): Awaitable
@@ -99,7 +96,7 @@ function onTestRunStart(
): Awaitable
```
-当新的测试运行开始时调用此方法。它接收计划运行的 [测试规范](/advanced/api/test-specification) 数组。此数组是只读的,仅用于信息目的。
+当新的测试运行开始时调用此方法。它接收计划运行的 [测试规范](/api/advanced/test-specification) 数组。此数组是只读的,仅用于信息目的。
如果 Vitest 没有找到任何要运行的测试文件,此事件将以空数组调用,然后 [`onTestRunEnd`](#ontestrunend) 将立即被调用。
@@ -133,7 +130,7 @@ function onTestRunEnd(
当所有测试完成运行并且覆盖率合并了所有报告(如果启用)时调用此方法。请注意,我们可以在 [`onCoverage`](#oncoverage) 钩子中获取覆盖率信息。
-它接收一个只读的测试模块列表。我们可以通过 [`testModule.children`](/advanced/api/test-collection) 属性遍历它以报告状态和错误(如果有)。
+它接收一个只读的测试模块列表。我们可以通过 [`testModule.children`](/api/advanced/test-collection) 属性遍历它以报告状态和错误(如果有)。
第二个参数是 Vitest 无法归因于任何测试的未处理错误的只读列表。这些错误可能发生在测试运行之外,例如插件中的错误,或者在测试运行中作为未等待函数的副作用(例如,在测试完成后抛出错误的超时)。
@@ -141,7 +138,7 @@ function onTestRunEnd(
- `passed`: 测试运行正常结束,没有错误
- `failed`: 测试运行至少有一个错误(由于收集期间的语法错误或测试执行期间的实际错误)
-- `interrupted`: 测试被 [`vitest.cancelCurrentRun`](/advanced/api/vitest#cancelcurrentrun) 调用或在终端中按下 `Ctrl+C` 中断(请注意,在这种情况下仍然有可能导致测试失败)
+- `interrupted`: 测试被 [`vitest.cancelCurrentRun`](/api/advanced/vitest#cancelcurrentrun) 调用或在终端中按下 `Ctrl+C` 中断(请注意,在这种情况下仍然有可能导致测试失败)
如果 Vitest 没有找到任何要运行的测试文件,此事件将以空的模块和错误数组调用,状态将取决于 [`config.passWithNoTests`](/config/#passwithnotests) 的值。
@@ -210,7 +207,7 @@ declare function onCoverage(coverage: CoverageMap): Awaitable
function onTestModuleQueued(testModule: TestModule): Awaitable
```
-在 Vitest 导入设置文件和测试模块本身之前调用此方法。这意味着 `testModule` 还没有 [`children`](/advanced/api/test-suite#children),但我们可以开始将其报告为下一个要运行的测试。
+在 Vitest 导入设置文件和测试模块本身之前调用此方法。这意味着 `testModule` 还没有 [`children`](/api/advanced/test-suite#children),但我们可以开始将其报告为下一个要运行的测试。
## onTestModuleCollected
@@ -218,7 +215,7 @@ function onTestModuleQueued(testModule: TestModule): Awaitable
function onTestModuleCollected(testModule: TestModule): Awaitable
```
-当文件中的所有测试都被收集时调用此方法,这意味着 [`testModule.children`](/advanced/api/test-suite#children) 集合已填充,但测试还没有任何结果。
+当文件中的所有测试都被收集时调用此方法,这意味着 [`testModule.children`](/api/advanced/test-suite#children) 集合已填充,但测试还没有任何结果。
## onTestModuleStart
@@ -226,7 +223,7 @@ function onTestModuleCollected(testModule: TestModule): Awaitable
function onTestModuleStart(testModule: TestModule): Awaitable
```
-在 [`onTestModuleCollected`](#ontestmodulecollected) 之后立即调用此方法,除非 Vitest 在收集模式下运行([`vitest.collect()`](/advanced/api/vitest#collect) 或 CLI 中的 `vitest collect`),在这种情况下,根本不会调用它,因为没有要运行的测试。
+在 [`onTestModuleCollected`](#ontestmodulecollected) 之后立即调用此方法,除非 Vitest 在收集模式下运行([`vitest.collect()`](/api/advanced/vitest#collect) 或 CLI 中的 `vitest collect`),在这种情况下,根本不会调用它,因为没有要运行的测试。
## onTestModuleEnd
@@ -234,7 +231,7 @@ function onTestModuleStart(testModule: TestModule): Awaitable
function onTestModuleEnd(testModule: TestModule): Awaitable
```
-当模块中的每个测试完成运行时调用此方法。这意味着 [`testModule.children`](/advanced/api/test-suite#children) 中的每个测试都将有一个不等于 `pending` 的 `test.result()`。
+当模块中的每个测试完成运行时调用此方法。这意味着 [`testModule.children`](/api/advanced/test-suite#children) 中的每个测试都将有一个不等于 `pending` 的 `test.result()`。
## onHookStart
@@ -249,9 +246,9 @@ function onHookStart(context: ReportedHookContext): Awaitable
- `beforeEach`
- `afterEach`
-如果 `beforeAll` 或 `afterAll` 开始,`entity` 将是 [`TestSuite`](/advanced/api/test-suite) 或 [`TestModule`](/advanced/api/test-module)。
+如果 `beforeAll` 或 `afterAll` 开始,`entity` 将是 [`TestSuite`](/api/advanced/test-suite) 或 [`TestModule`](/api/advanced/test-module)。
-如果 `beforeEach` 或 `afterEach` 开始,`entity` 将始终是 [`TestCase`](/advanced/api/test-case)。
+如果 `beforeEach` 或 `afterEach` 开始,`entity` 将始终是 [`TestCase`](/api/advanced/test-case)。
::: warning
如果钩子在测试运行期间没有运行,则不会调用 `onHookStart` 方法。
@@ -270,9 +267,9 @@ function onHookEnd(context: ReportedHookContext): Awaitable
- `beforeEach`
- `afterEach`
-如果 `beforeAll` 或 `afterAll` 完成,`entity` 将是 [`TestSuite`](/advanced/api/test-suite) 或 [`TestModule`](/advanced/api/test-module)。
+如果 `beforeAll` 或 `afterAll` 完成,`entity` 将是 [`TestSuite`](/api/advanced/test-suite) 或 [`TestModule`](/api/advanced/test-module)。
-如果 `beforeEach` 或 `afterEach` 完成,`entity` 将始终是 [`TestCase`](/advanced/api/test-case)。
+如果 `beforeEach` 或 `afterEach` 完成,`entity` 将始终是 [`TestCase`](/api/advanced/test-case)。
::: warning
如果钩子在测试运行期间没有运行,则不会调用 `onHookEnd` 方法。
@@ -307,7 +304,7 @@ function onTestCaseReady(testCase: TestCase): Awaitable
在测试开始运行或被跳过之前调用此方法。请注意,`beforeEach` 和 `afterEach` 钩子被视为测试的一部分,因为它们可能会影响结果。
::: warning
-请注意,当调用 `onTestCaseReady` 时,[`testCase.result()`](/advanced/api/test-case#result) 可能已经具有 `passed` 或 `failed` 状态。如果测试运行得太快,并且 `onTestCaseReady` 和 `onTestCaseResult` 被安排在同一微任务中运行,则可能发生这种情况。
+请注意,当调用 `onTestCaseReady` 时,[`testCase.result()`](/api/advanced/test-case#result) 可能已经具有 `passed` 或 `failed` 状态。如果测试运行得太快,并且 `onTestCaseReady` 和 `onTestCaseResult` 被安排在同一微任务中运行,则可能发生这种情况。
:::
## onTestCaseResult
@@ -318,7 +315,7 @@ function onTestCaseResult(testCase: TestCase): Awaitable
当测试完成运行或刚刚被跳过时调用此方法。请注意,如果有 `afterEach` 钩子,这将在 `afterEach` 钩子完成后调用。
-此时,[`testCase.result()`](/advanced/api/test-case#result) 已不再是挂起状态。
+此时,[`testCase.result()`](/api/advanced/test-case#result) 已不再是挂起状态。
## onTestAnnotate 3.2.0 {#ontestannotate}
@@ -332,3 +329,19 @@ function onTestAnnotate(
onTestAnnotate 是与 [`context.annotate`](/guide/test-context#annotate) 方法配套使用的钩子。当你在测试中调用 annotate 后, Vitest 会将注解内容序列化,并将其发送到主线程,从而让报告器可以处理这些附加信息。
如果在注解中指定了文件路径, Vitest 会将附件保存到一个独立的目录(该目录通过 [`attachmentsDir`](/config/#attachmentsdir) 配置),并自动更新 path 属性,使其指向存储后的文件位置。
+
+
+## onTestCaseArtifactRecord 4.0.11 {#ontestcaseartifactrecord}
+
+```ts
+function onTestCaseArtifactRecord(
+ testCase: TestCase,
+ artifact: TestArtifact,
+): Awaitable
+```
+
+The `onTestCaseArtifactRecord` hook is associated with the [`recordArtifact`](/api/advanced/artifacts#recordartifact) utility. When `recordArtifact` is invoked, Vitest serialises it and sends the same attachment to the main thread where reporter can interact with it.
+
+If the path is specified, Vitest stores it in a separate directory (configured by [`attachmentsDir`](/config/#attachmentsdir)) and modifies the `path` property to reference it.
+
+Note: annotations, [even though they're built on top of this feature](/api/advanced/artifacts#relationship-with-annotations), won't hit this hook and won't appear in the `task.artifacts` array for backwards compatibility reasons until the next major version.
diff --git a/advanced/runner.md b/api/advanced/runner.md
similarity index 96%
rename from advanced/runner.md
rename to api/advanced/runner.md
index 0311e34d..5ffda2fa 100644
--- a/advanced/runner.md
+++ b/api/advanced/runner.md
@@ -1,4 +1,4 @@
-# 运行器 API {#runner-api}
+# 运行器 API advanced
::: warning 注意
这是高级 API。如果你只需要 [运行测试](/guide/),你可能不需要这个。它主要被库的作者使用。
@@ -31,7 +31,7 @@ export interface VitestRunner {
* 这是在实际运行测试函数之前被调用的。
* 此时已经有了带有 "state" 和 "startTime" 属性的 "result" 对象。
*/
- onBeforeTryTask?: (test: Test, options: { retry: number, repeats: number }) => unknown
+ onBeforeTryTask?: (test: Test, options: { retry: number; repeats: number }) => unknown
/**
* 这是在结果和状态都被设置之后被调用的。
*/
@@ -40,12 +40,12 @@ export interface VitestRunner {
* 这是在运行测试函数后立即被调用的。此时还没有新的状态。
* 如果测试函数抛出异常,将不会调用此方法。
*/
- onAfterTryTask?: (test: Test, options: { retry: number, repeats: number }) => unknown
+ onAfterTryTask?: (test: Test, options: { retry: number; repeats: number }) => unknown
/**
* 在重试结果确定后调用。与 `onAfterTryTask` 不同,此时测试已进入新的状态,
* 并且所有的 `after` 钩子此时也已被执行。
*/
- onAfterRetryTask?: (test: Test, options: { retry: number, repeats: number }) => unknown
+ onAfterRetryTask?: (test: Test, options: { retry: number; repeats: number }) => unknown
/**
* 这是在运行单个测试套件之前被调用的,此时还没有测试结果。
@@ -153,7 +153,7 @@ export default class Runner {
## Tasks {#tasks}
::: warning
-“Runner Tasks API” 是实验性的,主要应在测试运行时使用。Vitest 还暴露了 [“Reported Tasks API”](/advanced/api/test-module),在主线程中工作时(例如在报告器内部)应优先使用。
+“Runner Tasks API” 是实验性的,主要应在测试运行时使用。Vitest 还暴露了 [“Reported Tasks API”](/api/advanced/test-module),在主线程中工作时(例如在报告器内部)应优先使用。
团队目前正在讨论未来是否应将“Runner Tasks”替换为“Reported Tasks”。
:::
diff --git a/advanced/api/test-case.md b/api/advanced/test-case.md
similarity index 85%
rename from advanced/api/test-case.md
rename to api/advanced/test-case.md
index 334c473e..eceb927e 100644
--- a/advanced/api/test-case.md
+++ b/api/advanced/test-case.md
@@ -1,6 +1,6 @@
# TestCase
-`TestCase` 类表示单个测试。此类仅在主线程中可用。如果您正在处理运行时任务,请参阅 [“运行器 API”](/advanced/runner#tasks)。
+`TestCase` 类表示单个测试。此类仅在主线程中可用。如果您正在处理运行时任务,请参阅 [“运行器 API”](/api/advanced/runner#tasks)。
`TestCase` 实例始终有一个值为 `test` 的 `type` 属性。您可以使用它来区分不同的任务类型:
@@ -12,11 +12,11 @@ if (task.type === 'test') {
## project
-这引用了测试所属的 [`TestProject`](/advanced/api/test-project)。
+这引用了测试所属的 [`TestProject`](/api/advanced/test-project)。
## module
-这是对定义测试的 [`TestModule`](/advanced/api/test-module) 的直接引用。
+这是对定义测试的 [`TestModule`](/api/advanced/test-module) 的直接引用。
## name
@@ -49,7 +49,7 @@ describe('the validation logic', () => {
## id
-这是测试的唯一标识符。此 ID 是确定性的,在多次运行中相同的测试将具有相同的 ID。ID 基于 [project](/advanced/api/test-project) 名称、模块 ID 和测试顺序。
+这是测试的唯一标识符。此 ID 是确定性的,在多次运行中相同的测试将具有相同的 ID。ID 基于 [project](/api/advanced/test-project) 名称、模块 ID 和测试顺序。
ID 的格式如下:
@@ -94,7 +94,7 @@ test('the validation works correctly', () => {
## parent
-父级 [suite](/advanced/api/test-suite)。如果测试是直接在 [模块](/advanced/api/test-module) 内调用的,则父级将是模块本身。
+父级 [suite](/api/advanced/test-suite)。如果测试是直接在 [模块](/api/advanced/test-module) 内调用的,则父级将是模块本身。
## options
@@ -126,7 +126,7 @@ function ok(): boolean
function meta(): TaskMeta
```
-在测试执行期间附加到测试上的自定义[元数据](/advanced/metadata)。我们可以在测试运行期间通过给 `ctx.task.meta` 对象分配属性来附加元数据。
+在测试执行期间附加到测试上的自定义[元数据](/api/advanced/metadata)。我们可以在测试运行期间通过给 `ctx.task.meta` 对象分配属性来附加元数据。
```ts {3,6}
import { test } from 'vitest'
@@ -265,3 +265,19 @@ interface TestDiagnostic {
::: info
如果测试尚未被安排运行,`diagnostic()` 将返回 `undefined`。
:::
+
+## annotations
+
+```ts
+function annotations(): ReadonlyArray
+```
+
+[Test annotations](/guide/test-annotations) added via the [`task.annotate`](/guide/test-context#annotate) API during the test execution.
+
+## artifacts 4.0.11 {#artifacts}
+
+```ts
+function artifacts(): ReadonlyArray
+```
+
+[Test artifacts](/api/advanced/artifacts) recorded via the `recordArtifact` API during the test execution.
diff --git a/advanced/api/test-collection.md b/api/advanced/test-collection.md
similarity index 93%
rename from advanced/api/test-collection.md
rename to api/advanced/test-collection.md
index f7dd40de..f19c83db 100644
--- a/advanced/api/test-collection.md
+++ b/api/advanced/test-collection.md
@@ -1,6 +1,6 @@
# TestCollection
-`TestCollection` 表示套件或模块中顶级 [suite](/advanced/api/test-suite) 和 [test](/advanced/api/test-case) 的集合。它还提供了有用的方法来迭代自身。
+`TestCollection` 表示套件或模块中顶级 [suite](/api/advanced/test-suite) 和 [test](/api/advanced/test-case) 的集合。它还提供了有用的方法来迭代自身。
::: info
大多数方法返回迭代器而不是数组,以在你不需使用集合中的每个项目时提高性能。如果你更喜欢使用数组,可以展开迭代器:`[...children.allSuites()]`。
diff --git a/advanced/api/test-module.md b/api/advanced/test-module.md
similarity index 86%
rename from advanced/api/test-module.md
rename to api/advanced/test-module.md
index c88c8ec1..2bf88e8b 100644
--- a/advanced/api/test-module.md
+++ b/api/advanced/test-module.md
@@ -1,6 +1,6 @@
# TestModule
-`TestModule` 类表示项目中的单个模块。此类仅在主线程中可用。如果你正在处理运行时任务,请参阅 [“运行器 API”](/advanced/runner#tasks)。
+`TestModule` 类表示项目中的单个模块。此类仅在主线程中可用。如果你正在处理运行时任务,请参阅 [“运行器 API”](/api/advanced/runner#tasks)。
`TestModule` 实例始终具有一个 `type` 属性,其值为 `module`。你可以使用它来区分不同的任务类型:
@@ -11,7 +11,7 @@ if (task.type === 'module') {
```
::: warning 扩展 Suite 的方法
-`TestModule` 类继承了 [`TestSuite`](/advanced/api/test-suite) 的所有方法和属性。本指南将列出 `TestModule` 独有的方法和属性。
+`TestModule` 类继承了 [`TestSuite`](/api/advanced/test-suite) 的所有方法和属性。本指南将列出 `TestModule` 独有的方法和属性。
:::
## moduleId
@@ -40,7 +40,7 @@ if (task.type === 'module') {
function state(): TestModuleState
```
-与 [`testSuite.state()`](/advanced/api/test-suite#state) 的工作方式相同,但如果模块尚未执行,还可以返回 `queued`。
+与 [`testSuite.state()`](/api/advanced/test-suite#state) 的工作方式相同,但如果模块尚未执行,还可以返回 `queued`。
## meta 3.1.0 {#meta}
@@ -48,7 +48,7 @@ function state(): TestModuleState
function meta(): TaskMeta
```
-在模块执行或收集过程中附加到模块的自定义 [元数据](/advanced/metadata)。在测试运行期间,可以通过向 `task.meta` 对象分配属性来附加 meta:
+在模块执行或收集过程中附加到模块的自定义 [元数据](/api/advanced/metadata)。在测试运行期间,可以通过向 `task.meta` 对象分配属性来附加 meta:
```ts {5,10}
import { test } from 'vitest'
@@ -120,3 +120,7 @@ interface ImportDuration {
totalTime: number
}
```
+
+## viteEnvironment 4.0.15 {#viteenvironment}
+
+This is a Vite's [`DevEnvironment`](https://vite.dev/guide/api-environment) that transforms all files inside of the test module.
diff --git a/advanced/api/test-project.md b/api/advanced/test-project.md
similarity index 93%
rename from advanced/api/test-project.md
rename to api/advanced/test-project.md
index 1d5f8c52..c357ad17 100644
--- a/advanced/api/test-project.md
+++ b/api/advanced/test-project.md
@@ -51,12 +51,12 @@ export default defineConfig({
:::
::: info
-如果 [根项目](/advanced/api/vitest#getroottestproject) 不是用户工作区的一部分,则不会解析其 `name`。
+如果 [根项目](/api/advanced/vitest#getroottestproject) 不是用户工作区的一部分,则不会解析其 `name`。
:::
## vitest
-`vitest` 引用全局的 [`Vitest`](/advanced/api/vitest) 进程。
+`vitest` 引用全局的 [`Vitest`](/api/advanced/vitest) 进程。
## serializedConfig
@@ -78,7 +78,7 @@ project.serializedConfig === project.serializedConfig // ❌
## globalConfig
-[`Vitest`](/advanced/api/vitest) 初始化时的测试配置。如果这是 [根项目](/advanced/api/vitest#getroottestproject),`globalConfig` 和 `config` 将引用同一个对象。此配置对于无法在项目级别设置的值非常有用,例如 `coverage` 或 `reporters`。
+[`Vitest`](/api/advanced/vitest) 初始化时的测试配置。如果这是 [根项目](/api/advanced/vitest#getroottestproject),`globalConfig` 和 `config` 将引用同一个对象。此配置对于无法在项目级别设置的值非常有用,例如 `coverage` 或 `reporters`。
```ts
import type { ResolvedConfig } from 'vitest/node'
@@ -179,7 +179,7 @@ function createSpecification(
): TestSpecification
```
-创建一个 [测试规范](/advanced/api/test-specification),可用于 [`vitest.runTestSpecifications`](/advanced/api/vitest#runtestspecifications)。规范将测试文件限定到特定的 `project` 和测试 `locations`(可选)。测试 [位置](/advanced/api/test-case#location) 是源代码中定义测试的代码行。如果提供了位置,Vitest 将仅运行在这些行上定义的测试。请注意,如果定义了 [`testNamePattern`](/config/#testnamepattern),则它也将被应用。
+创建一个 [测试规范](/api/advanced/test-specification),可用于 [`vitest.runTestSpecifications`](/api/advanced/vitest#runtestspecifications)。规范将测试文件限定到特定的 `project` 和测试 `locations`(可选)。测试 [位置](/api/advanced/test-case#location) 是源代码中定义测试的代码行。如果提供了位置,Vitest 将仅运行在这些行上定义的测试。请注意,如果定义了 [`testNamePattern`](/config/#testnamepattern),则它也将被应用。
```ts
import { resolve } from 'node:path/posix'
@@ -195,7 +195,7 @@ await vitest.runTestSpecifications([specification])
```
::: warning
-`createSpecification` 期望传入已解析的 [模块 ID](/advanced/api/test-specification#moduleid)。它不会自动解析文件或检查文件系统中是否存在该文件。
+`createSpecification` 期望传入已解析的 [模块 ID](/api/advanced/test-specification#moduleid)。它不会自动解析文件或检查文件系统中是否存在该文件。
另请注意,`project.createSpecification` 总是返回一个新实例。
:::
@@ -225,7 +225,7 @@ function globTestFiles(filters?: string[]): {
全局匹配所有测试文件。此函数返回一个包含常规测试和类型检查测试的对象。
-此方法接受 `filters`。过滤器只能是文件路径的一部分,与 [`Vitest`](/advanced/api/vitest) 实例上的其他方法不同:
+此方法接受 `filters`。过滤器只能是文件路径的一部分,与 [`Vitest`](/api/advanced/vitest) 实例上的其他方法不同:
```js
project.globTestFiles(['foo']) // ✅
@@ -298,7 +298,7 @@ Vitest 在内部通过这个方法加载全局设置、自定义的覆盖率提
function onTestsRerun(cb: OnTestsRerunHandler): void
```
-这是 [`project.vitest.onTestsRerun`](/advanced/api/vitest#ontestsrerun) 的简写。它接受一个回调,当测试被安排重新运行时(通常是由于文件更改)将等待该回调。
+这是 [`project.vitest.onTestsRerun`](/api/advanced/vitest#ontestsrerun) 的简写。它接受一个回调,当测试被安排重新运行时(通常是由于文件更改)将等待该回调。
```ts
project.onTestsRerun((specs) => {
diff --git a/advanced/api/test-specification.md b/api/advanced/test-specification.md
similarity index 89%
rename from advanced/api/test-specification.md
rename to api/advanced/test-specification.md
index 6d7a65e4..8a5b3590 100644
--- a/advanced/api/test-specification.md
+++ b/api/advanced/test-specification.md
@@ -2,7 +2,7 @@
`TestSpecification` 类描述了要作为测试运行的模块及其参数。
-你只能通过在测试项目上调用 [`createSpecification`](/advanced/api/test-project#createspecification) 方法来创建规范:
+你只能通过在测试项目上调用 [`createSpecification`](/api/advanced/test-project#createspecification) 方法来创建规范:
```ts
const specification = project.createSpecification(
@@ -15,11 +15,11 @@ const specification = project.createSpecification(
## taskId
-[测试模块的](/advanced/api/test-suite#id) 标识符。
+[测试模块](/api/advanced/test-suite#id) 的标识符。
## project
-这引用了测试模块所属的 [`TestProject`](/advanced/api/test-project)。
+这引用了测试模块所属的 [`TestProject`](/api/advanced/test-project)。
## moduleId
@@ -33,7 +33,7 @@ Vite 模块图中的模块 ID。通常,它是一个使用 POSIX 分隔符的
## testModule
-与规范相关联的 [`TestModule`](/advanced/api/test-module) 实例。如果测试还未加入队列,则将是 `undefined`。
+与规范相关联的 [`TestModule`](/api/advanced/test-module) 实例。如果测试还未加入队列,则将是 `undefined`。
## pool experimental {#pool}
diff --git a/advanced/api/test-suite.md b/api/advanced/test-suite.md
similarity index 83%
rename from advanced/api/test-suite.md
rename to api/advanced/test-suite.md
index 168abfb5..949c4240 100644
--- a/advanced/api/test-suite.md
+++ b/api/advanced/test-suite.md
@@ -1,6 +1,6 @@
# TestSuite
-`TestSuite` 类表示一个单一的套件。此类仅在主线程中可用。如果你正在处理运行时任务,请参阅 [“运行器 API”](/advanced/runner#tasks)。
+`TestSuite` 类表示一个单一的套件。此类仅在主线程中可用。如果你正在处理运行时任务,请参阅 [“运行器 API”](/api/advanced/runner#tasks)。
`TestSuite` 实例始终具有一个 `type` 属性,其值为 `suite`。你可以使用它来区分不同的任务类型:
@@ -12,11 +12,11 @@ if (task.type === 'suite') {
## project
-这引用了测试所属的 [`TestProject`](/advanced/api/test-project)。
+这引用了测试所属的 [`TestProject`](/api/advanced/test-project)。
## module
-这是对定义测试的 [`TestModule`](/advanced/api/test-module) 的直接引用。
+这是对定义测试的 [`TestModule`](/api/advanced/test-module) 的直接引用。
## name
@@ -49,7 +49,7 @@ describe('the validation logic', () => {
## id
-这是套件的唯一标识符。此 ID 是确定性的,在多次运行中相同的套件将具有相同的 ID。ID 基于 [项目](/advanced/api/test-project) 名称、模块 ID 和套件顺序。
+这是套件的唯一标识符。此 ID 是确定性的,在多次运行中相同的套件将具有相同的 ID。ID 基于 [项目](/api/advanced/test-project) 名称、模块 ID 和套件顺序。
ID 的格式如下:
@@ -63,7 +63,7 @@ ID 的格式如下:
::: tip
你可以使用 `vitest/node` 中的 `generateFileHash` 函数生成文件哈希,该函数自 Vitest 3 起可用:
-
+
```ts
import { generateFileHash } from 'vitest/node'
@@ -95,7 +95,7 @@ describe('the validation works correctly', () => {
## parent
-父级套件。如果套件是在 [模块](/advanced/api/test-module) 内直接调用的,则父级将是模块本身。
+父级套件。如果套件是在 [模块](/api/advanced/test-module) 内直接调用的,则父级将是模块本身。
## options
@@ -115,7 +115,7 @@ interface TaskOptions {
## children
-这是当前套件内所有套件和测试的 [集合](/advanced/api/test-collection)。
+这是当前套件内所有套件和测试的 [集合](/api/advanced/test-collection)。
```ts
for (const task of suite.children) {
@@ -130,7 +130,7 @@ for (const task of suite.children) {
```
::: warning
-请注意,`suite.children` 只会遍历第一层嵌套,不会深入嵌套层次。如果我们需要遍历所有测试或套件,请使用 [`children.allTests()`](/advanced/api/test-collection#alltests) 或 [`children.allSuites()`](/advanced/api/test-collection#allsuites)。如果我们需要遍历所有内容,请使用递归函数。
+请注意,`suite.children` 只会遍历第一层嵌套,不会深入嵌套层次。如果我们需要遍历所有测试或套件,请使用 [`children.allTests()`](/api/advanced/test-collection#alltests) 或 [`children.allSuites()`](/api/advanced/test-collection#allsuites)。如果我们需要遍历所有内容,请使用递归函数。
```ts
function visit(collection: TestCollection) {
@@ -170,7 +170,7 @@ function state(): TestSuiteState
- **skipped**:此套件在收集过程中被跳过。
::: warning
-请注意,[测试模块](/advanced/api/test-module) 也有一个 `state` 方法,返回相同的值,但如果模块尚未执行,它还可以返回一个额外的 `queued` 状态。
+请注意,[测试模块](/api/advanced/test-module) 也有一个 `state` 方法,返回相同的值,但如果模块尚未执行,它还可以返回一个额外的 `queued` 状态。
:::
## errors
@@ -198,14 +198,16 @@ describe('collection failed', () => {
```ts
function meta(): TaskMeta
```
-在执行或收集过程中附加到套件的自定义[元数据](/advanced/metadata)。在测试运行期间,可以通过向 `task.meta` 对象分配属性来附加 meta:
-
-```ts {5,10}
+在执行或收集过程中附加到套件的自定义[元数据](/api/advanced/metadata)。在测试运行期间,可以通过向 `task.meta` 对象分配属性来附加 meta:
+
+```ts {7,12}
import { test } from 'vitest'
+import { getCurrentSuite } from 'vitest/suite'
-describe('the validation works correctly', (task) => {
- // 在收集过程中指定 “decorated”
- task.meta.decorated = false
+describe('the validation works correctly', () => {
+ // assign "decorated" during collection
+ const { suite } = getCurrentSuite()
+ suite!.meta.decorated = true
test('some test', ({ task }) => {
// 在试运行期间指定 “decorated”,它将可用
diff --git a/advanced/api/vitest.md b/api/advanced/vitest.md
similarity index 85%
rename from advanced/api/vitest.md
rename to api/advanced/vitest.md
index d6cab735..87c9e845 100644
--- a/advanced/api/vitest.md
+++ b/api/advanced/vitest.md
@@ -53,7 +53,7 @@ Vitest 4 新增了多个 API(它们都标记有 "4.0.0+" 徽章),并移除
公共 `state` 是一个实验性 API(除了 `vitest.state.getReportedEntity`)。破坏性更改可能不遵循 SemVer,请在使用时固定 Vitest 的版本。
:::
-全局状态存储有关当前测试的信息。默认情况下,它使用与 `@vitest/runner` 相同的 API,但我们建议通过调用 `@vitest/runner` API 上的 `state.getReportedEntity()` 来使用 [任务报告器 API](/advanced/reporters#reported-tasks):
+全局状态存储有关当前测试的信息。默认情况下,它使用与 `@vitest/runner` 相同的 API,但我们建议通过调用 `@vitest/runner` API 上的 `state.getReportedEntity()` 来使用 [任务报告器 API](/api/advanced/reporters#reported-tasks):
```ts
const task = vitest.state.idMap.get(taskId) // 旧 API
@@ -78,7 +78,7 @@ const testCase = vitest.state.getReportedEntity(task) // 新 API
## projects
-这是一个数组,里面包含了所有 [测试项目](/advanced/api/test-project) ,这些项目是用户自己定义的。如果用户没有显式指定任何项目,那么这个数组中只会包含一个 [根项目](#getrootproject) 。
+这是一个数组,里面包含了所有 [测试项目](/api/advanced/test-project) ,这些项目是用户自己定义的。如果用户没有显式指定任何项目,那么这个数组中只会包含一个 [根项目](#getrootproject) 。
Vitest 会保证这个数组里至少有一个项目可用。如果用户在命令行里通过 --project 参数指定了不存在的项目名称,Vitest 会在创建这个数组前就报错。
@@ -132,7 +132,7 @@ declare module 'vitest' {
```
::: warning
-从技术角度讲,`provide` 是 [`TestProject`](/advanced/api/test-project) 的一种方法,因此它仅限于特定项目。但是,所有项目都会从根项目继承值,这使得 `vitest.provide` 成为将值传递给测试的通用方法。
+从技术角度讲,`provide` 是 [`TestProject`](/api/advanced/test-project) 的一种方法,因此它仅限于特定项目。但是,所有项目都会从根项目继承值,这使得 `vitest.provide` 成为将值传递给测试的通用方法。
:::
## getProvidedContext
@@ -165,7 +165,7 @@ function globTestSpecifications(
): Promise
```
-此方法通过收集所有项目中的每个测试来构造新的 [测试规范](/advanced/api/test-specification),使用 [`project.globTestFiles`](/advanced/api/test-project#globtestfiles)。它接受字符串过滤器以匹配测试文件 - 这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。
+此方法通过收集所有项目中的每个测试来构造新的 [测试规范](/api/advanced/test-specification),使用 [`project.globTestFiles`](/api/advanced/test-project#globtestfiles)。它接受字符串过滤器以匹配测试文件 - 这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。
此方法自动缓存所有测试规范。当我们下次调用 [`getModuleSpecifications`](#getmodulespecifications) 时,它将返回相同的规范,除非在此之前调用了 [`clearSpecificationsCache`](#clearspecificationscache)。
@@ -187,7 +187,7 @@ function getRelevantTestSpecifications(
): Promise
```
-此方法通过调用 [`project.globTestFiles`](/advanced/api/test-project#globtestfiles) 解析每个测试规范。它接受字符串过滤器以匹配测试文件 - 这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。如果指定了 `--changed` 标志,则列表将被过滤为仅包含已更改的文件。`getRelevantTestSpecifications` 不会运行任何测试文件。
+此方法通过调用 [`project.globTestFiles`](/api/advanced/test-project#globtestfiles) 解析每个测试规范。它接受字符串过滤器以匹配测试文件 - 这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。如果指定了 `--changed` 标志,则列表将被过滤为仅包含已更改的文件。`getRelevantTestSpecifications` 不会运行任何测试文件。
::: warning
此方法可能很慢,因为它需要过滤 `--changed` 标志。如果我们只需要测试文件列表,请不要使用它。
@@ -206,7 +206,7 @@ function mergeReports(directory?: string): Promise
请注意,`directory` 将始终相对于工作目录解析。
-如果设置了 `config.mergeReports`,则此方法由 [`startVitest`](/advanced/guide/tests) 自动调用。
+如果设置了 `config.mergeReports`,则此方法由 [`startVitest`](/guide/advanced/) 自动调用。
## collect
@@ -214,9 +214,9 @@ function mergeReports(directory?: string): Promise
function collect(filters?: string[]): Promise
```
-执行测试文件而不运行测试回调。`collect` 返回未处理的错误和 [测试模块](/advanced/api/test-module) 数组。它接受字符串过滤器以匹配测试文件 - 这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。
+执行测试文件而不运行测试回调。`collect` 返回未处理的错误和 [测试模块](/api/advanced/test-module) 数组。它接受字符串过滤器以匹配测试文件 - 这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。
-此方法根据配置的 `include`、`exclude` 和 `includeSource` 值解析测试规范。有关更多信息,请参阅 [`project.globTestFiles`](/advanced/api/test-project#globtestfiles)。如果指定了 `--changed` 标志,则列表将被过滤为仅包含已更改的文件。
+此方法根据配置的 `include`、`exclude` 和 `includeSource` 值解析测试规范。有关更多信息,请参阅 [`project.globTestFiles`](/api/advanced/test-project#globtestfiles)。如果指定了 `--changed` 标志,则列表将被过滤为仅包含已更改的文件。
::: warning
请注意,Vitest 不使用静态分析来收集测试。Vitest 将像运行常规测试一样在隔离环境中运行每个测试文件。
@@ -236,7 +236,7 @@ function start(filters?: string[]): Promise
如果还调用了 [`vitest.init()`](#init),则不应调用此方法。如果我们需要在 Vitest 初始化后运行测试,请使用 [`runTestSpecifications`](#runtestspecifications) 或 [`rerunTestSpecifications`](#reruntestspecifications)。
:::
-如果未设置 `config.mergeReports` 和 `config.standalone`,则此方法由 [`startVitest`](/advanced/guide/tests) 自动调用。
+如果未设置 `config.mergeReports` 和 `config.standalone`,则此方法由 [`startVitest`](/guide/advanced/tests) 自动调用。
## init
@@ -252,7 +252,7 @@ function init(): Promise
如果还调用了 [`vitest.start()`](#start),则不应调用此方法。
:::
-如果设置了 `config.standalone`,则此方法由 [`startVitest`](/advanced/guide/tests) 自动调用。
+如果设置了 `config.standalone`,则此方法由 [`startVitest`](/guide/advanced/tests) 自动调用。
## getModuleSpecifications
@@ -262,7 +262,7 @@ function getModuleSpecifications(moduleId: string): TestSpecification[]
返回与模块 ID 相关的测试规范列表。ID 应已解析为绝对文件路径。如果 ID 不匹配 `include` 或 `includeSource` 模式,则返回的数组将为空。
-此方法可以根据 `moduleId` 和 `pool` 返回已缓存的规范。但请注意,[`project.createSpecification`](/advanced/api/test-project#createspecification) 总是返回一个新实例,并且不会自动缓存。但是,当调用 [`runTestSpecifications`](#runtestspecifications) 时,规范会自动缓存。
+此方法可以根据 `moduleId` 和 `pool` 返回已缓存的规范。但请注意,[`project.createSpecification`](/api/advanced/test-project#createspecification) 总是返回一个新实例,并且不会自动缓存。但是,当调用 [`runTestSpecifications`](#runtestspecifications) 时,规范会自动缓存。
::: warning
从 Vitest 3 开始,此方法使用缓存来检查文件是否为测试文件。为确保缓存不为空,请至少调用一次 [`globTestSpecifications`](#globtestspecifications)。
@@ -285,7 +285,7 @@ function runTestSpecifications(
): Promise
```
-该方法会遍历并执行所有根据 [测试规格](/advanced/api/test-specification) 定义的测试用例。第二个参数 `allTestsRun` 则供覆盖率工具判断是否应在覆盖率报告中加入那些没有被任何测试覆盖到的文件。
+该方法会遍历并执行所有根据 [测试规格](/api/advanced/test-specification) 定义的测试用例。第二个参数 `allTestsRun` 则供覆盖率工具判断是否应在覆盖率报告中加入那些没有被任何测试覆盖到的文件。
::: warning
此方法不会触发 `onWatcherRerun`、`onWatcherStart` 和 `onTestsRerun` 回调。如果我们基于文件更改重新运行测试,请考虑使用 [`rerunTestSpecifications`](#reruntestspecifications) 代替。
@@ -318,7 +318,7 @@ function collectTests(
): Promise
```
-执行测试文件而不运行测试回调。`collectTests` 返回未处理的错误和 [测试模块](/advanced/api/test-module) 数组。
+执行测试文件而不运行测试回调。`collectTests` 返回未处理的错误和 [测试模块](/api/advanced/test-module) 数组。
此方法与 [`collect`](#collect) 完全相同,但我们需要自己提供测试规范。
@@ -348,7 +348,7 @@ function setGlobalTestNamePattern(pattern: string | RegExp): void
此方法不会开始运行任何测试。要使用更新后的模式运行测试,请调用 [`runTestSpecifications`](#runtestspecifications)。
:::
-## getGlobalTestNamePattern
+## getGlobalTestNamePattern 4.0.0 {#getglobaltestnamepattern}
```ts
function getGlobalTestNamePattern(): RegExp | undefined
@@ -458,11 +458,15 @@ function onServerRestart(fn: OnServerRestartHandler): void
## onCancel
```ts
-function onCancel(fn: (reason: CancelReason) => Awaitable): void
+function onCancel(fn: (reason: CancelReason) => Awaitable): () => void
```
注册一个处理程序,当测试运行被 [`vitest.cancelCurrentRun`](#cancelcurrentrun) 取消时调用。
+::: warning EXPERIMENTAL
+Since 4.0.10, `onCancel` returns a teardown function that will remove the listener.
+:::
+
## onClose
```ts
@@ -502,7 +506,7 @@ vitest.onFilterWatchedSpecification(specification =>
)
```
-Vitest 可以根据 `pool` 或 `locations` 选项为同一文件创建不同的规范,因此不要依赖引用。Vitest 还可以从 [`vitest.getModuleSpecifications`](#getmodulespecifications) 返回缓存的规范 - 缓存基于 `moduleId` 和 `pool`。请注意,[`project.createSpecification`](/advanced/api/test-project#createspecification) 总是返回一个新实例。
+Vitest 可以根据 `pool` 或 `locations` 选项为同一文件创建不同的规范,因此不要依赖引用。Vitest 还可以从 [`vitest.getModuleSpecifications`](#getmodulespecifications) 返回缓存的规范 - 缓存基于 `moduleId` 和 `pool`。请注意,[`project.createSpecification`](/api/advanced/test-project#createspecification) 总是返回一个新实例。
## matchesProjectFilter 3.1.0 {#matchesprojectfilter}
@@ -560,7 +564,7 @@ function getSeed(): number | null
如果测试以随机顺序运行,则返回种子值。
-## experimental_parseSpecification 4.0.0 experimental {#parsespecification}
+## experimental_parseSpecification 4.0.0 {#parsespecification}
```ts
function experimental_parseSpecification(
@@ -597,7 +601,7 @@ Vitest 只会收集当前文件内定义的测试,绝不会跟随导入去其
无论是否从 `vitest` 入口点导入, Vitest 都会收集所有 `it` 、`test` 、`suite` 和 `describe` 的定义。
:::
-## experimental_parseSpecifications 4.0.0 实验 {#parsespecifications}
+## experimental_parseSpecifications 4.0.0 {#parsespecifications}
```ts
function experimental_parseSpecifications(
@@ -607,7 +611,70 @@ function experimental_parseSpecifications(
}
): Promise
```
+
+This method will [collect tests](#parsespecification) from an array of specifications. By default, Vitest will run only `os.availableParallelism()` number of specifications at a time to reduce the potential performance degradation. You can specify a different number in a second argument.
+
+## experimental_clearCache 4.0.11 {#clearcache}
+
+```ts
+function experimental_clearCache(): Promise
+```
+
+Deletes all Vitest caches, including [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache).
+
+## experimental_getSourceModuleDiagnostic 4.0.15 {#getsourcemodulediagnostic}
+
+```ts
+export function experimental_getSourceModuleDiagnostic(
+ moduleId: string,
+ testModule?: TestModule,
+): Promise
+```
+
+::: details Types
+```ts
+export interface ModuleDefinitionLocation {
+ line: number
+ column: number
+}
+
+export interface SourceModuleLocations {
+ modules: ModuleDefinitionDiagnostic[]
+ untracked: ModuleDefinitionDiagnostic[]
+}
+
+export interface ModuleDefinitionDiagnostic {
+ start: ModuleDefinitionLocation
+ end: ModuleDefinitionLocation
+ startIndex: number
+ endIndex: number
+ url: string
+ resolvedId: string
+}
+
+export interface ModuleDefinitionDurationsDiagnostic extends ModuleDefinitionDiagnostic {
+ selfTime: number
+ totalTime: number
+ external?: boolean
+}
+
+export interface UntrackedModuleDefinitionDiagnostic {
+ url: string
+ resolvedId: string
+ selfTime: number
+ totalTime: number
+ external?: boolean
+}
+
+export interface SourceModuleDiagnostic {
+ modules: ModuleDefinitionDurationsDiagnostic[]
+ untrackedModules: UntrackedModuleDefinitionDiagnostic[]
+}
+```
+:::
-该方法会依据规格数组 [collect tests](#parsespecification)。
+Returns module's diagnostic. If [`testModule`](/api/advanced/test-module) is not provided, `selfTime` and `totalTime` will be aggregated across all tests that were running the last time. If the module was not transformed or executed, the diagnostic will be empty.
-默认情况下, Vitest 仅同时运行 `os.availableParallelism()` 个规格,以避免性能骤降。我们可以在第二个参数中指定其他并发数。
+::: warning
+At the moment, the [browser](/guide/browser/) modules are not supported.
+:::
diff --git a/guide/browser/assertion-api.md b/api/browser/assertions.md
similarity index 99%
rename from guide/browser/assertion-api.md
rename to api/browser/assertions.md
index 149f593b..af28e165 100644
--- a/guide/browser/assertion-api.md
+++ b/api/browser/assertions.md
@@ -1,5 +1,5 @@
---
-title: Assertion API | Browser Mode
+title: Assertion API | 浏览器模式
---
# Assertion API
@@ -298,7 +298,7 @@ await expect.element(
).toBeVisible()
```
-## toBeInViewport
+## toBeInViewport 4.0.0 {#tobeinviewport}
```ts
function toBeInViewport(options: { ratio?: number }): Promise
@@ -324,7 +324,7 @@ await expect.element(page.getByText('Vitest')).toBeInViewport({ ratio: 1 })
## toContainElement
```ts
-function toContainElement(element: HTMLElement | SVGElement | null): Promise
+function toContainElement(element: HTMLElement | SVGElement | Locator | null): Promise
```
这允许你断言一个元素是否包含另一个作为其后代的元素。
@@ -1016,7 +1016,7 @@ function toMatchScreenshot(
```
::: tip
-`toMatchScreenshot` 断言可在 [Vitest 配置](/guide/browser/config#browser-expect-tomatchscreenshot) 中全局设定。
+`toMatchScreenshot` 断言可在 [Vitest 配置](/config/browser/expect#tomatchscreenshot) 中全局设定。
:::
该断言通过将元素或整页的截图与预先保存的基准图像进行比对,实现视觉回归测试。
@@ -1115,7 +1115,7 @@ await expect.element(getByTestId('button')).toMatchScreenshot('fancy-button', {
- `screenshotOptions: object`
- 与 [`locator.screenshot()`](/guide/browser/locators.html#screenshot) 支持的选项一致,但以下情况除外:
+ 与 [`locator.screenshot()`](/api/browser/locators.html#screenshot) 支持的选项一致,但以下情况除外:
- `'base64'`
- `'path'`
diff --git a/guide/browser/commands.md b/api/browser/commands.md
similarity index 94%
rename from guide/browser/commands.md
rename to api/browser/commands.md
index dbc40daf..0b14ee94 100644
--- a/guide/browser/commands.md
+++ b/api/browser/commands.md
@@ -38,7 +38,7 @@ it('handles files', async () => {
## CDP Session
-Vitest 通过 `vitest/browser` 中导出的 `cdp` 方法访问原始 Chrome Devtools 协议。它主要用于库作者在其基础上构建工具。
+Vitest 通过 `vitest/browser` 中导出的 `cdp` 方法访问原始 Chrome DevTools 协议。它主要用于库作者在其基础上构建工具。
```ts
import { cdp } from 'vitest/browser'
@@ -61,7 +61,7 @@ CDP session仅适用于 `playwright` provider,并且仅在使用 `chromium`
## 自定义命令 {#custom-commands}
-我们也可以通过 [`browser.commands`](/guide/browser/config#browser-commands) 配置选项添加自己的命令。如果我们正在开发一个库,可以通过插件内的`config`钩子来提供它们:
+我们也可以通过 [`browser.commands`](/config/browser/commands) 配置选项添加自己的命令。如果我们正在开发一个库,可以通过插件内的 `config` 钩子来提供它们:
```ts
import type { Plugin } from 'vitest/config'
diff --git a/guide/browser/context.md b/api/browser/context.md
similarity index 80%
rename from guide/browser/context.md
rename to api/browser/context.md
index ac615fb3..917cceba 100644
--- a/guide/browser/context.md
+++ b/api/browser/context.md
@@ -1,5 +1,5 @@
---
-title: Context API | Browser Mode
+title: Context API | 浏览器模式
---
# 上下文 {#context-api}
@@ -9,7 +9,7 @@ Vitest 通过 `vitest/browser` 入口点公开上下文模块。从 2.0 开始
## `userEvent`
::: tip
-`userEvent` API 的详细说明见[Interactivity API](/guide/browser/interactivity-api)。
+`userEvent` API 的详细说明见 [Interactivity API](/api/browser/interactivity)。
:::
```ts
@@ -43,7 +43,7 @@ export const userEvent: {
## `commands`
::: tip
-Commands API 的详细说明见 [Commands API](/guide/browser/commands)。
+Commands API 的详细说明见 [Commands API](/api/browser/commands)。
:::
```ts
@@ -62,7 +62,7 @@ export const commands: BrowserCommands
虽然它从 Playwright 的 `page` 中获取了一些实用程序,但它与 Playwright 的 `page` 并不是同一个对象。由于浏览器上下文是在浏览器中评估的,您的测试无法访问 Playwright 的 `page`,因为它是在服务器上运行的。
:::
-使用 [Commands API](/guide/browser/commands) 如果您需要访问 Playwright 的 `page` 对象。
+使用 [Commands API](/api/browser/commands) 如果您需要访问 Playwright 的 `page` 对象。
```ts
export const page: {
/**
@@ -106,7 +106,7 @@ export const page: {
```
::: tip
-`getBy*` API 在 [Locators API](/guide/browser/locators) 中有详细说明。
+`getBy*` API 在 [Locators API](/api/browser/locators) 中有详细说明。
:::
::: warning WARNING 3.2.0
@@ -185,3 +185,43 @@ export const server: {
config: SerializedConfig
}
```
+
+## `utils`
+
+Utility functions useful for custom render libraries.
+
+```ts
+export const utils: {
+ /**
+ * This is simillar to calling `page.elementLocator`, but it returns only
+ * locator selectors.
+ */
+ getElementLocatorSelectors(element: Element): LocatorSelectors
+ /**
+ * Prints prettified HTML of an element.
+ */
+ debug(
+ el?: Element | Locator | null | (Element | Locator)[],
+ maxLength?: number,
+ options?: PrettyDOMOptions,
+ ): void
+ /**
+ * Returns prettified HTML of an element.
+ */
+ prettyDOM(
+ dom?: Element | Locator | undefined | null,
+ maxLength?: number,
+ prettyFormatOptions?: PrettyDOMOptions,
+ ): string
+ /**
+ * Configures default options of `prettyDOM` and `debug` functions.
+ * This will also affect `vitest-browser-{framework}` package.
+ * @experimental
+ */
+ configurePrettyDOM(options: StringifyOptions): void
+ /**
+ * Creates "Cannot find element" error. Useful for custom locators.
+ */
+ getElementError(selector: string, container?: Element): Error
+}
+```
diff --git a/guide/browser/interactivity-api.md b/api/browser/interactivity.md
similarity index 96%
rename from guide/browser/interactivity-api.md
rename to api/browser/interactivity.md
index 090bb4d6..0a8957f0 100644
--- a/guide/browser/interactivity-api.md
+++ b/api/browser/interactivity.md
@@ -60,10 +60,34 @@ test('clicks on an element', async () => {
await userEvent.click(logo)
// 或者你可以直接从定位器上访问
await logo.click()
+
+ // With WebdriverIO, this uses either ElementClick (with no arguments) or
+ // actions (with arguments). Use an empty object to force the use of actions.
+ await logo.click({})
})
```
+
+### Clicking with a modifier
-相关链接:
+With either WebdriverIO or Playwright:
+
+```ts
+await userEvent.keyboard('{Shift>}')
+// By using an empty object as the option, this opts in to using a chain of actions
+// instead of an ElementClick in webdriver.
+// Firefox has a bug that makes this necessary.
+// Follow https://bugzilla.mozilla.org/show_bug.cgi?id=1456642 to know when this
+// will be fixed.
+await userEvent.click(element, {})
+await userEvent.keyboard('{/Shift}')
+```
+
+With Playwright:
+```ts
+await userEvent.click(element, { modifiers: ['Shift'] })
+```
+
+References:
- [Playwright `locator.click` API](https://playwright.dev/docs/api/class-locator#locator-click)
- [WebdriverIO `element.click` API](https://webdriver.io/docs/api/element/click/)
diff --git a/guide/browser/locators.md b/api/browser/locators.md
similarity index 95%
rename from guide/browser/locators.md
rename to api/browser/locators.md
index 57403e14..f9cf47ff 100644
--- a/guide/browser/locators.md
+++ b/api/browser/locators.md
@@ -1,5 +1,5 @@
---
-title: Locators | Browser Mode
+title: Locators | 浏览器模式
outline: [2, 3]
---
@@ -7,7 +7,7 @@ outline: [2, 3]
定位器是表示一个或多个元素的方式。每个定位器都由一个称为选择器的字符串定义。Vitest 通过提供方便的方法在后台生成这些选择器,从而抽象了选择器。
-定位器 API 使用了 [Playwright 的定位器](https://playwright.dev/docs/api/class-locator) 的一个分支,称为 [Ivya](https://npmjs.com/ivya)。然而,Vitest 将此 API 提供给每个 [provider](/guide/browser/config.html#browser-provider)。
+定位器 API 使用了 [Playwright 的定位器](https://playwright.dev/docs/api/class-locator) 的一个分支,称为 [Ivya](https://npmjs.com/ivya)。然而,Vitest 将此 API 提供给每个 [provider](/config/browser#browser-provider)。
::: tip
本页介绍了 API 的使用。为了更好地了解定位器及其用法,请阅读 [Playwright 的“定位器”文档](https://playwright.dev/docs/locators)。
@@ -368,7 +368,7 @@ page.getByTitle('Create') // ❌
function getByTestId(text: string | RegExp): Locator
```
-创建一个能够找到与指定测试 ID 属性匹配的元素的定位器。你可以通过 [`browser.locators.testIdAttribute`](/guide/browser/config#browser-locators-testidattribute) 配置属性名称。
+创建一个能够找到与指定测试 ID 属性匹配的元素的定位器。你可以通过 [`browser.locators.testIdAttribute`](/config/browser/locators#testidattribute) 配置属性名称。
```tsx
@@ -616,7 +616,7 @@ import { page } from 'vitest/browser'
await page.getByRole('img', { name: 'Rose' }).click()
```
-- [更多内容请参阅 `userEvent.click`](/guide/browser/interactivity-api#userevent-click)
+- [更多内容请参阅 `userEvent.click`](/api/browser/interactivity#userevent-click)
### dblClick
@@ -632,7 +632,7 @@ import { page } from 'vitest/browser'
await page.getByRole('img', { name: 'Rose' }).dblClick()
```
-- [更多内容请参阅 `userEvent.dblClick`](/guide/browser/interactivity-api#userevent-dblclick)
+- [更多内容请参阅 `userEvent.dblClick`](/api/browser/interactivity#userevent-dblclick)
### tripleClick
@@ -648,7 +648,7 @@ import { page } from 'vitest/browser'
await page.getByRole('img', { name: 'Rose' }).tripleClick()
```
-- [更多内容请参阅 `userEvent.tripleClick`](/guide/browser/interactivity-api#userevent-tripleclick)
+- [更多内容请参阅 `userEvent.tripleClick`](/api/browser/interactivity#userevent-tripleclick)
### clear
@@ -664,7 +664,7 @@ import { page } from 'vitest/browser'
await page.getByRole('textbox', { name: 'Full Name' }).clear()
```
-- [更多内容请参阅 `userEvent.clear`](/guide/browser/interactivity-api#userevent-clear)
+- [更多内容请参阅 `userEvent.clear`](/api/browser/interactivity#userevent-clear)
### hover
@@ -680,7 +680,7 @@ import { page } from 'vitest/browser'
await page.getByRole('img', { name: 'Rose' }).hover()
```
-- [更多内容请参阅 `userEvent.hover`](/guide/browser/interactivity-api#userevent-hover)
+- [更多内容请参阅 `userEvent.hover`](/api/browser/interactivity#userevent-hover)
### unhover
@@ -696,7 +696,7 @@ import { page } from 'vitest/browser'
await page.getByRole('img', { name: 'Rose' }).unhover()
```
-- [更多内容请参阅 `userEvent.unhover`](/guide/browser/interactivity-api#userevent-unhover)
+- [更多内容请参阅 `userEvent.unhover`](/api/browser/interactivity#userevent-unhover)
### fill
@@ -712,7 +712,7 @@ import { page } from 'vitest/browser'
await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean')
```
-- [更多内容请参阅 `userEvent.fill`](/guide/browser/interactivity-api#userevent-fill)
+- [更多内容请参阅 `userEvent.fill`](/api/browser/interactivity#userevent-fill)
### dropTo
@@ -734,7 +734,7 @@ const france = page.getByText('France')
await paris.dropTo(france)
```
-- [更多内容请参阅 `userEvent.dragAndDrop`](/guide/browser/interactivity-api#userevent-draganddrop)
+- [更多内容请参阅 `userEvent.dragAndDrop`](/api/browser/interactivity#userevent-draganddrop)
### selectOptions
@@ -766,7 +766,7 @@ await languages.selectOptions([
])
```
-- [更多内容请参阅 `userEvent.selectOptions`](/guide/browser/interactivity-api#userevent-selectoptions)
+- [更多内容请参阅 `userEvent.selectOptions`](/api/browser/interactivity#userevent-selectoptions)
### screenshot
@@ -781,10 +781,10 @@ function screenshot(options?: LocatorScreenshotOptions & { base64?: false }): Pr
创建与定位器选择器匹配的元素的屏幕截图。
-你可以使用 `path` 选项指定屏幕截图的保存位置,该选项相对于当前测试文件。如果未设置 `path` 选项,Vitest 将默认使用 [`browser.screenshotDirectory`](/guide/browser/config#browser-screenshotdirectory)(默认为 `__screenshot__`),并结合文件名和测试名来确定屏幕截图的文件路径。
+你可以使用 `path` 选项指定屏幕截图的保存位置,该选项相对于当前测试文件。如果未设置 `path` 选项,Vitest 将默认使用 [`browser.screenshotDirectory`](/config/browser/screenshotdirectory)(默认为 `__screenshot__`),并结合文件名和测试名来确定屏幕截图的文件路径。
如果你还需要屏幕截图的内容,可以指定 `base64: true` 以返回屏幕截图的 base64 编码内容以及保存路径。
-
+
```ts
import { page } from 'vitest/browser'
@@ -851,7 +851,7 @@ function element(): Element
如果 _多个元素_ 匹配该选择器,则会抛出错误。如果你需要所有匹配的 DOM 元素,可以使用 [`.elements()`](#elements);如果你需要匹配选择器的定位器数组,可以使用 [`.all()`](#all)。
::: tip
-此方法在需要将其传递给外部库时非常有用。当定位器与 `expect.element` 一起使用时,每次断言 [重试](/guide/browser/assertion-api) 时都会自动调用此方法:
+此方法在需要将其传递给外部库时非常有用。当定位器与 `expect.element` 一起使用时,每次断言 [重试](/api/browser/assertions) 时都会自动调用此方法:
```ts
await expect.element(page.getByRole('button')).toBeDisabled()
@@ -909,7 +909,7 @@ function elements(): Element[]
page.getByText('Hello World').elements() // ✅ [HTMLElement]
page.getByText('World').elements() // ✅ [HTMLElement]
page.getByText('Hello', { exact: true }).elements() // ✅ [HTMLElement]
-page.getByText('Hello').element() // ✅ [HTMLElement, HTMLElement]
+page.getByText('Hello').elements() // ✅ [HTMLElement, HTMLElement]
page.getByText('Hello USA').elements() // ✅ []
```
@@ -921,7 +921,7 @@ function all(): Locator[]
此方法返回一个与选择器匹配的新定位器数组。
-在内部,此方法调用 `.elements` 并使用 [`page.elementLocator`](/guide/browser/context#page) 包装每个元素。
+在内部,此方法调用 `.elements` 并使用 [`page.elementLocator`](/api/browser/context#page) 包装每个元素。
- [更多内容请参阅 `locator.elements()`](#elements)
diff --git a/api/expect-typeof.md b/api/expect-typeof.md
index 6f086611..5c0ddb93 100644
--- a/api/expect-typeof.md
+++ b/api/expect-typeof.md
@@ -75,7 +75,7 @@ const user = {
name: 'John',
address: { city: 'New York', zip: '10001' }
}
-expectTypeOf(user).toMatchObjectType<{ name: string, address: { city: string } }>()
+expectTypeOf(user).toMatchObjectType<{ name: string; address: { city: string } }>()
```
::: warning
@@ -91,9 +91,9 @@ expectTypeOf(user).toMatchObjectType<{ name: string, address: { city: string } }
```ts
import { expectTypeOf } from 'vitest'
-type ResponsiveProp = T | T[] | { xs?: T, sm?: T, md?: T }
+type ResponsiveProp = T | T[] | { xs?: T; sm?: T; md?: T }
-interface CSSProperties { margin?: string, padding?: string }
+interface CSSProperties { margin?: string; padding?: string }
function getResponsiveProp(_props: T): ResponsiveProp {
return {}
@@ -103,7 +103,7 @@ const cssProperties: CSSProperties = { margin: '1px', padding: '2px' }
expectTypeOf(getResponsiveProp(cssProperties))
.extract<{ xs?: any }>() // 从联合类型中提取最后一个类型
- .toEqualTypeOf<{ xs?: CSSProperties, sm?: CSSProperties, md?: CSSProperties }>()
+ .toEqualTypeOf<{ xs?: CSSProperties; sm?: CSSProperties; md?: CSSProperties }>()
expectTypeOf(getResponsiveProp(cssProperties))
.extract() // 从联合类型中提取数组
@@ -123,9 +123,9 @@ expectTypeOf(getResponsiveProp(cssProperties))
```ts
import { expectTypeOf } from 'vitest'
-type ResponsiveProp = T | T[] | { xs?: T, sm?: T, md?: T }
+type ResponsiveProp = T | T[] | { xs?: T; sm?: T; md?: T }
-interface CSSProperties { margin?: string, padding?: string }
+interface CSSProperties { margin?: string; padding?: string }
function getResponsiveProp(_props: T): ResponsiveProp {
return {}
diff --git a/api/expect.md b/api/expect.md
index 708dcf1e..57a145ed 100644
--- a/api/expect.md
+++ b/api/expect.md
@@ -105,7 +105,7 @@ test('expect.soft test', () => {
```ts
interface ExpectPoll extends ExpectStatic {
- (actual: () => T, options?: { interval?: number, timeout?: number, message?: string }): Promise>
+ (actual: () => T, options?: { interval?: number; timeout?: number; message?: string }): Promise>
}
```
@@ -189,7 +189,8 @@ test('stocks are the same', () => {
- **类型:** `(value: number, numDigits?: number) => Awaitable`
-使用 `toBeCloseTo` 比较浮点数。可选的 `numDigits` 参数限制了小数点后要检查的位数。例如:
+
+Use `toBeCloseTo` to compare floating-point numbers. The optional `numDigits` argument limits the number of digits to check _after_ the decimal point. The default for `numDigits` is 2. For example:
```ts
import { expect, test } from 'vitest'
@@ -344,7 +345,7 @@ function apples() {
}
function bananas() {
- return null
+ return undefined
}
test('we don\'t have apples', () => {
@@ -379,10 +380,14 @@ test('getApplesCount has some unusual side effects...', () => {
```
## toBeOneOf
+
+- **Type:** `(sample: Array | Set) => any`
-- **类型:** `(sample: Array) => any`
+`toBeOneOf` asserts if a value matches any of the values in the provided array or set.
-`toBeOneOf` 断言某个值是否与所提供数组中的任何值匹配。
+::: warning EXPERIMENTAL
+Providing a `Set` is an experimental feature and may change in a future release.
+:::
```ts
import { expect, test } from 'vitest'
@@ -430,6 +435,17 @@ test('stock is type of string', () => {
})
```
+:::warning
+`toBeTypeOf` uses the native `typeof` operator under the hood with all its quirks, most notably that the value `null` has type `object`.
+
+```ts
+test('toBeTypeOf cannot check for null or array', () => {
+ expect(null).toBeTypeOf('object')
+ expect([]).toBeTypeOf('object')
+})
+```
+:::
+
## toBeInstanceOf
- **类型:** `(c: any) => Awaitable`
@@ -588,7 +604,13 @@ import { getAllFruits } from './stocks.js'
test('the fruit list contains orange', () => {
expect(getAllFruits()).toContain('orange')
+})
+
+test('pineapple contains apple', () => {
+ expect('pineapple').toContain('apple')
+})
+test('the element contains a class and is contained', () => {
const element = document.querySelector('#el')
// element 有 class 属性 flex
expect(element.classList).toContain('flex')
@@ -684,6 +706,9 @@ test('John Doe Invoice', () => {
// 将键名包裹在数组中,避免其被解析为深层引用
expect(invoice).toHaveProperty(['P.O'], '12345')
+
+ // Deep equality of object property
+ expect(invoice).toHaveProperty('items[0]', { type: 'apples', quantity: 10 })
})
```
@@ -1209,6 +1234,8 @@ test('spy function returns bananas on a last call', () => {
我们可以调用这个断言来检查函数是否在特定的调用中成功返回了带有特定参数的值。需要将一个 spy 函数传递给 `expect`。
+The count starts at 1. So, to check the second entry, you would write `.toHaveNthReturnedWith(2, ...)`.
+
```ts
import { expect, test, vi } from 'vitest'
@@ -1318,6 +1345,8 @@ test('spy function resolves bananas on a last call', async () => {
如果函数返回了一个 promise,但尚未 resolved,则将会失败。
+The count starts at 1. So, to check the second entry, you would write `.toHaveNthResolvedWith(2, ...)`.
+
```ts
import { expect, test, vi } from 'vitest'
@@ -1682,6 +1711,42 @@ test('variety ends with "re"', () => {
可以将 `expect.not` 与此匹配器一起使用,以否定预期值。
:::
+## expect.schemaMatching
+
+- **Type:** `(expected: StandardSchemaV1) => any`
+
+When used with an equality check, this asymmetric matcher will return `true` if the value matches the provided schema. The schema must implement the [Standard Schema v1](https://standardschema.dev/) specification.
+
+```ts
+import { expect, test } from 'vitest'
+import { z } from 'zod'
+import * as v from 'valibot'
+import { type } from 'arktype'
+
+test('email validation', () => {
+ const user = { email: 'john@example.com' }
+
+ // using Zod
+ expect(user).toEqual({
+ email: expect.schemaMatching(z.string().email()),
+ })
+
+ // using Valibot
+ expect(user).toEqual({
+ email: expect.schemaMatching(v.pipe(v.string(), v.email()))
+ })
+
+ // using ArkType
+ expect(user).toEqual({
+ email: expect.schemaMatching(type('string.email')),
+ })
+})
+```
+
+:::tip
+You can use `expect.not` with this matcher to negate the expected value.
+:::
+
## expect.addSnapshotSerializer
- **类型:** `(plugin: PrettyFormatPlugin) => void`
diff --git a/api/index.md b/api/index.md
index d655db68..0431e9c0 100644
--- a/api/index.md
+++ b/api/index.md
@@ -427,8 +427,27 @@ test.each([
expect(a + b).toBe(expected)
})
```
+
+You can also access Object attributes with `.`, if you are using objects as arguments:
+
+ ```ts
+ test.each`
+ a | b | expected
+ ${{ val: 1 }} | ${'b'} | ${'1b'}
+ ${{ val: 2 }} | ${'b'} | ${'2b'}
+ ${{ val: 3 }} | ${'b'} | ${'3b'}
+ `('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
+ expect(a.val + b).toBe(expected)
+ })
+
+ // this will return
+ // ✓ add(1, b) -> 1b
+ // ✓ add(2, b) -> 2b
+ // ✓ add(3, b) -> 3b
+ ```
-如果使用对象作为参数,也可以使用 `.` 访问对象属性:
+* First row should be column names, separated by `|`;
+* One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
```ts
import { expect, test } from 'vitest'
@@ -1084,8 +1103,6 @@ describe.each([
})
```
-从 Vitest 0.25.3 开始,还可以使用模板字符串表。
-
- 第一行应为列名,用 `|` 分隔;
- 使用 `${value}` 语法,以模板字面表达式的形式提供后面一行或多行数据。
@@ -1204,8 +1221,9 @@ afterEach(async () => {
在这里,`afterEach` 可确保在每次测试运行后清除测试数据。
+
::: tip
-Vitest 在 1.3.0 新增 [`onTestFinished`](#ontestfinished)。你可以在测试执行过程中调用它,以便在测试运行结束后清理任何状态。
+You can also use [`onTestFinished`](#ontestfinished) during the test execution to cleanup any state after the test has finished running.
:::
### beforeAll
diff --git a/api/mock.md b/api/mock.md
index 5cbc5677..917ca626 100644
--- a/api/mock.md
+++ b/api/mock.md
@@ -20,6 +20,32 @@ getApplesSpy.mock.calls.length === 1
要验证 mock 的行为,请通过 [`expect`](/api/expect) 调用类似 [`toHaveBeenCalled`](/api/expect#tohavebeencalled) 的断言方法;以下 API 参考汇总了所有可用来操控 mock 的属性和方法。
+::: warning IMPORTANT
+Vitest spies inherit implementation's [`length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length) property when initialized, but it doesn't override it if the implementation was changed later:
+
+::: code-group
+```ts [vi.fn]
+const fn = vi.fn((arg1) => {})
+fn.length // == 1
+
+fn.mockImplementation(() => {})
+fn.length // == 1
+```
+```ts [vi.spyOn]
+const example = {
+ fn(arg1, arg2) {
+ // ...
+ }
+}
+
+const fn = vi.spyOn(example, 'fn')
+fn.length // == 2
+
+fn.mockImplementation(() => {})
+fn.length // == 2
+```
+:::
+
::: tip
以下类型中的自定义函数实现使用泛型 `` 进行标记。
:::
diff --git a/api/vi.md b/api/vi.md
index 7cb7772a..5797da1b 100644
--- a/api/vi.md
+++ b/api/vi.md
@@ -231,7 +231,7 @@ function mocked(
): MaybeMockedDeep
function mocked(
object: T,
- options?: { partial?: boolean, deep?: boolean }
+ options?: { partial?: boolean; deep?: boolean }
): MaybePartiallyMockedDeep
```
@@ -449,7 +449,7 @@ expect(Cart).toHaveBeenCalled()
### vi.mockObject 3.2.0
```ts
-function mockObject(value: T): MaybeMockedDeep
+function mockObject(value: T, options?: MockOptions): MaybeMockedDeep
```
它与 `vi.mock()` 模拟模块相同,深层模拟给定对象的属性和方法。详见 [自动模拟](/guide/mocking.html#automocking-algorithm)。
@@ -854,7 +854,7 @@ await vi.advanceTimersToNextTimerAsync() // log: 3
function advanceTimersToNextFrame(): Vitest
```
-与 [`vi.advanceTimersByTime`](https://vitest.dev/api/vi#vi-advancetimersbytime) 类似,但会将计时器推进当前使用 `requestAnimationFrame` 安排的回调执行所需的毫秒数。
+与 [`vi.advanceTimersByTime`](/api/vi#vi-advancetimersbytime) 类似,但会将计时器推进当前使用 `requestAnimationFrame` 安排的回调执行所需的毫秒数。
```ts
let frameRendered = false
diff --git a/blog/vitest-3-2.md b/blog/vitest-3-2.md
index 7c8130c1..5fab10d8 100644
--- a/blog/vitest-3-2.md
+++ b/blog/vitest-3-2.md
@@ -10,7 +10,7 @@ head:
content: website
- - meta
- property: og:title
- content: Vitest 3.2 发布了
+ content: Vitest 3.2 发布了!
- - meta
- property: og:image
content: https://cn.vitest.dev/og-vitest-3-2.png
@@ -110,7 +110,7 @@ export default defineConfig({
## 自定义浏览器定位器 API {#custom-browser-locators-api}
-当内置定位器无法满足应用需求时。与其降级使用 CSS 选择器,并牺牲 Vitest 定位器 API 提供的重试保护机制,不如推荐你使用 [`locators.extend` API](/guide/browser/locators#custom-locators) 扩展定位器。
+当内置定位器无法满足应用需求时。与其降级使用 CSS 选择器,并牺牲 Vitest 定位器 API 提供的重试保护机制,不如推荐你使用 [`locators.extend` API](/api/browser/locators#custom-locators) 扩展定位器。
```ts
import { locators } from '@vitest/browser/context'
@@ -172,7 +172,7 @@ locators.extend({
await page.getByRole('textbox').clickAndFill('Hello World')
```
-请参阅 [`locators.extend` API](/guide/browser/locators#custom-locators) 获取更多信息。
+请参阅 [`locators.extend` API](/api/browser/locators#custom-locators) 获取更多信息。
## `vi.spyOn` 和 `vi.fn` 中的显式资源管理 {#explicit-resource-management-in-vi-spyon-and-vi-fn}
diff --git a/blog/vitest-3.md b/blog/vitest-3.md
index 2d2c355d..23ffb556 100644
--- a/blog/vitest-3.md
+++ b/blog/vitest-3.md
@@ -62,7 +62,7 @@ _2025 年 1 月 17 日_
-伴随此更改,我们还重新设计了公共报告器 API(reporters 字段),使[生命周期](/advanced/api/reporters)更容易理解。
+伴随此更改,我们还重新设计了公共报告器 API(reporters 字段),使[生命周期](/api/advanced/reporters)更容易理解。
你可以在 [#7069](https://github.com/vitest-dev/vitest/pull/7069) PR 中关注设计过程。为了逆向工程之前的 onTaskUpdate API 并实现这个新的优雅生命周期,我们经历了一番艰难的努力。
@@ -115,7 +115,7 @@ export default defineConfig({
实例相对于工作区的主要优势在于更好的缓存策略 - Vitest 只创建一个 Vite 服务器来服务文件,这些文件只会被处理一次,而与你测试的浏览器数量无关。
-此版本还改进了浏览器模式特性的文档,并引入了针对 [Playwright](/guide/browser/playwright) 和 [WebdriverIO](/guide/browser/webdriverio) 的单独指南,希望能使配置更容易。
+此版本还改进了浏览器模式特性的文档,并引入了针对 [Playwright](/config/browser/playwright) 和 [WebdriverIO](/config/browser/webdriverio) 的单独指南,希望能使配置更容易。
## 按需过滤 {#filtering-by-location}
diff --git a/blog/vitest-4.md b/blog/vitest-4.md
new file mode 100644
index 00000000..53c82784
--- /dev/null
+++ b/blog/vitest-4.md
@@ -0,0 +1,338 @@
+---
+title: Vitest 4.0 is out!
+author:
+ name: The Vitest Team
+date: 2025-10-22
+sidebar: false
+head:
+ - - meta
+ - property: og:type
+ content: website
+ - - meta
+ - property: og:title
+ content: Vitest 4.0 发布了!
+ - - meta
+ - property: og:image
+ content: https://vitest.dev/og-vitest-4.jpg
+ - - meta
+ - property: og:url
+ content: https://vitest.dev/blog/vitest-4
+ - - meta
+ - property: og:description
+ content: Vitest 4.0 Release Announcement
+ - - meta
+ - name: twitter:card
+ content: summary_large_image
+---
+
+# Vitest 4.0 is out!
+
+_October 22, 2025_
+
+
+
+## The next Vitest major is here
+
+Today, we are thrilled to announce Vitest 4!
+
+Quick links:
+
+- [Docs](/)
+- Translations: [简体中文](https://cn.vitest.dev/)
+- [Migration Guide](/guide/migration#vitest-4)
+- [GitHub Changelog](https://github.com/vitest-dev/vitest/releases/tag/v4.0.0)
+
+If you've not used Vitest before, we suggest reading the [Getting Started](/guide/) and [Features](/guide/features) guides first.
+
+We extend our gratitude to the over [640 contributors to Vitest Core](https://github.com/vitest-dev/vitest/graphs/contributors) and to the maintainers and contributors of Vitest integrations, tools, and translations who have helped us develop this new major release. We encourage you to get involved and help us improve Vitest for the entire ecosystem. Learn more at our [Contributing Guide](https://github.com/vitest-dev/vitest/blob/main/CONTRIBUTING.md).
+
+To get started, we suggest helping [triage issues](https://github.com/vitest-dev/vitest/issues), [review PRs](https://github.com/vitest-dev/vitest/pulls), send failing tests PRs based on open issues, and support others in [Discussions](https://github.com/vitest-dev/vitest/discussions) and Vitest Land's [help forum](https://discord.com/channels/917386801235247114/1057959614160851024). If you'd like to talk to us, join our [Discord community](http://chat.vitest.dev/) and say hi on the [#contributing channel](https://discord.com/channels/917386801235247114/1057959614160851024).
+
+For the latest news about the Vitest ecosystem and Vitest core, follow us on [Bluesky](https://bsky.app/profile/vitest.dev) or [Mastodon](https://webtoo.ls/@vitest).
+
+To stay updated, keep an eye on the [VoidZero blog](https://voidzero.dev/blog) and subscribe to the [newsletter](https://voidzero.dev/newsletter).
+
+## Browser Mode is Stable
+
+With this release we are removing the `experimental` tag from [Browser Mode](/guide/browser/). To make it possible, we had to introduce some changes to the public API.
+
+To define a provider, you now need to install a separate package: [`@vitest/browser-playwright`](https://www.npmjs.com/package/@vitest/browser-playwright), [`@vitest/browser-webdriverio`](https://www.npmjs.com/package/@vitest/browser-webdriverio), or [`@vitest/browser-preview`](https://www.npmjs.com/package/@vitest/browser-preview). This makes it simpler to work with custom options and doesn't require adding `/// // [!code --]
+
+export default defineConfig({
+ test: {
+ browser: {
+ provider: 'playwright', // [!code --]
+ provider: playwright({ // [!code ++]
+ launchOptions: { // [!code ++]
+ slowMo: 100, // [!code ++]
+ }, // [!code ++]
+ }), // [!code ++]
+ instances: [
+ {
+ browser: 'chromium',
+ launch: { // [!code --]
+ slowMo: 100, // [!code --]
+ }, // [!code --]
+ },
+ ],
+ },
+ },
+})
+```
+```ts [webdriverio]
+import { defineConfig } from 'vitest/config'
+import { webdriverio } from '@vitest/browser-webdriverio' // [!code ++]
+/// // [!code --]
+
+export default defineConfig({
+ test: {
+ browser: {
+ provider: 'webdriverio', // [!code --]
+ provider: webdriverio({ // [!code ++]
+ capabilities: { // [!code ++]
+ browserVersion: '82', // [!code ++]
+ }, // [!code ++]
+ }),
+ instances: [
+ {
+ browser: 'chrome',
+ capabilities: { // [!code --]
+ browserVersion: '82', // [!code --]
+ }, // [!code --]
+ },
+ ],
+ },
+ },
+})
+```
+```ts [preview]
+import { defineConfig } from 'vitest/config'
+import { preview } from '@vitest/browser-preview' // [!code ++]
+
+export default defineConfig({
+ test: {
+ browser: {
+ provider: 'preview', // [!code --]
+ provider: preview(), // [!code ++]
+ instances: [
+ { browser: 'chrome' },
+ ],
+ },
+ },
+})
+```
+:::
+
+The context is no longer imported from `@vitest/browser/context` (but it will keep working until the next major version for better compatibility with tools that did not update yet), now just import from `vitest/browser`:
+
+```ts
+import { page } from '@vitest/browser/context' // [!code --]
+import { page } from 'vitest/browser' // [!code ++]
+
+test('example', async () => {
+ await page.getByRole('button').click()
+})
+```
+
+With these changes, the `@vitest/browser` package can be removed from your dependencies. It is now included in every provider package automatically.
+
+## Visual Regression Testing
+
+Vitest 4 adds support for [Visual Regression testing](/guide/browser/visual-regression-testing) in Browser Mode. We will continue to iterate on this feature to improve the experience.
+
+Visual regression testing in Vitest can be done through the
+[`toMatchScreenshot` assertion](/api/browser/assertions.html#tomatchscreenshot):
+
+```ts
+import { expect, test } from 'vitest'
+import { page } from 'vitest/browser'
+
+test('hero section looks correct', async () => {
+ // ...the rest of the test
+
+ // capture and compare screenshot
+ await expect(page.getByTestId('hero')).toMatchScreenshot('hero-section')
+})
+```
+
+Vitest captures screenshots of your UI components and pages, then compares them against reference images to detect unintended visual changes.
+
+Alongside this feature, Vitest also introduces a `toBeInViewport` matcher. It allows you to check if an element is currently in viewport with [IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).
+
+```ts
+// A specific element is in viewport.
+await expect.element(page.getByText('Welcome')).toBeInViewport()
+
+// 50% of a specific element should be in viewport
+await expect.element(page.getByText('To')).toBeInViewport({ ratio: 0.5 })
+```
+
+## Playwright Traces Support
+
+Vitest 4 supports generating [Playwright Traces](/guide/browser/trace-view). To enable tracing, you need to set the [`trace`](/config/browser/trace) option in the `test.browser` configuration or pass down `--browser.trace=on` option (`off`, `on-first-retry`, `on-all-retries`, `retain-on-failure` are also available).
+
+
+
+The traces are available in reporters as [annotations](/guide/test-annotations). For example, in the HTML reporter, you can find the link to the trace file in the test details. To open the trace file, you can use the [Playwright Trace Viewer](https://playwright.dev/docs/trace-viewer).
+
+## Locator Improvements
+
+The `frameLocator` method returns a `FrameLocator` instance that can be used to find elements inside the iframe.
+Vitest now supports a new [`page.frameLocator`](/api/browser/context#framelocator) API (only with `playwright` provider).
+
+```ts
+const frame = page.frameLocator(
+ page.getByTestId('iframe')
+)
+
+await frame.getByText('Hello World').click() // ✅
+await frame.click() // ❌ Not available
+```
+
+Every locator now exposes a `length` property, allowing them to be used with `toHaveLength` matcher automatically:
+
+```ts
+await expect.element(page.getByText('Item')).toHaveLength(3)
+```
+
+## Improved Debugging
+
+The [vscode extension](https://vitest.dev/vscode) now supports "Debug Test" button when running browser tests.
+
+If you prefer configuring the debug options yourself, you can start Vitest with the `--inspect` flag (available with `playwright` and `webdriverio`) and connect to [DevTools](chrome://inspect/) manually. In this case Vitest will also disable the new [`trackUnhandledErrors`](/config/browser/trackunhandlederrors) option automatically.
+
+## Type-Aware Hooks
+
+When using `test.extend` with lifecycle hooks like `beforeEach` and `afterEach`, you can now reference them directly on the returned `test` object:
+
+```ts
+import { test as baseTest } from 'vitest'
+
+const test = baseTest.extend<{
+ todos: number[]
+}>({
+ todos: async ({}, use) => {
+ await use([])
+ },
+})
+
+// Unlike global hooks, these hooks are aware of the extended context
+test.beforeEach(({ todos }) => {
+ todos.push(1)
+})
+
+test.afterEach(({ todos }) => {
+ console.log(todos)
+})
+```
+
+## `expect.assert`
+
+Vitest has always exported [Chai's `assert`](https://www.chaijs.com/api/assert/), but sometimes using it was inconvenient because many modules have the same export.
+
+Now Vitest exposes the same method on `expect` for an easy access. This is especially useful if you need to narrow down the type, since `expect.to*` methods do not support that:
+
+```ts
+interface Cat {
+ __type: 'Cat'
+ mew(): void
+}
+interface Dog {
+ __type: 'Dog'
+ bark(): void
+}
+type Animal = Cat | Dog
+
+const animal: Animal = { __type: 'Dog', bark: () => {} }
+
+expect.assert(animal.__type === 'Dog')
+// does not show a type error!
+expect(animal.bark()).toBeUndefined()
+```
+
+## `expect.schemaMatching`
+
+Vitest 4 introduces a new asymmetric matcher called `expect.schemaMatching`. It accepts a [Standard Schema v1](https://standardschema.dev/) object and validates values against it, passing the assertion when the value conforms to the schema.
+
+As a reminder, asymmetric matchers can be used in all `expect` matchers that check equality, including `toEqual`, `toStrictEqual`, `toMatchObject`, `toContainEqual`, `toThrowError`, `toHaveBeenCalledWith`, `toHaveReturnedWith` and `toHaveBeenResolvedWith`.
+
+```ts
+import { expect, test } from 'vitest'
+import { z } from 'zod'
+import * as v from 'valibot'
+import { type } from 'arktype'
+
+test('email validation', () => {
+ const user = { email: 'john@example.com' }
+
+ // using Zod
+ expect(user).toEqual({
+ email: expect.schemaMatching(z.string().email()),
+ })
+
+ // using Valibot
+ expect(user).toEqual({
+ email: expect.schemaMatching(v.pipe(v.string(), v.email()))
+ })
+
+ // using ArkType
+ expect(user).toEqual({
+ email: expect.schemaMatching(type('string.email')),
+ })
+})
+```
+
+## Reporter Updates
+
+The `basic` reporter was removed. You can use the `default` reporter with `summary: false` instead:
+
+```ts
+export default defineConfig({
+ test: {
+ reporters: [
+ ['default', { summary: false }],
+ ],
+ },
+})
+```
+
+The [`default`](/guide/reporters#default-reporter) reporter now only prints tests in a tree if there is only one test file running. If you want to always see tests printed as a tree, you can use a new [`tree`](/guide/reporters#tree-reporter) reporter.
+
+The [`verbose`](/guide/reporters#verbose-reporter) reporter now always prints tests one by one when they are finished. Previously, this was done only in CI, and locally `verbose` would behave mostly like a `default` reporter. If you prefer to keep the old behaviour, you can conditionally use the `verbose` reporter only in CI by updating the config:
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ reporter: process.env.CI ? 'verbose' : 'default',
+ },
+})
+```
+
+## New API Methods
+
+Vitest 4 comes with new advanced public [API methods](/api/advanced/vitest):
+
+- [`experimental_parseSpecifications`](/api/advanced/vitest#parsespecification) allows you to parse a test file without running it.
+- [`watcher`](/api/advanced/vitest#watcher) exposes methods that can be used when you disable the default Vitest watcher.
+- [`enableCoverage`](/api/advanced/vitest#enablecoverage) and [`disableCoverage`](/api/advanced/vitest#disablecoverage) allow you to enable and disable coverage dynamically.
+- [`getSeed`](/api/advanced/vitest#enablecoverage) returns the seed value, if tests run at random.
+- [`getGlobalTestNamePattern`](/api/advanced/vitest#getglobaltestnamepattern) returns the current test name pattern.
+- [`waitForTestRunEnd`](/api/advanced/vitest#waitfortestrunend) returns a promise that resolves when all tests have finished running.
+
+## Breaking changes
+
+Vitest 4 has a few breaking changes that could affect you, so we advise reviewing the detailed [Migration Guide](/guide/migration#vitest-4) before upgrading.
+
+The complete list of changes is at the [Vitest 4 Changelog](https://github.com/vitest-dev/vitest/releases/tag/v4.0.0).
+
+## Acknowledgments
+
+Vitest 4 is the result of countless hours by the [Vitest team](/team) and our contributors. We appreciate the individuals and companies sponsoring Vitest development. [Vladimir](https://github.com/sheremet-va) and [Hiroshi](https://github.com/hi-ogawa) are part of the [VoidZero](https://voidzero.dev) Team and are able to work on Vite and Vitest full-time, and [Ari](https://github.com/ariperkkio) can invest more time in Vitest thanks to [StackBlitz](https://stackblitz.com/). A shout-out to [NuxtLabs](https://nuxtlabs.com), [Zammad](https://zammad.com), and sponsors on [Vitest's GitHub Sponsors](https://github.com/sponsors/vitest-dev) and [Vitest's Open Collective](https://opencollective.com/vitest).
diff --git a/config/alias.md b/config/alias.md
new file mode 100644
index 00000000..97ff2fa6
--- /dev/null
+++ b/config/alias.md
@@ -0,0 +1,18 @@
+---
+title: alias | Config
+outline: deep
+---
+
+# alias
+
+- **Type:** `Record | Array<{ find: string | RegExp, replacement: string, customResolver?: ResolverFunction | ResolverObject }>`
+
+Define custom aliases when running inside tests. They will be merged with aliases from `resolve.alias`.
+
+::: warning
+Vitest uses Vite SSR primitives to run tests which has [certain pitfalls](https://vitejs.dev/guide/ssr.html#ssr-externals).
+
+1. Aliases affect only modules imported directly with an `import` keyword by an [inlined](#server-deps-inline) module (all source code is inlined by default).
+2. Vitest does not support aliasing `require` calls.
+3. If you are aliasing an external dependency (e.g., `react` -> `preact`), you may want to alias the actual `node_modules` packages instead to make it work for externalized dependencies. Both [Yarn](https://classic.yarnpkg.com/en/docs/cli/add/#toc-yarn-add-alias) and [pnpm](https://pnpm.io/aliases/) support aliasing via the `npm:` prefix.
+:::
diff --git a/config/allowonly.md b/config/allowonly.md
new file mode 100644
index 00000000..e6071032
--- /dev/null
+++ b/config/allowonly.md
@@ -0,0 +1,37 @@
+---
+title: allowOnly | Config
+outline: deep
+---
+
+# allowOnly
+
+- **Type**: `boolean`
+- **Default**: `!process.env.CI`
+- **CLI:** `--allowOnly`, `--allowOnly=false`
+
+By default, Vitest does not permit tests marked with the [`only`](/api/#test-only) flag in Continuous Integration (CI) environments. Conversely, in local development environments, Vitest allows these tests to run.
+
+::: info
+Vitest uses [`std-env`](https://www.npmjs.com/package/std-env) package to detect the environment.
+:::
+
+You can customize this behavior by explicitly setting the `allowOnly` option to either `true` or `false`.
+
+::: code-group
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ allowOnly: true,
+ },
+})
+```
+```bash [CLI]
+vitest --allowOnly
+```
+:::
+
+When enabled, Vitest will not fail the test suite if tests marked with [`only`](/api/#test-only) are detected, including in CI environments.
+
+When disabled, Vitest will fail the test suite if tests marked with [`only`](/api/#test-only) are detected, including in local development environments.
diff --git a/config/api.md b/config/api.md
new file mode 100644
index 00000000..2bb16ecf
--- /dev/null
+++ b/config/api.md
@@ -0,0 +1,12 @@
+---
+title: api | Config
+outline: deep
+---
+
+# api
+
+- **Type:** `boolean | number`
+- **Default:** `false`
+- **CLI:** `--api`, `--api.port`, `--api.host`, `--api.strictPort`
+
+Listen to port and serve API for [the UI](/guide/ui) or [browser server](/guide/browser/). When set to `true`, the default port is `51204`.
diff --git a/config/attachmentsdir.md b/config/attachmentsdir.md
new file mode 100644
index 00000000..993fa9f8
--- /dev/null
+++ b/config/attachmentsdir.md
@@ -0,0 +1,11 @@
+---
+title: attachmentsDir | Config
+outline: deep
+---
+
+# attachmentsDir
+
+- **Type:** `string`
+- **Default:** `'.vitest-attachments'`
+
+Directory path for storing attachments created by [`context.annotate`](/guide/test-context#annotate) relative to the project root.
diff --git a/config/bail.md b/config/bail.md
new file mode 100644
index 00000000..27018e56
--- /dev/null
+++ b/config/bail.md
@@ -0,0 +1,14 @@
+---
+title: bail | Config
+outline: deep
+---
+
+# bail
+
+- **Type:** `number`
+- **Default:** `0`
+- **CLI**: `--bail=`
+
+Stop test execution when given number of tests have failed.
+
+By default Vitest will run all of your test cases even if some of them fail. This may not be desired for CI builds where you are only interested in 100% successful builds and would like to stop test execution as early as possible when test failures occur. The `bail` option can be used to speed up CI runs by preventing it from running more tests when failures have occurred.
diff --git a/config/benchmark.md b/config/benchmark.md
new file mode 100644
index 00000000..ad9dea62
--- /dev/null
+++ b/config/benchmark.md
@@ -0,0 +1,70 @@
+---
+title: benchmark | Config
+outline: deep
+---
+
+# benchmark {#benchmark}
+
+- **Type:** `{ include?, exclude?, ... }`
+
+Options used when running `vitest bench`.
+
+## benchmark.include
+
+- **Type:** `string[]`
+- **Default:** `['**/*.{bench,benchmark}.?(c|m)[jt]s?(x)']`
+
+Include globs for benchmark test files
+
+## benchmark.exclude
+
+- **Type:** `string[]`
+- **Default:** `['node_modules', 'dist', '.idea', '.git', '.cache']`
+
+Exclude globs for benchmark test files
+
+## benchmark.includeSource
+
+- **Type:** `string[]`
+- **Default:** `[]`
+
+Include globs for in-source benchmark test files. This option is similar to [`includeSource`](#includesource).
+
+When defined, Vitest will run all matched files with `import.meta.vitest` inside.
+
+## benchmark.reporters
+
+- **Type:** `Arrayable`
+- **Default:** `'default'`
+
+Custom reporter for output. Can contain one or more built-in report names, reporter instances, and/or paths to custom reporters.
+
+## benchmark.outputFile
+
+Deprecated in favor of `benchmark.outputJson`.
+
+## benchmark.outputJson {#benchmark-outputJson}
+
+- **Type:** `string | undefined`
+- **Default:** `undefined`
+
+A file path to store the benchmark result, which can be used for `--compare` option later.
+
+For example:
+
+```sh
+# save main branch's result
+git checkout main
+vitest bench --outputJson main.json
+
+# change a branch and compare against main
+git checkout feature
+vitest bench --compare main.json
+```
+
+## benchmark.compare {#benchmark-compare}
+
+- **Type:** `string | undefined`
+- **Default:** `undefined`
+
+A file path to a previous benchmark result to compare against current runs.
diff --git a/guide/browser/config.md b/config/browser.md
similarity index 75%
rename from guide/browser/config.md
rename to config/browser.md
index 8cfaec21..dd56ae03 100644
--- a/guide/browser/config.md
+++ b/config/browser.md
@@ -1,3 +1,8 @@
+
+---
+title: Browser Config Reference | Config
+outline: deep
+---
# 浏览器配置参考 {#browser-config-reference}
我们可以通过更新 [配置文件](/config/) 中的 `test.browser` 字段来更改浏览器配置。一个简单的配置文件示例如下:
@@ -51,7 +56,8 @@ export default defineConfig({
定义多个浏览器设置。每个配置必须至少有一个 `browser` 字段。
-你可以指定大部分[项目选项](/config/)(未标记图标的选项)和一些 `browser` 选项,如`browser.testerHtmlPath`。
+
+You can specify most of the [project options](/config/) (not marked with a icon) and some of the `browser` options like `browser.testerHtmlPath`.
::: warning
每个浏览器配置都从根配置继承选项:
@@ -89,7 +95,7 @@ export default defineConfig({
- [`browser.screenshotFailures`](#browser-screenshotfailures)
- [`browser.provider`](#browser-provider)
-在底层,Vitest 将这些实例转换为共享单个 Vite 服务器的单独[测试项目](/advanced/api/test-project),以获得更好的缓存性能。
+在底层,Vitest 将这些实例转换为共享单个 Vite 服务器的单独[测试项目](/api/advanced/test-project),以获得更好的缓存性能。
## browser.headless
@@ -99,14 +105,19 @@ export default defineConfig({
在 `headless` 模式下运行浏览器。如果我们在 CI 中运行 Vitest,则默认启用此模式。
-## browser.isolate
+
+## browser.isolate
- **类型:** `boolean`
-- **默认值:** `true`
+- **Default:** the same as [`--isolate`](/config/#isolate)
- **CLI:** `--browser.isolate`, `--browser.isolate=false`
在单独的 iframe 中运行每个测试。
+::: danger DEPRECATED
+This option is deprecated. Use [`isolate`](/config/#isolate) instead.
+:::
+
## browser.testerHtmlPath
- **类型:** `string`
@@ -191,6 +202,7 @@ export default defineConfig({
export interface BrowserProvider {
name: string
mocker?: BrowserModuleMocker
+ readonly initScripts?: string[]
/**
* @experimental 选择进入文件并行化
*/
@@ -219,7 +231,7 @@ export interface BrowserProvider {
## browser.locators
-内置 [浏览器定位器](/guide/browser/locators) 的选项。
+内置 [浏览器定位器](/api/browser/locators) 的选项。
### browser.locators.testIdAttribute
@@ -287,7 +299,7 @@ export interface BrowserScript {
- **类型:** `Record`
- **默认值:** `{ readFile, writeFile, ... }`
-可以在浏览器测试中从 `vitest/browser` 导入的自定义[命令](/guide/browser/commands)。
+可以在浏览器测试中从 `vitest/browser` 导入的自定义 [命令](/api/browser/commands)。
## browser.connectTimeout
@@ -341,7 +353,7 @@ interface TraceOptions {
```
::: danger WARNING
-只有 [**playwright**](/guide/browser/playwright) 提供者支持该选项。
+只有 [**playwright**](/config/browser/playwright) 提供者支持该选项。
:::
## browser.trackUnhandledErrors
@@ -361,7 +373,7 @@ interface TraceOptions {
### browser.expect.toMatchScreenshot
-[`toMatchScreenshot`](/guide/browser/assertion-api.html#tomatchscreenshot) 断言的默认选项。
+[`toMatchScreenshot`](/api/browser/assertions.html#tomatchscreenshot) 断言的默认选项。
这些选项将应用于所有截图断言。
::: tip
@@ -391,7 +403,7 @@ export default defineConfig({
})
```
-`toMatchScreenshot` 断言中可用的 [所有选项](/guide/browser/assertion-api#options) 均可在此配置。此外,还提供了两个路径解析函数:`resolveScreenshotPath` 和 `resolveDiffPath`。
+`toMatchScreenshot` 断言中可用的 [所有选项](/api/browser/assertions#options) 均可在此配置。此外,还提供了两个路径解析函数:`resolveScreenshotPath` 和 `resolveDiffPath`。
#### browser.expect.toMatchScreenshot.resolveScreenshotPath
@@ -434,7 +446,7 @@ export default defineConfig({
- `screenshotDirectory: string`
- 如果未提供值,则为 [`browser.screenshotDirectory`](/guide/browser/config#browser-screenshotdirectory)。
+ 如果未提供值,则为 [`browser.screenshotDirectory`](/config/browser/screenshotdirectory)。
- `root: string`
@@ -476,3 +488,116 @@ resolveScreenshotPath: ({ arg, browserName, ext, root, testFileName }) =>
resolveDiffPath: ({ arg, attachmentsDir, browserName, ext, root, testFileName }) =>
`${root}/${attachmentsDir}/screenshot-diffs/${testFileName}/${arg}-${browserName}${ext}`
```
+
+#### browser.expect.toMatchScreenshot.comparators
+
+- **Type:** `Record`
+
+Register custom screenshot comparison algorithms, like [SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure) or other perceptual similarity metrics.
+
+To create a custom comparator, you need to register it in your config. If using TypeScript, declare its options in the `ScreenshotComparatorRegistry` interface.
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+// 1. Declare the comparator's options type
+declare module 'vitest/browser' {
+ interface ScreenshotComparatorRegistry {
+ myCustomComparator: {
+ sensitivity?: number
+ ignoreColors?: boolean
+ }
+ }
+}
+
+// 2. Implement the comparator
+export default defineConfig({
+ test: {
+ browser: {
+ expect: {
+ toMatchScreenshot: {
+ comparators: {
+ myCustomComparator: async (
+ reference,
+ actual,
+ {
+ createDiff, // always provided by Vitest
+ sensitivity = 0.01,
+ ignoreColors = false,
+ }
+ ) => {
+ // ...algorithm implementation
+ return { pass, diff, message }
+ },
+ },
+ },
+ },
+ },
+ },
+})
+```
+
+Then use it in your tests:
+
+```ts
+await expect(locator).toMatchScreenshot({
+ comparatorName: 'myCustomComparator',
+ comparatorOptions: {
+ sensitivity: 0.08,
+ ignoreColors: true,
+ },
+})
+```
+
+**Comparator Function Signature:**
+
+```ts
+type Comparator = (
+ reference: {
+ metadata: { height: number; width: number }
+ data: TypedArray
+ },
+ actual: {
+ metadata: { height: number; width: number }
+ data: TypedArray
+ },
+ options: {
+ createDiff: boolean
+ } & Options
+) => Promise<{
+ pass: boolean
+ diff: TypedArray | null
+ message: string | null
+}> | {
+ pass: boolean
+ diff: TypedArray | null
+ message: string | null
+}
+```
+
+The `reference` and `actual` images are decoded using the appropriate codec (currently only PNG). The `data` property is a flat `TypedArray` (`Buffer`, `Uint8Array`, or `Uint8ClampedArray`) containing pixel data in RGBA format:
+
+- **4 bytes per pixel**: red, green, blue, alpha (from `0` to `255` each)
+- **Row-major order**: pixels are stored left-to-right, top-to-bottom
+- **Total length**: `width × height × 4` bytes
+- **Alpha channel**: always present. Images without transparency have alpha values set to `255` (fully opaque)
+
+::: tip Performance Considerations
+The `createDiff` option indicates whether a diff image is needed. During [stable screenshot detection](/guide/browser/visual-regression-testing#how-visual-tests-work), Vitest calls comparators with `createDiff: false` to avoid unnecessary work.
+
+**Respect this flag to keep your tests fast**.
+:::
+
+::: warning Handle Missing Options
+The `options` parameter in `toMatchScreenshot()` is optional, so users might not provide all your comparator options. Always make them optional with default values:
+
+```ts
+myCustomComparator: (
+ reference,
+ actual,
+ { createDiff, threshold = 0.1, maxDiff = 100 },
+) => {
+ // ...comparison logic
+}
+```
+:::
diff --git a/config/browser/api.md b/config/browser/api.md
new file mode 100644
index 00000000..b1491e14
--- /dev/null
+++ b/config/browser/api.md
@@ -0,0 +1,12 @@
+---
+title: browser.api | Config
+outline: deep
+---
+
+# browser.api
+
+- **Type:** `number | { port?, strictPort?, host? }`
+- **Default:** `63315`
+- **CLI:** `--browser.api=63315`, `--browser.api.port=1234, --browser.api.host=example.com`
+
+Configure options for Vite server that serves code in the browser. Does not affect [`test.api`](#api) option. By default, Vitest assigns port `63315` to avoid conflicts with the development server, allowing you to run both in parallel.
diff --git a/config/browser/commands.md b/config/browser/commands.md
new file mode 100644
index 00000000..b933f093
--- /dev/null
+++ b/config/browser/commands.md
@@ -0,0 +1,11 @@
+---
+title: browser.commands | Config
+outline: deep
+---
+
+# browser.commands
+
+- **Type:** `Record`
+- **Default:** `{ readFile, writeFile, ... }`
+
+Custom [commands](/api/browser/commands) that can be imported during browser tests from `vitest/browser`.
diff --git a/config/browser/connecttimeout.md b/config/browser/connecttimeout.md
new file mode 100644
index 00000000..275b39b5
--- /dev/null
+++ b/config/browser/connecttimeout.md
@@ -0,0 +1,15 @@
+---
+title: browser.connectTimeout | Config
+outline: deep
+---
+
+# browser.connectTimeout
+
+- **Type:** `number`
+- **Default:** `60_000`
+
+The timeout in milliseconds. If connection to the browser takes longer, the test suite will fail.
+
+::: info
+This is the time it should take for the browser to establish the WebSocket connection with the Vitest server. In normal circumstances, this timeout should never be reached.
+:::
diff --git a/config/browser/enabled.md b/config/browser/enabled.md
new file mode 100644
index 00000000..766e85ba
--- /dev/null
+++ b/config/browser/enabled.md
@@ -0,0 +1,44 @@
+---
+title: browser.enabled | Config
+---
+
+# browser.enabled
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **CLI:** `--browser`, `--browser.enabled=false`
+
+Enabling this flag makes Vitest run all tests in a [browser](/guide/browser/) by default. If you are configuring other browser options via the CLI, you can use `--browser.enabled` alongside them instead of `--browser`:
+
+```sh
+vitest --browser.enabled --browser.headless
+```
+
+::: warning
+To enable [Browser Mode](/guide/browser/), you must also specify the [`provider`](/config/browser/provider) and at least one [`instance`](/config/browser/instances). Available providers:
+
+- [playwright](/config/browser/playwright)
+- [webdriverio](/config/browser/webdriverio)
+- [preview](/config/browser/preview)
+:::
+
+## Example
+
+```js{7} [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+import { playwright } from '@vitest/browser-playwright'
+
+export default defineConfig({
+ test: {
+ browser: {
+ enabled: true,
+ provider: playwright(),
+ instances: [
+ { browser: 'chromium' },
+ ],
+ },
+ },
+})
+```
+
+If you use TypeScript, the `browser` field in `instances` provides autocompletion based on your provider.
diff --git a/config/browser/expect.md b/config/browser/expect.md
new file mode 100644
index 00000000..501fb0c1
--- /dev/null
+++ b/config/browser/expect.md
@@ -0,0 +1,255 @@
+---
+title: browser.expect | Config
+outline: deep
+---
+
+# browser.expect
+
+- **Type:** `ExpectOptions`
+
+## browser.expect.toMatchScreenshot
+
+Default options for the
+[`toMatchScreenshot` assertion](/api/browser/assertions.html#tomatchscreenshot).
+These options will be applied to all screenshot assertions.
+
+::: tip
+Setting global defaults for screenshot assertions helps maintain consistency
+across your test suite and reduces repetition in individual tests. You can still
+override these defaults at the assertion level when needed for specific test cases.
+:::
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ browser: {
+ enabled: true,
+ expect: {
+ toMatchScreenshot: {
+ comparatorName: 'pixelmatch',
+ comparatorOptions: {
+ threshold: 0.2,
+ allowedMismatchedPixels: 100,
+ },
+ resolveScreenshotPath: ({ arg, browserName, ext, testFileName }) =>
+ `custom-screenshots/${testFileName}/${arg}-${browserName}${ext}`,
+ },
+ },
+ },
+ },
+})
+```
+
+[All options available in the `toMatchScreenshot` assertion](/api/browser/assertions#options)
+can be configured here. Additionally, two path resolution functions are
+available: `resolveScreenshotPath` and `resolveDiffPath`.
+
+## browser.expect.toMatchScreenshot.resolveScreenshotPath
+
+- **Type:** `(data: PathResolveData) => string`
+- **Default output:** `` `${root}/${testFileDirectory}/${screenshotDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}` ``
+
+A function to customize where reference screenshots are stored. The function
+receives an object with the following properties:
+
+- `arg: string`
+
+ Path **without** extension, sanitized and relative to the test file.
+
+ This comes from the arguments passed to `toMatchScreenshot`; if called
+ without arguments this will be the auto-generated name.
+
+ ```ts
+ test('calls `onClick`', () => {
+ expect(locator).toMatchScreenshot()
+ // arg = "calls-onclick-1"
+ })
+
+ expect(locator).toMatchScreenshot('foo/bar/baz.png')
+ // arg = "foo/bar/baz"
+
+ expect(locator).toMatchScreenshot('../foo/bar/baz.png')
+ // arg = "foo/bar/baz"
+ ```
+
+- `ext: string`
+
+ Screenshot extension, with leading dot.
+
+ This can be set through the arguments passed to `toMatchScreenshot`, but
+ the value will fall back to `'.png'` if an unsupported extension is used.
+
+- `browserName: string`
+
+ The instance's browser name.
+
+- `platform: NodeJS.Platform`
+
+ The value of
+ [`process.platform`](https://nodejs.org/docs/v22.16.0/api/process.html#processplatform).
+
+- `screenshotDirectory: string`
+
+ The value provided to
+ [`browser.screenshotDirectory`](/config/browser/screenshotdirectory),
+ if none is provided, its default value.
+
+- `root: string`
+
+ Absolute path to the project's [`root`](/config/#root).
+
+- `testFileDirectory: string`
+
+ Path to the test file, relative to the project's [`root`](/config/#root).
+
+- `testFileName: string`
+
+ The test's filename.
+
+- `testName: string`
+
+ The [`test`](/api/#test)'s name, including parent
+ [`describe`](/api/#describe), sanitized.
+
+- `attachmentsDir: string`
+
+ The value provided to [`attachmentsDir`](/config/#attachmentsdir), if none is
+ provided, its default value.
+
+For example, to group screenshots by browser:
+
+```ts
+resolveScreenshotPath: ({ arg, browserName, ext, root, testFileName }) =>
+ `${root}/screenshots/${browserName}/${testFileName}/${arg}${ext}`
+```
+
+## browser.expect.toMatchScreenshot.resolveDiffPath
+
+- **Type:** `(data: PathResolveData) => string`
+- **Default output:** `` `${root}/${attachmentsDir}/${testFileDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}` ``
+
+A function to customize where diff images are stored when screenshot comparisons
+fail. Receives the same data object as
+[`resolveScreenshotPath`](#browser-expect-tomatchscreenshot-resolvescreenshotpath).
+
+For example, to store diffs in a subdirectory of attachments:
+
+```ts
+resolveDiffPath: ({ arg, attachmentsDir, browserName, ext, root, testFileName }) =>
+ `${root}/${attachmentsDir}/screenshot-diffs/${testFileName}/${arg}-${browserName}${ext}`
+```
+
+## browser.expect.toMatchScreenshot.comparators
+
+- **Type:** `Record`
+
+Register custom screenshot comparison algorithms, like [SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure) or other perceptual similarity metrics.
+
+To create a custom comparator, you need to register it in your config. If using TypeScript, declare its options in the `ScreenshotComparatorRegistry` interface.
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+// 1. Declare the comparator's options type
+declare module 'vitest/browser' {
+ interface ScreenshotComparatorRegistry {
+ myCustomComparator: {
+ sensitivity?: number
+ ignoreColors?: boolean
+ }
+ }
+}
+
+// 2. Implement the comparator
+export default defineConfig({
+ test: {
+ browser: {
+ expect: {
+ toMatchScreenshot: {
+ comparators: {
+ myCustomComparator: async (
+ reference,
+ actual,
+ {
+ createDiff, // always provided by Vitest
+ sensitivity = 0.01,
+ ignoreColors = false,
+ }
+ ) => {
+ // ...algorithm implementation
+ return { pass, diff, message }
+ },
+ },
+ },
+ },
+ },
+ },
+})
+```
+
+Then use it in your tests:
+
+```ts
+await expect(locator).toMatchScreenshot({
+ comparatorName: 'myCustomComparator',
+ comparatorOptions: {
+ sensitivity: 0.08,
+ ignoreColors: true,
+ },
+})
+```
+
+**Comparator Function Signature:**
+
+```ts
+type Comparator = (
+ reference: {
+ metadata: { height: number; width: number }
+ data: TypedArray
+ },
+ actual: {
+ metadata: { height: number; width: number }
+ data: TypedArray
+ },
+ options: {
+ createDiff: boolean
+ } & Options
+) => Promise<{
+ pass: boolean
+ diff: TypedArray | null
+ message: string | null
+}> | {
+ pass: boolean
+ diff: TypedArray | null
+ message: string | null
+}
+```
+
+The `reference` and `actual` images are decoded using the appropriate codec (currently only PNG). The `data` property is a flat `TypedArray` (`Buffer`, `Uint8Array`, or `Uint8ClampedArray`) containing pixel data in RGBA format:
+
+- **4 bytes per pixel**: red, green, blue, alpha (from `0` to `255` each)
+- **Row-major order**: pixels are stored left-to-right, top-to-bottom
+- **Total length**: `width × height × 4` bytes
+- **Alpha channel**: always present. Images without transparency have alpha values set to `255` (fully opaque)
+
+::: tip Performance Considerations
+The `createDiff` option indicates whether a diff image is needed. During [stable screenshot detection](/guide/browser/visual-regression-testing#how-visual-tests-work), Vitest calls comparators with `createDiff: false` to avoid unnecessary work.
+
+**Respect this flag to keep your tests fast**.
+:::
+
+::: warning Handle Missing Options
+The `options` parameter in `toMatchScreenshot()` is optional, so users might not provide all your comparator options. Always make them optional with default values:
+
+```ts
+myCustomComparator: (
+ reference,
+ actual,
+ { createDiff, threshold = 0.1, maxDiff = 100 },
+) => {
+ // ...comparison logic
+}
+```
+:::
diff --git a/config/browser/headless.md b/config/browser/headless.md
new file mode 100644
index 00000000..f0bd1614
--- /dev/null
+++ b/config/browser/headless.md
@@ -0,0 +1,12 @@
+---
+title: browser.headless | Config
+outline: deep
+---
+
+# browser.headless
+
+- **Type:** `boolean`
+- **Default:** `process.env.CI`
+- **CLI:** `--browser.headless`, `--browser.headless=false`
+
+Run the browser in a `headless` mode. If you are running Vitest in CI, it will be enabled by default.
diff --git a/config/browser/instances.md b/config/browser/instances.md
new file mode 100644
index 00000000..446545ea
--- /dev/null
+++ b/config/browser/instances.md
@@ -0,0 +1,52 @@
+---
+title: browser.instances | Config
+outline: deep
+---
+
+# browser.instances
+
+- **Type:** `BrowserConfig`
+- **Default:** `[]`
+
+Defines multiple browser setups. Every config has to have at least a `browser` field.
+
+You can specify most of the [project options](/config/) (not marked with a icon) and some of the `browser` options like `browser.testerHtmlPath`.
+
+::: warning
+Every browser config inherits options from the root config:
+
+```ts{3,9} [vitest.config.ts]
+export default defineConfig({
+ test: {
+ setupFile: ['./root-setup-file.js'],
+ browser: {
+ enabled: true,
+ testerHtmlPath: './custom-path.html',
+ instances: [
+ {
+ // will have both setup files: "root" and "browser"
+ setupFile: ['./browser-setup-file.js'],
+ // implicitly has "testerHtmlPath" from the root config // [!code warning]
+ // testerHtmlPath: './custom-path.html', // [!code warning]
+ },
+ ],
+ },
+ },
+})
+```
+
+For more examples, refer to the ["Multiple Setups" guide](/guide/browser/multiple-setups).
+:::
+
+List of available `browser` options:
+
+- `browser` (the name of the browser)
+- [`headless`](/config/browser/headless)
+- [`locators`](/config/browser/locators)
+- [`viewport`](/config/browser/viewport)
+- [`testerHtmlPath`](/config/browser/testerhtmlpath)
+- [`screenshotDirectory`](/config/browser/screenshotdirectory)
+- [`screenshotFailures`](/config/browser/screenshotfailures)
+- [`provider`](/config/browser/provider)
+
+Under the hood, Vitest transforms these instances into separate [test projects](/api/advanced/test-project) sharing a single Vite server for better caching performance.
diff --git a/config/browser/isolate.md b/config/browser/isolate.md
new file mode 100644
index 00000000..6663c85c
--- /dev/null
+++ b/config/browser/isolate.md
@@ -0,0 +1,16 @@
+---
+title: browser.isolate | Config
+outline: deep
+---
+
+# browser.isolate
+
+- **Type:** `boolean`
+- **Default:** the same as [`--isolate`](/config/#isolate)
+- **CLI:** `--browser.isolate`, `--browser.isolate=false`
+
+Run every test in a separate iframe.
+
+::: danger DEPRECATED
+This option is deprecated. Use [`isolate`](/config/#isolate) instead.
+:::
diff --git a/config/browser/locators.md b/config/browser/locators.md
new file mode 100644
index 00000000..c0e4991c
--- /dev/null
+++ b/config/browser/locators.md
@@ -0,0 +1,15 @@
+---
+title: browser.locators | Config
+outline: deep
+---
+
+# browser.locators
+
+Options for built-in [browser locators](/api/browser/locators).
+
+## browser.locators.testIdAttribute
+
+- **Type:** `string`
+- **Default:** `data-testid`
+
+Attribute used to find elements with `getByTestId` locator.
diff --git a/config/browser/orchestratorscripts.md b/config/browser/orchestratorscripts.md
new file mode 100644
index 00000000..7a430429
--- /dev/null
+++ b/config/browser/orchestratorscripts.md
@@ -0,0 +1,44 @@
+---
+title: browser.orchestratorScripts | Config
+outline: deep
+---
+
+# browser.orchestratorScripts
+
+- **Type:** `BrowserScript[]`
+- **Default:** `[]`
+
+Custom scripts that should be injected into the orchestrator HTML before test iframes are initiated. This HTML document only sets up iframes and doesn't actually import your code.
+
+The script `src` and `content` will be processed by Vite plugins. Script should be provided in the following shape:
+
+```ts
+export interface BrowserScript {
+ /**
+ * If "content" is provided and type is "module", this will be its identifier.
+ *
+ * If you are using TypeScript, you can add `.ts` extension here for example.
+ * @default `injected-${index}.js`
+ */
+ id?: string
+ /**
+ * JavaScript content to be injected. This string is processed by Vite plugins if type is "module".
+ *
+ * You can use `id` to give Vite a hint about the file extension.
+ */
+ content?: string
+ /**
+ * Path to the script. This value is resolved by Vite so it can be a node module or a file path.
+ */
+ src?: string
+ /**
+ * If the script should be loaded asynchronously.
+ */
+ async?: boolean
+ /**
+ * Script type.
+ * @default 'module'
+ */
+ type?: string
+}
+```
diff --git a/guide/browser/playwright.md b/config/browser/playwright.md
similarity index 92%
rename from guide/browser/playwright.md
rename to config/browser/playwright.md
index 73097d7f..8a166e2e 100644
--- a/guide/browser/playwright.md
+++ b/config/browser/playwright.md
@@ -62,7 +62,7 @@ export default defineConfig({
这些选项直接传递给 `playwright[browser].launch` 命令。我们可以在 [Playwright 文档](https://playwright.dev/docs/api/class-browsertype#browser-type-launch) 中阅读有关该命令和可用参数的更多信息。
::: warning
-Vitest 将忽略 `launch.headless` 选项。请改用 [`test.browser.headless`](/guide/browser/config#browser-headless)。
+Vitest 将忽略 `launch.headless` 选项。请改用 [`test.browser.headless`](/config/browser/headless)。
请注意,如果启用了 [`--inspect`](/guide/cli#inspect),Vitest 会将调试标志推送到 `launch.args`。
:::
@@ -86,14 +86,14 @@ Vitest 通过调用 [`browser.newContext()`](https://playwright.dev/docs/api/cla
::: warning
如果我们的服务器通过 HTTPS 提供服务,Vitest 始终将 `ignoreHTTPSErrors` 设置为 `true`,并将 `serviceWorkers` 设置为 `'allow'`,以支持通过 [MSW](https://mswjs.io) 进行模块模拟。
-建议使用 [`test.browser.viewport`](/guide/browser/config#browser-headless) 而不是在此处指定它,因为在无头模式下运行测试时会丢失该设置。
+建议使用 [`test.browser.viewport`](/config/browser/headless) 而不是在此处指定它,因为在无头模式下运行测试时会丢失该设置。
:::
## `actionTimeout`
- **默认:** 无超时
-此值配置 Playwright 等待所有可访问性检查通过并 [操作](/guide/browser/interactivity-api) 实际完成的默认超时时间。
+此值配置 Playwright 等待所有可访问性检查通过并 [操作](/api/browser/interactivity) 实际完成的默认超时时间。
我们还可以为每个操作配置操作超时:
diff --git a/guide/browser/preview.md b/config/browser/preview.md
similarity index 75%
rename from guide/browser/preview.md
rename to config/browser/preview.md
index 4067d5de..eb608a04 100644
--- a/guide/browser/preview.md
+++ b/config/browser/preview.md
@@ -1,7 +1,7 @@
# 配置预览
::: warning
-`preview` 提供程序的主要功能是在真实浏览器环境中显示测试。不过,它不支持高级浏览器自动化功能,如多个浏览器实例或无头模式。对于更复杂的场景,请考虑使用 [Playwright](/guide/browser/playwright) 或 [WebdriverIO](/guide/browser/webdriverio)。
+`preview` 提供程序的主要功能是在真实浏览器环境中显示测试。不过,它不支持高级浏览器自动化功能,如多个浏览器实例或无头模式。对于更复杂的场景,请考虑使用 [Playwright](/config/browser/playwright) 或 [WebdriverIO](/config/browser/webdriverio)。
:::
要让你的测试运行在真实浏览器中,需要安装 [`@vitest/browser-preview`](https://www.npmjs.com/package/@vitest/browser-preview) npm 软件包,并在配置的 `test.browser.provider` 属性中指定其 `preview` 导出:
@@ -24,9 +24,9 @@ export default defineConfig({
## 与其他 Providers 的差异
-与 [Playwright](/guide/browser/playwright) 或 [WebdriverIO](/guide/browser/webdriverio) 等其他 Providers 相比,预览服务存在一些限制:
+与 [Playwright](/config/browser/playwright) 或 [WebdriverIO](/config/browser/webdriverio) 等其他 Providers 相比,预览服务存在一些限制:
- 它不支持无头模式; 浏览器窗口始终可见.
- 它不支持同一浏览器的多个实例; 每个实例必须使用不同的浏览器.
- 它不支持高级浏览器功能或选项; 你只能指定浏览器名称.
-- 它不支持 CDP(Chrome DevTools 协议)命令或其他低层浏览器交互. 与 Playwright 或 WebdriverIO 不同, [`userEvent`](/guide/browser/interactivity-api) API 只是从 [`@testing-library/user-event`](https://www.npmjs.com/package/@testing-library/user-event) 重新导出, 没有与浏览器的特殊集成.
+- 它不支持 CDP(Chrome DevTools 协议)命令或其他低层浏览器交互. 与 Playwright 或 WebdriverIO 不同, [`userEvent`](/api/browser/interactivity) API 只是从 [`@testing-library/user-event`](https://www.npmjs.com/package/@testing-library/user-event) 重新导出, 没有与浏览器的特殊集成.
diff --git a/config/browser/provider.md b/config/browser/provider.md
new file mode 100644
index 00000000..366c07e0
--- /dev/null
+++ b/config/browser/provider.md
@@ -0,0 +1,84 @@
+---
+title: browser.provider | Config
+outline: deep
+---
+
+# browser.provider {#browser-provider}
+
+- **Type:** `BrowserProviderOption`
+
+The return value of the provider factory. You can import the factory from `@vitest/browser-` or make your own provider:
+
+```ts{8-10}
+import { playwright } from '@vitest/browser-playwright'
+import { webdriverio } from '@vitest/browser-webdriverio'
+import { preview } from '@vitest/browser-preview'
+
+export default defineConfig({
+ test: {
+ browser: {
+ provider: playwright(),
+ provider: webdriverio(),
+ provider: preview(),
+ },
+ },
+})
+```
+
+To configure how provider initializes the browser, you can pass down options to the factory function:
+
+```ts{7-13,20-26}
+import { playwright } from '@vitest/browser-playwright'
+
+export default defineConfig({
+ test: {
+ browser: {
+ // shared provider options between all instances
+ provider: playwright({
+ launchOptions: {
+ slowMo: 50,
+ channel: 'chrome-beta',
+ },
+ actionTimeout: 5_000,
+ }),
+ instances: [
+ { browser: 'chromium' },
+ {
+ browser: 'firefox',
+ // overriding options only for a single instance
+ // this will NOT merge options with the parent one
+ provider: playwright({
+ launchOptions: {
+ firefoxUserPrefs: {
+ 'browser.startup.homepage': 'https://example.com',
+ },
+ },
+ })
+ }
+ ],
+ },
+ },
+})
+```
+
+## Custom Provider advanced
+
+::: danger ADVANCED API
+The custom provider API is highly experimental and can change between patches. If you just need to run tests in a browser, use the [`browser.instances`](#browser-instances) option instead.
+:::
+
+```ts
+export interface BrowserProvider {
+ name: string
+ mocker?: BrowserModuleMocker
+ readonly initScripts?: string[]
+ /**
+ * @experimental opt-in into file parallelisation
+ */
+ supportsParallelism: boolean
+ getCommandsContext: (sessionId: string) => Record
+ openPage: (sessionId: string, url: string) => Promise
+ getCDPSession?: (sessionId: string) => Promise
+ close: () => Awaitable
+}
+```
diff --git a/config/browser/screenshotdirectory.md b/config/browser/screenshotdirectory.md
new file mode 100644
index 00000000..8cc87068
--- /dev/null
+++ b/config/browser/screenshotdirectory.md
@@ -0,0 +1,11 @@
+---
+title: browser.screenshotDirectory | Config
+outline: deep
+---
+
+# browser.screenshotDirectory
+
+- **Type:** `string`
+- **Default:** `__screenshots__` in the test file directory
+
+Path to the screenshots directory relative to the `root`.
diff --git a/config/browser/screenshotfailures.md b/config/browser/screenshotfailures.md
new file mode 100644
index 00000000..4c787c5c
--- /dev/null
+++ b/config/browser/screenshotfailures.md
@@ -0,0 +1,11 @@
+---
+title: browser.screenshotFailures | Config
+outline: deep
+---
+
+# browser.screenshotFailures
+
+- **Type:** `boolean`
+- **Default:** `!browser.ui`
+
+Should Vitest take screenshots if the test fails.
diff --git a/config/browser/testerhtmlpath.md b/config/browser/testerhtmlpath.md
new file mode 100644
index 00000000..7042e204
--- /dev/null
+++ b/config/browser/testerhtmlpath.md
@@ -0,0 +1,10 @@
+---
+title: browser.testerHtmlPath | Config
+outline: deep
+---
+
+# browser.testerHtmlPath
+
+- **Type:** `string`
+
+A path to the HTML entry point. Can be relative to the root of the project. This file will be processed with [`transformIndexHtml`](https://vite.dev/guide/api-plugin#transformindexhtml) hook.
diff --git a/config/browser/trace.md b/config/browser/trace.md
new file mode 100644
index 00000000..51b62eba
--- /dev/null
+++ b/config/browser/trace.md
@@ -0,0 +1,48 @@
+---
+title: browser.trace | Config
+outline: deep
+---
+
+# browser.trace
+
+- **Type:** `'on' | 'off' | 'on-first-retry' | 'on-all-retries' | 'retain-on-failure' | object`
+- **CLI:** `--browser.trace=on`, `--browser.trace=retain-on-failure`
+- **Default:** `'off'`
+
+Capture a trace of your browser test runs. You can preview traces with [Playwright Trace Viewer](https://trace.playwright.dev/).
+
+This options supports the following values:
+
+- `'on'` - capture trace for all tests. (not recommended as it's performance heavy)
+- `'off'` - do not capture traces.
+- `'on-first-retry'` - capture trace only when retrying the test for the first time.
+- `'on-all-retries'` - capture trace on every retry of the test.
+- `'retain-on-failure'` - capture trace only for tests that fail. This will automatically delete traces for tests that pass.
+- `object` - an object with the following shape:
+
+```ts
+interface TraceOptions {
+ mode: 'on' | 'off' | 'on-first-retry' | 'on-all-retries' | 'retain-on-failure'
+ /**
+ * The directory where all traces will be stored. By default, Vitest
+ * stores all traces in `__traces__` folder close to the test file.
+ */
+ tracesDir?: string
+ /**
+ * Whether to capture screenshots during tracing. Screenshots are used to build a timeline preview.
+ * @default true
+ */
+ screenshots?: boolean
+ /**
+ * If this option is true tracing will
+ * - capture DOM snapshot on every action
+ * - record network activity
+ * @default true
+ */
+ snapshots?: boolean
+}
+```
+
+::: danger WARNING
+This option is supported only by the [**playwright**](/config/browser/playwright) provider.
+:::
diff --git a/config/browser/trackunhandlederrors.md b/config/browser/trackunhandlederrors.md
new file mode 100644
index 00000000..cab9a2d4
--- /dev/null
+++ b/config/browser/trackunhandlederrors.md
@@ -0,0 +1,15 @@
+---
+title: browser.trackUnhandledErrors | Config
+outline: deep
+---
+
+# browser.trackUnhandledErrors
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Enables tracking uncaught errors and exceptions so they can be reported by Vitest.
+
+If you need to hide certain errors, it is recommended to use [`onUnhandledError`](/config/#onunhandlederror) option instead.
+
+Disabling this will completely remove all Vitest error handlers, which can help debugging with the "Pause on exceptions" checkbox turned on.
diff --git a/config/browser/ui.md b/config/browser/ui.md
new file mode 100644
index 00000000..4b437c96
--- /dev/null
+++ b/config/browser/ui.md
@@ -0,0 +1,12 @@
+---
+title: browser.ui | Config
+outline: deep
+---
+
+# browser.ui
+
+- **Type:** `boolean`
+- **Default:** `!isCI`
+- **CLI:** `--browser.ui=false`
+
+Should Vitest UI be injected into the page. By default, injects UI iframe during development.
diff --git a/config/browser/viewport.md b/config/browser/viewport.md
new file mode 100644
index 00000000..e226a453
--- /dev/null
+++ b/config/browser/viewport.md
@@ -0,0 +1,11 @@
+---
+title: browser.viewport | Config
+outline: deep
+---
+
+# browser.viewport
+
+- **Type:** `{ width, height }`
+- **Default:** `414x896`
+
+Default iframe's viewport.
diff --git a/guide/browser/webdriverio.md b/config/browser/webdriverio.md
similarity index 91%
rename from guide/browser/webdriverio.md
rename to config/browser/webdriverio.md
index 7da339f3..11ba70cf 100644
--- a/guide/browser/webdriverio.md
+++ b/config/browser/webdriverio.md
@@ -1,7 +1,7 @@
# 配置 WebdriverIO {#configuring-webdriverio}
::: info Playwright 与 WebdriverIO
-如果我们的项目尚未使用 WebdriverIO,我们建议从 [Playwright](/guide/browser/playwright) 开始,因为它更易于配置且 API 更灵活。
+如果我们的项目尚未使用 WebdriverIO,我们建议从 [Playwright](/config/browser/playwright) 开始,因为它更易于配置且 API 更灵活。
:::
要使用 WebdriverIO 运行测试,你需要安装 [`@vitest/browser-webdriverio`](https://www.npmjs.com/package/@vitest/browser-webdriverio) npm 包,并在配置中的 `test.browser.provider` 属性中指定其 `webdriverio` 导出:
@@ -60,5 +60,5 @@ export default defineConfig({
::: tip
最有用的选项位于 `capabilities` 对象上。WebdriverIO 允许嵌套功能,但 Vitest 将忽略这些选项,因为我们依赖于不同的机制来生成多个浏览器。
-请注意,Vitest 将忽略 `capabilities.browserName` — 请改用 [`test.browser.instances.browser`](/guide/browser/config#browser-capabilities-name)。
+请注意,Vitest 将忽略 `capabilities.browserName` — 请改用 [`test.browser.instances.browser`](/config/browser/instances#browser)。
:::
diff --git a/config/cache.md b/config/cache.md
new file mode 100644
index 00000000..a480f628
--- /dev/null
+++ b/config/cache.md
@@ -0,0 +1,31 @@
+---
+title: cache | Config
+outline: deep
+---
+
+# cache
+
+- **Type**: `false`
+- **CLI**: `--no-cache`, `--cache=false`
+
+Use this option if you want to disable the cache feature. At the moment Vitest stores cache for test results to run the longer and failed tests first.
+
+The cache directory is controlled by the Vite's [`cacheDir`](https://vitejs.dev/config/shared-options.html#cachedir) option:
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ cacheDir: 'custom-folder/.vitest'
+})
+```
+
+You can limit the directory only for Vitest by using `process.env.VITEST`:
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ cacheDir: process.env.VITEST ? 'custom-folder/.vitest' : undefined
+})
+```
diff --git a/config/chaiconfig.md b/config/chaiconfig.md
new file mode 100644
index 00000000..24cf085a
--- /dev/null
+++ b/config/chaiconfig.md
@@ -0,0 +1,34 @@
+---
+title: chaiConfig | Config
+outline: deep
+---
+
+# chaiConfig
+
+- **Type:** `{ includeStack?, showDiff?, truncateThreshold? }`
+- **Default:** `{ includeStack: false, showDiff: true, truncateThreshold: 40 }`
+
+Equivalent to [Chai config](https://github.com/chaijs/chai/blob/4.x.x/lib/chai/config.js).
+
+## chaiConfig.includeStack
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Influences whether stack trace is included in Assertion error message. Default of false suppresses stack trace in the error message.
+
+## chaiConfig.showDiff
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Influences whether or not the `showDiff` flag should be included in the thrown AssertionErrors. `false` will always be `false`; `true` will be true when the assertion has requested a diff to be shown.
+
+## chaiConfig.truncateThreshold
+
+- **Type:** `number`
+- **Default:** `40`
+
+Sets length threshold for actual and expected values in assertion errors. If this threshold is exceeded, for example for large data structures, the value is replaced with something like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. Set it to `0` if you want to disable truncating altogether.
+
+This config option affects truncating values in `test.each` titles and inside the assertion error message.
diff --git a/config/clearmocks.md b/config/clearmocks.md
new file mode 100644
index 00000000..fff1dbfd
--- /dev/null
+++ b/config/clearmocks.md
@@ -0,0 +1,23 @@
+---
+title: clearMocks | Config
+outline: deep
+---
+
+# clearMocks
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Should Vitest automatically call [`vi.clearAllMocks()`](/api/vi#vi-clearallmocks) before each test.
+
+This will clear mock history without affecting mock implementations.
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ clearMocks: true,
+ },
+})
+```
diff --git a/config/coverage.md b/config/coverage.md
new file mode 100644
index 00000000..d760620c
--- /dev/null
+++ b/config/coverage.md
@@ -0,0 +1,397 @@
+---
+title: coverage | Config
+outline: deep
+---
+
+# coverage {#coverage}
+
+You can use [`v8`](/guide/coverage.html#v8-provider), [`istanbul`](/guide/coverage.html#istanbul-provider) or [a custom coverage solution](/guide/coverage#custom-coverage-provider) for coverage collection.
+
+You can provide coverage options to CLI with dot notation:
+
+```sh
+npx vitest --coverage.enabled --coverage.provider=istanbul
+```
+
+::: warning
+If you are using coverage options with dot notation, don't forget to specify `--coverage.enabled`. Do not provide a single `--coverage` option in that case.
+:::
+
+## coverage.provider
+
+- **Type:** `'v8' | 'istanbul' | 'custom'`
+- **Default:** `'v8'`
+- **CLI:** `--coverage.provider=`
+
+Use `provider` to select the tool for coverage collection.
+
+## coverage.enabled
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.enabled`, `--coverage.enabled=false`
+
+Enables coverage collection. Can be overridden using `--coverage` CLI option.
+
+## coverage.include
+
+- **Type:** `string[]`
+- **Default:** Files that were imported during test run
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.include=`, `--coverage.include= --coverage.include=`
+
+List of files included in coverage as glob patterns. By default only files covered by tests are included.
+
+It is recommended to pass file extensions in the pattern.
+
+See [Including and excluding files from coverage report](/guide/coverage.html#including-and-excluding-files-from-coverage-report) for examples.
+
+## coverage.exclude
+
+- **Type:** `string[]`
+- **Default:** : `[]`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.exclude=`, `--coverage.exclude= --coverage.exclude=`
+
+List of files excluded from coverage as glob patterns.
+
+See [Including and excluding files from coverage report](/guide/coverage.html#including-and-excluding-files-from-coverage-report) for examples.
+
+## coverage.clean
+
+- **Type:** `boolean`
+- **Default:** `true`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.clean`, `--coverage.clean=false`
+
+Clean coverage results before running tests
+
+## coverage.cleanOnRerun
+
+- **Type:** `boolean`
+- **Default:** `true`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.cleanOnRerun`, `--coverage.cleanOnRerun=false`
+
+Clean coverage report on watch rerun. Set to `false` to preserve coverage results from previous run in watch mode.
+
+## coverage.reportsDirectory
+
+- **Type:** `string`
+- **Default:** `'./coverage'`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.reportsDirectory=`
+
+::: warning
+Vitest will delete this directory before running tests if `coverage.clean` is enabled (default value).
+:::
+
+Directory to write coverage report to.
+
+To preview the coverage report in the output of [HTML reporter](/guide/reporters.html#html-reporter), this option must be set as a sub-directory of the html report directory (for example `./html/coverage`).
+
+## coverage.reporter
+
+- **Type:** `string | string[] | [string, {}][]`
+- **Default:** `['text', 'html', 'clover', 'json']`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.reporter=`, `--coverage.reporter= --coverage.reporter=`
+
+Coverage reporters to use. See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters. See [`@types/istanbul-reporter`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/276d95e4304b3670eaf6e8e5a7ea9e265a14e338/types/istanbul-reports/index.d.ts) for details about reporter specific options.
+
+The reporter has three different types:
+
+- A single reporter: `{ reporter: 'html' }`
+- Multiple reporters without options: `{ reporter: ['html', 'json'] }`
+- A single or multiple reporters with reporter options:
+
+ ```ts
+ {
+ reporter: [
+ ['lcov', { 'projectRoot': './src' }],
+ ['json', { 'file': 'coverage.json' }],
+ ['text']
+ ]
+ }
+ ```
+
+You can also pass custom coverage reporters. See [Guide - Custom Coverage Reporter](/guide/coverage#custom-coverage-reporter) for more information.
+
+
+```ts
+ {
+ reporter: [
+ // Specify reporter using name of the NPM package
+ '@vitest/custom-coverage-reporter',
+ ['@vitest/custom-coverage-reporter', { someOption: true }],
+
+ // Specify reporter using local path
+ '/absolute/path/to/custom-reporter.cjs',
+ ['/absolute/path/to/custom-reporter.cjs', { someOption: true }],
+ ]
+ }
+```
+
+You can check your coverage report in Vitest UI: check [Vitest UI Coverage](/guide/coverage#vitest-ui) for more details.
+
+## coverage.reportOnFailure {#coverage-reportonfailure}
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.reportOnFailure`, `--coverage.reportOnFailure=false`
+
+Generate coverage report even when tests fail.
+
+## coverage.allowExternal
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.allowExternal`, `--coverage.allowExternal=false`
+
+Collect coverage of files outside the [project `root`](#root).
+
+## coverage.excludeAfterRemap
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.excludeAfterRemap`, `--coverage.excludeAfterRemap=false`
+
+Apply exclusions again after coverage has been remapped to original sources.
+This is useful when your source files are transpiled and may contain source maps of non-source files.
+
+Use this option when you are seeing files that show up in report even if they match your `coverage.exclude` patterns.
+
+## coverage.skipFull
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.skipFull`, `--coverage.skipFull=false`
+
+Do not show files with 100% statement, branch, and function coverage.
+
+## coverage.thresholds
+
+Options for coverage thresholds.
+
+If a threshold is set to a positive number, it will be interpreted as the minimum percentage of coverage required. For example, setting the lines threshold to `90` means that 90% of lines must be covered.
+
+If a threshold is set to a negative number, it will be treated as the maximum number of uncovered items allowed. For example, setting the lines threshold to `-10` means that no more than 10 lines may be uncovered.
+
+
+```ts
+{
+ coverage: {
+ thresholds: {
+ // Requires 90% function coverage
+ functions: 90,
+
+ // Require that no more than 10 lines are uncovered
+ lines: -10,
+ }
+ }
+}
+```
+
+### coverage.thresholds.lines
+
+- **Type:** `number`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.thresholds.lines=`
+
+Global threshold for lines.
+
+### coverage.thresholds.functions
+
+- **Type:** `number`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.thresholds.functions=`
+
+Global threshold for functions.
+
+### coverage.thresholds.branches
+
+- **Type:** `number`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.thresholds.branches=`
+
+Global threshold for branches.
+
+### coverage.thresholds.statements
+
+- **Type:** `number`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.thresholds.statements=`
+
+Global threshold for statements.
+
+### coverage.thresholds.perFile
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.thresholds.perFile`, `--coverage.thresholds.perFile=false`
+
+Check thresholds per file.
+
+### coverage.thresholds.autoUpdate
+
+- **Type:** `boolean | function`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.thresholds.autoUpdate=`
+
+Update all threshold values `lines`, `functions`, `branches` and `statements` to configuration file when current coverage is better than the configured thresholds.
+This option helps to maintain thresholds when coverage is improved.
+
+You can also pass a function for formatting the updated threshold values:
+
+
+```ts
+{
+ coverage: {
+ thresholds: {
+ // Update thresholds without decimals
+ autoUpdate: (newThreshold) => Math.floor(newThreshold),
+
+ // 95.85 -> 95
+ functions: 95,
+ }
+ }
+}
+```
+
+### coverage.thresholds.100
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.thresholds.100`, `--coverage.thresholds.100=false`
+
+Sets global thresholds to 100.
+Shortcut for `--coverage.thresholds.lines 100 --coverage.thresholds.functions 100 --coverage.thresholds.branches 100 --coverage.thresholds.statements 100`.
+
+### coverage.thresholds[glob-pattern]
+
+- **Type:** `{ statements?: number functions?: number branches?: number lines?: number }`
+- **Default:** `undefined`
+- **Available for providers:** `'v8' | 'istanbul'`
+
+Sets thresholds for files matching the glob pattern.
+
+::: tip NOTE
+Vitest counts all files, including those covered by glob-patterns, into the global coverage thresholds.
+This is different from Jest behavior.
+:::
+
+
+```ts
+{
+ coverage: {
+ thresholds: {
+ // Thresholds for all files
+ functions: 95,
+ branches: 70,
+
+ // Thresholds for matching glob pattern
+ 'src/utils/**.ts': {
+ statements: 95,
+ functions: 90,
+ branches: 85,
+ lines: 80,
+ },
+
+ // Files matching this pattern will only have lines thresholds set.
+ // Global thresholds are not inherited.
+ '**/math.ts': {
+ lines: 100,
+ }
+ }
+ }
+}
+```
+
+### coverage.thresholds[glob-pattern].100
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8' | 'istanbul'`
+
+Sets thresholds to 100 for files matching the glob pattern.
+
+
+```ts
+{
+ coverage: {
+ thresholds: {
+ // Thresholds for all files
+ functions: 95,
+ branches: 70,
+
+ // Thresholds for matching glob pattern
+ 'src/utils/**.ts': { 100: true },
+ '**/math.ts': { 100: true }
+ }
+ }
+}
+```
+
+## coverage.ignoreClassMethods
+
+- **Type:** `string[]`
+- **Default:** `[]`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.ignoreClassMethods=`
+
+Set to array of class method names to ignore for coverage.
+See [istanbul documentation](https://github.com/istanbuljs/nyc#ignoring-methods) for more information.
+
+## coverage.watermarks
+
+- **Type:**
+
+```ts
+{
+ statements?: [number, number],
+ functions?: [number, number],
+ branches?: [number, number],
+ lines?: [number, number]
+}
+```
+
+- **Default:**
+
+```ts
+{
+ statements: [50, 80],
+ functions: [50, 80],
+ branches: [50, 80],
+ lines: [50, 80]
+}
+```
+
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.watermarks.statements=50,80`, `--coverage.watermarks.branches=50,80`
+
+Watermarks for statements, lines, branches and functions. See [istanbul documentation](https://github.com/istanbuljs/nyc#high-and-low-watermarks) for more information.
+
+## coverage.processingConcurrency
+
+- **Type:** `boolean`
+- **Default:** `Math.min(20, os.availableParallelism?.() ?? os.cpus().length)`
+- **Available for providers:** `'v8' | 'istanbul'`
+- **CLI:** `--coverage.processingConcurrency=`
+
+Concurrency limit used when processing the coverage results.
+
+## coverage.customProviderModule
+
+- **Type:** `string`
+- **Available for providers:** `'custom'`
+- **CLI:** `--coverage.customProviderModule=`
+
+Specifies the module name or path for the custom coverage provider module. See [Guide - Custom Coverage Provider](/guide/coverage#custom-coverage-provider) for more information.
diff --git a/config/css.md b/config/css.md
new file mode 100644
index 00000000..eb096d16
--- /dev/null
+++ b/config/css.md
@@ -0,0 +1,52 @@
+---
+title: css | Config
+outline: deep
+---
+
+# css
+
+- **Type**: `boolean | { include?, exclude?, modules? }`
+
+Configure if CSS should be processed. When excluded, CSS files will be replaced with empty strings to bypass the subsequent processing. CSS Modules will return a proxy to not affect runtime.
+
+::: warning
+This option is not applied to [browser tests](/guide/browser/).
+:::
+
+## css.include
+
+- **Type**: `RegExp | RegExp[]`
+- **Default**: `[]`
+
+RegExp pattern for files that should return actual CSS and will be processed by Vite pipeline.
+
+:::tip
+To process all CSS files, use `/.+/`.
+:::
+
+## css.exclude
+
+- **Type**: `RegExp | RegExp[]`
+- **Default**: `[]`
+
+RegExp pattern for files that will return an empty CSS file.
+
+## css.modules
+
+- **Type**: `{ classNameStrategy? }`
+- **Default**: `{}`
+
+### css.modules.classNameStrategy
+
+- **Type**: `'stable' | 'scoped' | 'non-scoped'`
+- **Default**: `'stable'`
+
+If you decide to process CSS files, you can configure if class names inside CSS modules should be scoped. You can choose one of the options:
+
+- `stable`: class names will be generated as `_${name}_${hashedFilename}`, which means that generated class will stay the same, if CSS content is changed, but will change, if the name of the file is modified, or file is moved to another folder. This setting is useful, if you use snapshot feature.
+- `scoped`: class names will be generated as usual, respecting `css.modules.generateScopedName` method, if you have one and CSS processing is enabled. By default, filename will be generated as `_${name}_${hash}`, where hash includes filename and content of the file.
+- `non-scoped`: class names will not be hashed.
+
+::: warning
+By default, Vitest exports a proxy, bypassing CSS Modules processing. If you rely on CSS properties on your classes, you have to enable CSS processing using `include` option.
+:::
diff --git a/config/dangerouslyignoreunhandlederrors.md b/config/dangerouslyignoreunhandlederrors.md
new file mode 100644
index 00000000..54536f19
--- /dev/null
+++ b/config/dangerouslyignoreunhandlederrors.md
@@ -0,0 +1,28 @@
+---
+title: dangerouslyIgnoreUnhandledErrors | Config
+outline: deep
+---
+
+# dangerouslyIgnoreUnhandledErrors
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI:**
+ - `--dangerouslyIgnoreUnhandledErrors`
+ - `--dangerouslyIgnoreUnhandledErrors=false`
+
+If this option is set to `true`, Vitest will not fail the test run if there are unhandled errors. Note that built-in reporters will still report them.
+
+If you want to filter out certain errors conditionally, use [`onUnhandledError`](/config/onunhandlederror) callback instead.
+
+## Example
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ dangerouslyIgnoreUnhandledErrors: true,
+ },
+})
+```
diff --git a/config/deps.md b/config/deps.md
new file mode 100644
index 00000000..b49b8fdd
--- /dev/null
+++ b/config/deps.md
@@ -0,0 +1,132 @@
+---
+title: deps | Config
+outline: deep
+---
+
+# deps
+
+- **Type:** `{ optimizer?, ... }`
+
+Handling for dependencies resolution.
+
+## deps.optimizer {#deps-optimizer}
+
+- **Type:** `{ ssr?, client? }`
+- **See also:** [Dep Optimization Options](https://vitejs.dev/config/dep-optimization-options.html)
+
+Enable dependency optimization. If you have a lot of tests, this might improve their performance.
+
+When Vitest encounters the external library listed in `include`, it will be bundled into a single file using esbuild and imported as a whole module. This is good for several reasons:
+
+- Importing packages with a lot of imports is expensive. By bundling them into one file we can save a lot of time
+- Importing UI libraries is expensive because they are not meant to run inside Node.js
+- Your `alias` configuration is now respected inside bundled packages
+- Code in your tests is running closer to how it's running in the browser
+
+Be aware that only packages in `deps.optimizer?.[mode].include` option are bundled (some plugins populate this automatically, like Svelte). You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs (Vitest doesn't support `disable` and `noDiscovery` options). By default, Vitest uses `optimizer.client` for `jsdom` and `happy-dom` environments, and `optimizer.ssr` for `node` and `edge` environments.
+
+This options also inherits your `optimizeDeps` configuration (for web Vitest will extend `optimizeDeps`, for ssr - `ssr.optimizeDeps`). If you redefine `include`/`exclude` option in `deps.optimizer` it will extend your `optimizeDeps` when running tests. Vitest automatically removes the same options from `include`, if they are listed in `exclude`.
+
+::: tip
+You will not be able to edit your `node_modules` code for debugging, since the code is actually located in your `cacheDir` or `test.cache.dir` directory. If you want to debug with `console.log` statements, edit it directly or force rebundling with `deps.optimizer?.[mode].force` option.
+:::
+
+### deps.optimizer.{mode}.enabled
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Enable dependency optimization.
+
+## deps.client {#deps-client}
+
+- **Type:** `{ transformAssets?, ... }`
+
+Options that are applied to external files when the environment is set to `client`. By default, `jsdom` and `happy-dom` use `client` environment, while `node` and `edge` environments use `ssr`, so these options will have no affect on files inside those environments.
+
+Usually, files inside `node_modules` are externalized, but these options also affect files in [`server.deps.external`](#server-deps-external).
+
+### deps.client.transformAssets
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Should Vitest process assets (.png, .svg, .jpg, etc) files and resolve them like Vite does in the browser.
+
+This module will have a default export equal to the path to the asset, if no query is specified.
+
+::: warning
+At the moment, this option only works with [`vmThreads`](#vmthreads) and [`vmForks`](#vmforks) pools.
+:::
+
+### deps.client.transformCss
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Should Vitest process CSS (.css, .scss, .sass, etc) files and resolve them like Vite does in the browser.
+
+If CSS files are disabled with [`css`](#css) options, this option will just silence `ERR_UNKNOWN_FILE_EXTENSION` errors.
+
+::: warning
+At the moment, this option only works with [`vmThreads`](#vmthreads) and [`vmForks`](#vmforks) pools.
+:::
+
+### deps.client.transformGlobPattern
+
+- **Type:** `RegExp | RegExp[]`
+- **Default:** `[]`
+
+Regexp pattern to match external files that should be transformed.
+
+By default, files inside `node_modules` are externalized and not transformed, unless it's CSS or an asset, and corresponding option is not disabled.
+
+::: warning
+At the moment, this option only works with [`vmThreads`](#vmthreads) and [`vmForks`](#vmforks) pools.
+:::
+
+## deps.interopDefault
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Interpret CJS module's default as named exports. Some dependencies only bundle CJS modules and don't use named exports that Node.js can statically analyze when a package is imported using `import` syntax instead of `require`. When importing such dependencies in Node environment using named exports, you will see this error:
+
+```
+import { read } from 'fs-jetpack';
+ ^^^^
+SyntaxError: Named export 'read' not found. The requested module 'fs-jetpack' is a CommonJS module, which may not support all module.exports as named exports.
+CommonJS modules can always be imported via the default export.
+```
+
+Vitest doesn't do static analysis, and cannot fail before your running code, so you will most likely see this error when running tests, if this feature is disabled:
+
+```
+TypeError: createAsyncThunk is not a function
+TypeError: default is not a function
+```
+
+By default, Vitest assumes you are using a bundler to bypass this and will not fail, but you can disable this behaviour manually, if your code is not processed.
+
+## deps.moduleDirectories
+
+- **Type:** `string[]`
+- **Default**: `['node_modules']`
+
+A list of directories that should be treated as module directories. This config option affects the behavior of [`vi.mock`](/api/vi#vi-mock): when no factory is provided and the path of what you are mocking matches one of the `moduleDirectories` values, Vitest will try to resolve the mock by looking for a `__mocks__` folder in the [root](#root) of the project.
+
+This option will also affect if a file should be treated as a module when externalizing dependencies. By default, Vitest imports external modules with native Node.js bypassing Vite transformation step.
+
+Setting this option will _override_ the default, if you wish to still search `node_modules` for packages include it along with any other options:
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ deps: {
+ moduleDirectories: ['node_modules', path.resolve('../../packages')],
+ }
+ },
+})
+```
diff --git a/config/diff.md b/config/diff.md
new file mode 100644
index 00000000..ec878917
--- /dev/null
+++ b/config/diff.md
@@ -0,0 +1,99 @@
+---
+title: diff | Config
+outline: deep
+---
+
+# diff
+
+- **Type:** `string`
+- **CLI:** `--diff=`
+
+`DiffOptions` object or a path to a module which exports `DiffOptions`. Useful if you want to customize diff display.
+
+For example, as a config object:
+
+```ts
+import { defineConfig } from 'vitest/config'
+import c from 'picocolors'
+
+export default defineConfig({
+ test: {
+ diff: {
+ aIndicator: c.bold('--'),
+ bIndicator: c.bold('++'),
+ omitAnnotationLines: true,
+ },
+ },
+})
+```
+
+Or as a module:
+
+:::code-group
+```ts [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ diff: './vitest.diff.ts',
+ },
+})
+```
+
+```ts [vitest.diff.ts]
+import type { DiffOptions } from 'vitest'
+import c from 'picocolors'
+
+export default {
+ aIndicator: c.bold('--'),
+ bIndicator: c.bold('++'),
+ omitAnnotationLines: true,
+} satisfies DiffOptions
+```
+:::
+
+## diff.expand
+
+- **Type**: `boolean`
+- **Default**: `true`
+- **CLI:** `--diff.expand=false`
+
+Expand all common lines.
+
+## diff.truncateThreshold
+
+- **Type**: `number`
+- **Default**: `0`
+- **CLI:** `--diff.truncateThreshold=`
+
+The maximum length of diff result to be displayed. Diffs above this threshold will be truncated.
+Truncation won't take effect with default value 0.
+
+## diff.truncateAnnotation
+
+- **Type**: `string`
+- **Default**: `'... Diff result is truncated'`
+- **CLI:** `--diff.truncateAnnotation=`
+
+Annotation that is output at the end of diff result if it's truncated.
+
+## diff.truncateAnnotationColor
+
+- **Type**: `DiffOptionsColor = (arg: string) => string`
+- **Default**: `noColor = (string: string): string => string`
+
+Color of truncate annotation, default is output with no color.
+
+## diff.printBasicPrototype
+
+- **Type**: `boolean`
+- **Default**: `false`
+
+Print basic prototype `Object` and `Array` in diff output
+
+## diff.maxDepth
+
+- **Type**: `number`
+- **Default**: `20` (or `8` when comparing different types)
+
+Limit the depth to recurse when printing nested objects
diff --git a/config/dir.md b/config/dir.md
new file mode 100644
index 00000000..4fa15aea
--- /dev/null
+++ b/config/dir.md
@@ -0,0 +1,12 @@
+---
+title: dir | Config
+outline: deep
+---
+
+# dir
+
+- **Type:** `string`
+- **CLI:** `--dir=`
+- **Default:** same as `root`
+
+Base directory to scan for the test files. You can specify this option to speed up test discovery if your root covers the whole project
diff --git a/config/disableconsoleintercept.md b/config/disableconsoleintercept.md
new file mode 100644
index 00000000..40c04f5f
--- /dev/null
+++ b/config/disableconsoleintercept.md
@@ -0,0 +1,20 @@
+---
+title: disableConsoleIntercept | Config
+outline: deep
+---
+
+# disableConsoleIntercept
+
+- **Type:** `boolean`
+- **CLI:** `--disableConsoleIntercept`
+- **Default:** `false`
+
+By default, Vitest automatically intercepts console logging during tests for extra formatting of test file, test title, etc.
+
+This is also required for console log preview on Vitest UI.
+
+However, disabling such interception might help when you want to debug a code with normal synchronous terminal console logging.
+
+::: warning
+This option has no effect on [browser tests](/guide/browser/) since Vitest preserves original logging in browser devtools.
+:::
diff --git a/config/env.md b/config/env.md
new file mode 100644
index 00000000..eaf3ee13
--- /dev/null
+++ b/config/env.md
@@ -0,0 +1,10 @@
+---
+title: env | Config
+outline: deep
+---
+
+# env
+
+- **Type:** `Partial`
+
+Environment variables available on `process.env` and `import.meta.env` during tests. These variables will not be available in the main process (in `globalSetup`, for example).
diff --git a/config/environment.md b/config/environment.md
new file mode 100644
index 00000000..d359278b
--- /dev/null
+++ b/config/environment.md
@@ -0,0 +1,100 @@
+---
+title: environment | Config
+---
+
+# environment
+
+- **Type:** `'node' | 'jsdom' | 'happy-dom' | 'edge-runtime' | string`
+- **Default:** `'node'`
+- **CLI:** `--environment=`
+
+The environment that will be used for testing. The default environment in Vitest
+is a Node.js environment. If you are building a web application, you can use
+browser-like environment through either [`jsdom`](https://github.com/jsdom/jsdom)
+or [`happy-dom`](https://github.com/capricorn86/happy-dom) instead.
+If you are building edge functions, you can use [`edge-runtime`](https://edge-runtime.vercel.app/packages/vm) environment
+
+::: tip
+You can also use [Browser Mode](/guide/browser/) to run integration or unit tests in the browser without mocking the environment.
+:::
+
+To define custom options for your environment, use [`environmentOptions`](/config/environmentoptions).
+
+By adding a `@vitest-environment` docblock or comment at the top of the file,
+you can specify another environment to be used for all tests in that file:
+
+Docblock style:
+
+```js
+/**
+ * @vitest-environment jsdom
+ */
+
+test('use jsdom in this test file', () => {
+ const element = document.createElement('div')
+ expect(element).not.toBeNull()
+})
+```
+
+Comment style:
+
+```js
+// @vitest-environment happy-dom
+
+test('use happy-dom in this test file', () => {
+ const element = document.createElement('div')
+ expect(element).not.toBeNull()
+})
+```
+
+For compatibility with Jest, there is also a `@jest-environment`:
+
+```js
+/**
+ * @jest-environment jsdom
+ */
+
+test('use jsdom in this test file', () => {
+ const element = document.createElement('div')
+ expect(element).not.toBeNull()
+})
+```
+
+You can also define a custom environment. When non-builtin environment is used, Vitest will try to load the file if it's relative or absolute, or a package `vitest-environment-${name}`, if the name is a bare specifier.
+
+The custom environment file should export an object with the shape of `Environment`:
+
+```ts [environment.js]
+import type { Environment } from 'vitest'
+
+export default {
+ name: 'custom',
+ viteEnvironment: 'ssr',
+ setup() {
+ // custom setup
+ return {
+ teardown() {
+ // called after all tests with this env have been run
+ }
+ }
+ }
+}
+```
+
+::: tip
+The `viteEnvironment` field corresponde to the environment defined by the [Vite Environment API](https://vite.dev/guide/api-environment#environment-api). By default, Vite exposes `client` (for the browser) and `ssr` (for the server) environments.
+:::
+
+Vitest also exposes `builtinEnvironments` through `vitest/environments` entry, in case you just want to extend it. You can read more about extending environments in [our guide](/guide/environment).
+
+::: tip
+jsdom environment exposes `jsdom` global variable equal to the current [JSDOM](https://github.com/jsdom/jsdom) instance. If you want TypeScript to recognize it, you can add `vitest/jsdom` to your `tsconfig.json` when you use this environment:
+
+```json [tsconfig.json]
+{
+ "compilerOptions": {
+ "types": ["vitest/jsdom"]
+ }
+}
+```
+:::
diff --git a/config/environmentoptions.md b/config/environmentoptions.md
new file mode 100644
index 00000000..0a8e478c
--- /dev/null
+++ b/config/environmentoptions.md
@@ -0,0 +1,34 @@
+---
+title: environmentOptions | Config
+---
+
+# environmentOptions
+
+- **Type:** `Record<'jsdom' | 'happyDOM' | string, unknown>`
+- **Default:** `{}`
+
+These options are passed to the setup method of the current [environment](/config/environment). By default, you can configure options only for `jsdom` and `happyDOM` when you use them as your test environment.
+
+## Example
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ environmentOptions: {
+ jsdom: {
+ url: 'http://localhost:3000',
+ },
+ happyDOM: {
+ width: 300,
+ height: 400,
+ },
+ },
+ },
+})
+```
+
+::: warning
+Options are scoped to their environment. For example, put jsdom options under the `jsdom` key and happy-dom options under the `happyDOM` key. This lets you mix multiple environments within the same project.
+:::
diff --git a/config/exclude.md b/config/exclude.md
new file mode 100644
index 00000000..7116ce6b
--- /dev/null
+++ b/config/exclude.md
@@ -0,0 +1,53 @@
+---
+title: exclude | Config
+---
+
+# exclude
+
+- **Type:** `string[]`
+- **Default:** `['**/node_modules/**', '**/.git/**']`
+- **CLI:** `vitest --exclude "**/excluded-file" --exclude "*/other-files/*.js"`
+
+A list of [glob patterns](https://superchupu.dev/tinyglobby/comparison) that should be excluded from your test files. These patterns are resolved relative to the [`root`](/config/root) ([`process.cwd()`](https://nodejs.org/api/process.html#processcwd) by default).
+
+Vitest uses the [`tinyglobby`](https://www.npmjs.com/package/tinyglobby) package to resolve the globs.
+
+::: warning
+This option does not affect coverage. If you need to remove certain files from the coverage report, use [`coverage.exclude`](/config/coverage#exclude).
+
+This is the only option that doesn't override your configuration if you provide it with a CLI flag. All glob patterns added via `--exclude` flag will be added to the config's `exclude`.
+:::
+
+## Example
+
+```js
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ exclude: [
+ '**/node_modules/**',
+ '**/dist/**',
+ './temp/**',
+ ],
+ },
+})
+```
+
+::: tip
+Although the CLI `exclude` option is additive, manually setting `exclude` in your config will replace the default value. To extend the default `exclude` patterns, use `configDefaults` from `vitest/config`:
+
+```js{6}
+import { configDefaults, defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ exclude: [
+ ...configDefaults.exclude,
+ 'packages/template/*',
+ './temp/**',
+ ],
+ },
+})
+```
+:::
diff --git a/config/execargv.md b/config/execargv.md
new file mode 100644
index 00000000..78991e44
--- /dev/null
+++ b/config/execargv.md
@@ -0,0 +1,15 @@
+---
+title: execArgv | Config
+outline: deep
+---
+
+# execArgv
+
+- **Type:** `string[]`
+- **Default:** `[]`
+
+Pass additional arguments to `node` in the runner worker. See [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) for more information.
+
+:::warning
+Be careful when using, it as some options may crash worker, e.g. `--prof`, `--title`. See https://github.com/nodejs/node/issues/41103.
+:::
diff --git a/config/expandsnapshotdiff.md b/config/expandsnapshotdiff.md
new file mode 100644
index 00000000..47dc59b2
--- /dev/null
+++ b/config/expandsnapshotdiff.md
@@ -0,0 +1,12 @@
+---
+title: expandSnapshotDiff | Config
+outline: deep
+---
+
+# expandSnapshotDiff
+
+- **Type:** `boolean`
+- **CLI:** `--expandSnapshotDiff`, `--expand-snapshot-diff`
+- **Default:** `false`
+
+Show full diff when snapshot fails instead of a patch.
diff --git a/config/expect.md b/config/expect.md
new file mode 100644
index 00000000..1090f171
--- /dev/null
+++ b/config/expect.md
@@ -0,0 +1,43 @@
+---
+title: expect | Config
+outline: deep
+---
+
+# expect
+
+- **Type:** `ExpectOptions`
+
+## expect.requireAssertions
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+The same as calling [`expect.hasAssertions()`](/api/expect#expect-hasassertions) at the start of every test. This makes sure that no test will pass accidentally.
+
+::: tip
+This only works with Vitest's `expect`. If you use `assert` or `.should` assertions, they will not count, and your test will fail due to the lack of expect assertions.
+
+You can change the value of this by calling `vi.setConfig({ expect: { requireAssertions: false } })`. The config will be applied to every subsequent `expect` call until the `vi.resetConfig` is called manually.
+:::
+
+::: warning
+When you run tests with `sequence.concurrent` and `expect.requireAssertions` set to `true`, you should use [local expect](/guide/test-context.html#expect) instead of the global one. Otherwise, this may cause false negatives in [some situations (#8469)](https://github.com/vitest-dev/vitest/issues/8469).
+:::
+
+## expect.poll
+
+Global configuration options for [`expect.poll`](/api/expect#poll). These are the same options you can pass down to `expect.poll(condition, options)`.
+
+### expect.poll.interval
+
+- **Type:** `number`
+- **Default:** `50`
+
+Polling interval in milliseconds
+
+### expect.poll.timeout
+
+- **Type:** `number`
+- **Default:** `1000`
+
+Polling timeout in milliseconds
diff --git a/config/experimental.md b/config/experimental.md
new file mode 100644
index 00000000..984763a8
--- /dev/null
+++ b/config/experimental.md
@@ -0,0 +1,185 @@
+---
+title: experimental | Config
+outline: deep
+---
+
+# experimental
+
+## experimental.fsModuleCache 4.0.11 {#experimental-fsmodulecache}
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Enabling this option allows Vitest to keep cached modules on the file system, making tests run faster between reruns.
+
+You can delete the old cache by running [`vitest --clearCache`](/guide/cli#clearcache).
+
+::: warning BROWSER SUPPORT
+At the moment, this option does not affect [the browser](/guide/browser/).
+:::
+
+You can debug if your modules are cached by running vitest with a `DEBUG=vitest:cache:fs` environment variable:
+
+```shell
+DEBUG=vitest:cache:fs vitest --experimental.fsModuleCache
+```
+
+### Known Issues
+
+Vitest creates persistent file hash based on file content, its id, vite's environment configuration and coverage status. Vitest tries to use as much information it has about the configuration, but it is still incomplete. At the moment, it is not possible to track your plugin options because there is no standard interface for it.
+
+If you have a plugin that relies on things outside the file content or the public configuration (like reading another file or a folder), it's possible that the cache will get stale. To workaround that, you can define a [cache key generator](/api/advanced/plugin#definecachekeygenerator) to specify dynamic option or to opt-out of caching for that module:
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ plugins: [
+ {
+ name: 'vitest-cache',
+ configureVitest({ experimental_defineCacheKeyGenerator }) {
+ experimental_defineCacheKeyGenerator(({ id, sourceCode }) => {
+ // never cache this id
+ if (id.includes('do-not-cache')) {
+ return false
+ }
+
+ // cache this file based on the value of a dynamic variable
+ if (sourceCode.includes('myDynamicVar')) {
+ return process.env.DYNAMIC_VAR_VALUE
+ }
+ })
+ }
+ }
+ ],
+ test: {
+ experimental: {
+ fsModuleCache: true,
+ },
+ },
+})
+```
+
+If you are a plugin author, consider defining a [cache key generator](/api/advanced/plugin#definecachekeygenerator) in your plugin if it can be registered with different options that affect the transform result.
+
+On the other hand, if your plugin should not affect the cache key, you can opt-out by setting `api.vitest.experimental.ignoreFsModuleCache` to `true`:
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ plugins: [
+ {
+ name: 'vitest-cache',
+ api: {
+ vitest: {
+ experimental: {
+ ignoreFsModuleCache: true,
+ },
+ },
+ },
+ },
+ ],
+ test: {
+ experimental: {
+ fsModuleCache: true,
+ },
+ },
+})
+```
+
+Note that you can still define the cache key generator even the plugin opt-out of module caching.
+
+## experimental.fsModuleCachePath 4.0.11 {#experimental-fsmodulecachepath}
+
+- **Type:** `string`
+- **Default:** `'node_modules/.experimental-vitest-cache'`
+
+Directory where the file system cache is located.
+
+By default, Vitest will try to find the workspace root and store the cache inside the `node_modules` folder. The root is based on your package manager's lockfile (for example, `.package-lock.json`, `.yarn-state.yml`, `.pnpm/lock.yaml` and so on).
+
+At the moment, Vitest ignores the [test.cache.dir](/config/cache) or [cacheDir](https://vite.dev/config/shared-options#cachedir) options completely and creates a separate folder.
+
+## experimental.openTelemetry 4.0.11 {#experimental-opentelemetry}
+
+- **Type:**
+
+```ts
+interface OpenTelemetryOptions {
+ enabled: boolean
+ /**
+ * A path to a file that exposes an OpenTelemetry SDK.
+ */
+ sdkPath?: string
+}
+```
+
+- **Default:** `{ enabled: false }`
+
+This option controls [OpenTelemetry](https://opentelemetry.io/) support. Vitest imports the SDK file in the main thread and before every test file, if `enabled` is set to `true`.
+
+::: danger PERFORMANCE CONCERNS
+OpenTelemetry may significantly impact Vitest performance; enable it only for local debugging.
+:::
+
+You can use a [custom service](/guide/open-telemetry) together with Vitest to pinpoint which tests or files are slowing down your test suite.
+
+::: warning BROWSER SUPPORT
+At the moment, Vitest does not start any spans when running in [the browser](/guide/browser/).
+:::
+
+An `sdkPath` is resolved relative to the [`root`](/config/root) of the project and should point to a module that exposes a started SDK instance as a default export. For example:
+
+::: code-group
+```js [otel.js]
+import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
+import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'
+import { NodeSDK } from '@opentelemetry/sdk-node'
+
+const sdk = new NodeSDK({
+ serviceName: 'vitest',
+ traceExporter: new OTLPTraceExporter(),
+ instrumentations: [getNodeAutoInstrumentations()],
+})
+
+sdk.start()
+export default sdk
+```
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ experimental: {
+ openTelemetry: {
+ enabled: true,
+ sdkPath: './otel.js',
+ },
+ },
+ },
+})
+```
+:::
+
+::: warning
+It's important that Node can process `sdkPath` content because it is not transformed by Vitest. See [the guide](/guide/open-telemetry) on how to work with OpenTelemetry inside of Vitest.
+:::
+
+## experimental.printImportBreakdown 4.0.15 {#experimental-printimportbreakdown}
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Show import duration breakdown after tests have finished running. This option only works with [`default`](/guide/reporters#default), [`verbose`](/guide/reporters#verbose), or [`tree`](/guide/reporters#tree) reporters.
+
+- Self: the time it took to import the module, excluding static imports;
+- Total: the time it took to import the module, including static imports. Note that this does not include `transform` time of the current module.
+
+
+
+Note that if the file path is too long, Vitest will truncate it at the start until it fits 45 character limit.
+
+::: info
+[Vitest UI](/guide/ui#import-breakdown) shows a breakdown of imports automatically if at least one file took longer than 500 milliseconds to load. You can manually set this option to `false` to disable this.
+:::
diff --git a/config/faketimers.md b/config/faketimers.md
new file mode 100644
index 00000000..a389b451
--- /dev/null
+++ b/config/faketimers.md
@@ -0,0 +1,56 @@
+---
+title: fakeTimers | Config
+outline: deep
+---
+
+# fakeTimers
+
+- **Type:** `FakeTimerInstallOpts`
+
+Options that Vitest will pass down to [`@sinon/fake-timers`](https://www.npmjs.com/package/@sinonjs/fake-timers) when using [`vi.useFakeTimers()`](/api/vi#vi-usefaketimers).
+
+## fakeTimers.now
+
+- **Type:** `number | Date`
+- **Default:** `Date.now()`
+
+Installs fake timers with the specified Unix epoch.
+
+## fakeTimers.toFake
+
+- **Type:** `('setTimeout' | 'clearTimeout' | 'setImmediate' | 'clearImmediate' | 'setInterval' | 'clearInterval' | 'Date' | 'nextTick' | 'hrtime' | 'requestAnimationFrame' | 'cancelAnimationFrame' | 'requestIdleCallback' | 'cancelIdleCallback' | 'performance' | 'queueMicrotask')[]`
+- **Default:** everything available globally except `nextTick` and `queueMicrotask`
+
+An array with names of global methods and APIs to fake.
+
+To only mock `setTimeout()` and `nextTick()`, specify this property as `['setTimeout', 'nextTick']`.
+
+Mocking `nextTick` is not supported when running Vitest inside `node:child_process` by using `--pool=forks`. NodeJS uses `process.nextTick` internally in `node:child_process` and hangs when it is mocked. Mocking `nextTick` is supported when running Vitest with `--pool=threads`.
+
+## fakeTimers.loopLimit
+
+- **Type:** `number`
+- **Default:** `10_000`
+
+The maximum number of timers that will be run when calling [`vi.runAllTimers()`](/api/vi#vi-runalltimers).
+
+## fakeTimers.shouldAdvanceTime
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Tells @sinonjs/fake-timers to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change in the real system time).
+
+## fakeTimers.advanceTimeDelta
+
+- **Type:** `number`
+- **Default:** `20`
+
+Relevant only when using with `shouldAdvanceTime: true`. increment mocked time by advanceTimeDelta ms every advanceTimeDelta ms change in the real system time.
+
+## fakeTimers.shouldClearNativeTimers
+
+- **Type:** `boolean`
+- **Default:** `true`
+
+Tells fake timers to clear "native" (i.e. not fake) timers by delegating to their respective handlers. When disabled, it can lead to potentially unexpected behavior if timers existed prior to starting fake timers session.
diff --git a/config/fileparallelism.md b/config/fileparallelism.md
new file mode 100644
index 00000000..20f1143f
--- /dev/null
+++ b/config/fileparallelism.md
@@ -0,0 +1,16 @@
+---
+title: fileParallelism | Config
+outline: deep
+---
+
+# fileParallelism
+
+- **Type:** `boolean`
+- **Default:** `true`
+- **CLI:** `--no-file-parallelism`, `--fileParallelism=false`
+
+Should all test files run in parallel. Setting this to `false` will override `maxWorkers` option to `1`.
+
+::: tip
+This option doesn't affect tests running in the same file. If you want to run those in parallel, use `concurrent` option on [describe](/api/#describe-concurrent) or via [a config](#sequence-concurrent).
+:::
diff --git a/config/forcereruntriggers.md b/config/forcereruntriggers.md
new file mode 100644
index 00000000..342143e1
--- /dev/null
+++ b/config/forcereruntriggers.md
@@ -0,0 +1,24 @@
+---
+title: forceRerunTriggers | Config
+outline: deep
+---
+
+# forceRerunTriggers
+
+- **Type**: `string[]`
+- **Default:** `['**/package.json/**', '**/vitest.config.*/**', '**/vite.config.*/**']`
+
+Glob pattern of file paths that will trigger the whole suite rerun. When paired with the `--changed` argument will run the whole test suite if the trigger is found in the git diff.
+
+Useful if you are testing calling CLI commands, because Vite cannot construct a module graph:
+
+```ts
+test('execute a script', async () => {
+ // Vitest cannot rerun this test, if content of `dist/index.js` changes
+ await execa('node', ['dist/index.js'])
+})
+```
+
+::: tip
+Make sure that your files are not excluded by [`server.watch.ignored`](https://vitejs.dev/config/server-options.html#server-watch).
+:::
diff --git a/config/globals.md b/config/globals.md
new file mode 100644
index 00000000..1dcf7ef0
--- /dev/null
+++ b/config/globals.md
@@ -0,0 +1,46 @@
+---
+title: globals | Config
+---
+
+# globals
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **CLI:** `--globals`, `--no-globals`, `--globals=false`
+
+By default, `vitest` does not provide global APIs for explicitness. If you prefer to use the APIs globally like Jest, you can pass the `--globals` option to CLI or add `globals: true` in the config.
+
+```js
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ globals: true,
+ },
+})
+```
+
+::: tip
+Note that some libraries, e.g., `@testing-library/react`, rely on globals being present to perform auto cleanup.
+:::
+
+To get TypeScript working with the global APIs, add `vitest/globals` to the `types` field in your `tsconfig.json`:
+
+```json [tsconfig.json]
+{
+ "compilerOptions": {
+ "types": ["vitest/globals"]
+ }
+}
+```
+
+If you have redefined your [`typeRoots`](https://www.typescriptlang.org/tsconfig/#typeRoots) to include additional types in your compilation, you will need to add back the `node_modules` to make `vitest/globals` discoverable:
+
+```json [tsconfig.json]
+{
+ "compilerOptions": {
+ "typeRoots": ["./types", "./node_modules/@types", "./node_modules"],
+ "types": ["vitest/globals"]
+ }
+}
+```
diff --git a/config/globalsetup.md b/config/globalsetup.md
new file mode 100644
index 00000000..74370456
--- /dev/null
+++ b/config/globalsetup.md
@@ -0,0 +1,67 @@
+---
+title: globalSetup | Config
+outline: deep
+---
+
+# globalSetup
+
+- **Type:** `string | string[]`
+
+Path to global setup files, relative to project root.
+
+A global setup file can either export named functions `setup` and `teardown` or a `default` function that returns a teardown function ([example](https://github.com/vitest-dev/vitest/blob/main/test/global-setup/vitest.config.ts)).
+
+::: info
+Multiple globalSetup files are possible. setup and teardown are executed sequentially with teardown in reverse order.
+:::
+
+::: warning
+Global setup runs only if there is at least one running test. This means that global setup might start running during watch mode after test file is changed (the test file will wait for global setup to finish before running).
+
+Beware that the global setup is running in a different global scope, so your tests don't have access to variables defined here. However, you can pass down serializable data to tests via [`provide`](#provide) method:
+
+:::code-group
+```ts [example.test.js]
+import { inject } from 'vitest'
+
+inject('wsPort') === 3000
+```
+```ts [globalSetup.ts 3.0.0]
+import type { TestProject } from 'vitest/node'
+
+export default function setup(project: TestProject) {
+ project.provide('wsPort', 3000)
+}
+
+declare module 'vitest' {
+ export interface ProvidedContext {
+ wsPort: number
+ }
+}
+```
+```ts [globalSetup.ts 2.0.0]
+import type { GlobalSetupContext } from 'vitest/node'
+
+export default function setup({ provide }: GlobalSetupContext) {
+ provide('wsPort', 3000)
+}
+
+declare module 'vitest' {
+ export interface ProvidedContext {
+ wsPort: number
+ }
+}
+```
+:::
+
+Since Vitest 3, you can define a custom callback function to be called when Vitest reruns tests. If the function is asynchronous, the runner will wait for it to complete before executing tests. Note that you cannot destruct the `project` like `{ onTestsRerun }` because it relies on the context.
+
+```ts [globalSetup.ts]
+import type { TestProject } from 'vitest/node'
+
+export default function setup(project: TestProject) {
+ project.onTestsRerun(async () => {
+ await restartDb()
+ })
+}
+```
diff --git a/config/hideskippedtests.md b/config/hideskippedtests.md
new file mode 100644
index 00000000..9f63b0c5
--- /dev/null
+++ b/config/hideskippedtests.md
@@ -0,0 +1,12 @@
+---
+title: hideSkippedTests | Config
+outline: deep
+---
+
+# hideSkippedTests
+
+- **Type:** `boolean`
+- **CLI:** `--hideSkippedTests`, `--hide-skipped-tests`
+- **Default:** `false`
+
+Hide logs for skipped tests
diff --git a/config/hooktimeout.md b/config/hooktimeout.md
new file mode 100644
index 00000000..b922a635
--- /dev/null
+++ b/config/hooktimeout.md
@@ -0,0 +1,12 @@
+---
+title: hookTimeout | Config
+outline: deep
+---
+
+# hookTimeout
+
+- **Type:** `number`
+- **Default:** `10_000` in Node.js, `30_000` if `browser.enabled` is `true`
+- **CLI:** `--hook-timeout=10000`, `--hookTimeout=10000`
+
+Default timeout of a hook in milliseconds. Use `0` to disable timeout completely.
diff --git a/config/include-source.md b/config/include-source.md
new file mode 100644
index 00000000..e1ee0ce8
--- /dev/null
+++ b/config/include-source.md
@@ -0,0 +1,119 @@
+---
+title: includeSource | Config
+---
+
+# includeSource
+
+- **Type:** `string[]`
+- **Default:** `[]`
+
+A list of [glob patterns](https://superchupu.dev/tinyglobby/comparison) that match your [in-source test files](/guide/in-source). These patterns are resolved relative to the [`root`](/config/root) ([`process.cwd()`](https://nodejs.org/api/process.html#processcwd) by default).
+
+When defined, Vitest will run all matched files that have `import.meta.vitest` inside.
+
+::: warning
+Vitest performs a simple text-based inclusion check on source files. If a file contains `import.meta.vitest`, even in a comment, it will be matched as an in-source test file.
+:::
+
+Vitest uses the [`tinyglobby`](https://www.npmjs.com/package/tinyglobby) package to resolve the globs.
+
+## Example
+
+```js
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ includeSource: ['src/**/*.{js,ts}'],
+ },
+})
+```
+
+Then you can write tests inside your source files:
+
+```ts [src/index.ts]
+export function add(...args: number[]) {
+ return args.reduce((a, b) => a + b, 0)
+}
+
+// #region in-source test suites
+if (import.meta.vitest) {
+ const { it, expect } = import.meta.vitest
+ it('add', () => {
+ expect(add()).toBe(0)
+ expect(add(1)).toBe(1)
+ expect(add(1, 2, 3)).toBe(6)
+ })
+}
+// #endregion
+```
+
+For your production build, you need to replace the `import.meta.vitest` with `undefined`, letting the bundler do the dead code elimination.
+
+::: code-group
+```js [vite.config.ts]
+import { defineConfig } from 'vite'
+
+export default defineConfig({
+ define: { // [!code ++]
+ 'import.meta.vitest': 'undefined', // [!code ++]
+ }, // [!code ++]
+})
+```
+```js [rolldown.config.js]
+import { defineConfig } from 'rolldown/config'
+
+export default defineConfig({
+ transform: {
+ define: { // [!code ++]
+ 'import.meta.vitest': 'undefined', // [!code ++]
+ }, // [!code ++]
+ },
+})
+```
+```js [rollup.config.js]
+import replace from '@rollup/plugin-replace' // [!code ++]
+
+export default {
+ plugins: [
+ replace({ // [!code ++]
+ 'import.meta.vitest': 'undefined', // [!code ++]
+ }) // [!code ++]
+ ],
+ // other options
+}
+```
+```js [build.config.js]
+import { defineBuildConfig } from 'unbuild'
+
+export default defineBuildConfig({
+ replace: { // [!code ++]
+ 'import.meta.vitest': 'undefined', // [!code ++]
+ }, // [!code ++]
+ // other options
+})
+```
+```js [webpack.config.js]
+const webpack = require('webpack')
+
+module.exports = {
+ plugins: [
+ new webpack.DefinePlugin({ // [!code ++]
+ 'import.meta.vitest': 'undefined', // [!code ++]
+ })// [!code ++]
+ ],
+}
+```
+:::
+
+::: tip
+To get TypeScript support for `import.meta.vitest`, add `vitest/importMeta` to your `tsconfig.json`:
+
+```json [tsconfig.json]
+{
+ "compilerOptions": {
+ "types": ["vitest/importMeta"]
+ }
+}
+```
+:::
diff --git a/config/include.md b/config/include.md
new file mode 100644
index 00000000..41373db9
--- /dev/null
+++ b/config/include.md
@@ -0,0 +1,71 @@
+---
+title: include | Config
+---
+
+# include
+
+- **Type:** `string[]`
+- **Default:** `['**/*.{test,spec}.?(c|m)[jt]s?(x)']`
+- **CLI:** `vitest [...include]`, `vitest **/*.test.js`
+
+A list of [glob patterns](https://superchupu.dev/tinyglobby/comparison) that match your test files. These patterns are resolved relative to the [`root`](/config/root) ([`process.cwd()`](https://nodejs.org/api/process.html#processcwd) by default).
+
+Vitest uses the [`tinyglobby`](https://www.npmjs.com/package/tinyglobby) package to resolve the globs.
+
+::: tip NOTE
+When using coverage, Vitest automatically adds test files `include` patterns to coverage's default `exclude` patterns. See [`coverage.exclude`](/config/coverage#exclude).
+:::
+
+## Example
+
+```js
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ include: [
+ './test',
+ './**/*.{test,spec}.tsx?',
+ ],
+ },
+})
+```
+
+Vitest provides reasonable defaults, so normally you wouldn't override them. A good example of defining `include` is for [test projects](/guide/projects):
+
+```js{8,12} [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ name: 'unit',
+ include: ['./test/unit/*.test.js'],
+ },
+ {
+ name: 'e2e',
+ include: ['./test/e2e/*.test.js'],
+ },
+ ],
+ },
+})
+```
+
+::: warning
+This option will override Vitest defaults. If you just want to extend them, use `configDefaults` from `vitest/config`:
+
+```js{6}
+import { configDefaults, defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ include: [
+ ...configDefaults.include,
+ './test',
+ './**/*.{test,spec}.tsx?',
+ ],
+ },
+})
+```
+:::
diff --git a/config/includetasklocation.md b/config/includetasklocation.md
new file mode 100644
index 00000000..312c6bb1
--- /dev/null
+++ b/config/includetasklocation.md
@@ -0,0 +1,22 @@
+---
+title: includeTaskLocation | Config
+outline: deep
+---
+
+# includeTaskLocation
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Should `location` property be included when Vitest API receives tasks in [reporters](#reporters). If you have a lot of tests, this might cause a small performance regression.
+
+The `location` property has `column` and `line` values that correspond to the `test` or `describe` position in the original file.
+
+This option will be auto-enabled if you don't disable it explicitly, and you are running Vitest with:
+- [Vitest UI](/guide/ui)
+- or using the [Browser Mode](/guide/browser/) without [headless](/guide/browser/#headless) mode
+- or using [HTML Reporter](/guide/reporters#html-reporter)
+
+::: tip
+This option has no effect if you do not use custom code that relies on this.
+:::
diff --git a/config/index.md b/config/index.md
index ee5b3e25..24616e47 100644
--- a/config/index.md
+++ b/config/index.md
@@ -12,12 +12,11 @@ outline: deep
要配置 Vitest 本身,请在我们的 Vite 配置中添加 `test` 属性。如果我们是从 `vite` 本身导入 `defineConfig`,我们还需要在配置文件顶部使用 [三斜杠指令](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) 添加对 Vitest 类型引用。
-::: details 打开配置示例
-使用 `vite` 中的 `defineConfig` 时使用以下步骤:
+
+If you are not using `vite`, add `defineConfig` imported from `vitest/config` to your config file:
-```ts [vite.config.js]
-///
-import { defineConfig } from 'vite'
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
@@ -25,10 +24,10 @@ export default defineConfig({
},
})
```
+
+If you have a `vite` config already, you can add `/// ` to include the `test` types:
-`` 将在 Vitest 4 中停止工作,但我们已经可以开始迁移到 `vitest/config`:
-
-```ts [vite.config.js]
+```js [vite.config.js]
///
import { defineConfig } from 'vite'
@@ -39,21 +38,9 @@ export default defineConfig({
})
```
-使用 `vitest/config` 中的 `defineConfig` 时应遵循以下步骤:
-
-```ts [vitest.config.js]
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- // ... 在此指定选项。
- },
-})
-```
-
-我们可以检索 Vitest 的默认选项,以便在需要时扩展它们:
+You can retrieve Vitest's default options to expand them if needed:
-```ts [vitest.config.js]
+```js [vitest.config.js]
import { configDefaults, defineConfig } from 'vitest/config'
export default defineConfig({
@@ -65,7 +52,7 @@ export default defineConfig({
当使用单独的 `vitest.config.js` 时,我们还可以根据需要从另一个配置文件扩展 Vite 的选项:
-```ts [vitest.config.js]
+```js [vitest.config.js]
import { defineConfig, mergeConfig } from 'vitest/config'
import viteConfig from './vite.config'
@@ -78,7 +65,7 @@ export default mergeConfig(viteConfig, defineConfig({
如果我们的 Vite 配置定义为一个函数,我们可以像这样定义配置:
-```ts [vitest.config.js]
+```js [vitest.config.js]
import { defineConfig, mergeConfig } from 'vitest/config'
import viteConfig from './vite.config'
@@ -91,2371 +78,8 @@ export default defineConfig(configEnv => mergeConfig(
})
))
```
-:::
-
-::: warning
-本页上列出的 _所有选项_ 都位于配置内的 `test` 属性内:
-
-```ts [vitest.config.js]
-export default defineConfig({
- test: {
- exclude: [],
- },
-})
-```
由于 Vitest 使用 Vite 的配置,我们也可以使用 [Vite](https://vitejs.dev/config/) 中的任何配置选项。例如,使用 `define` 来定义全局变量,或者使用 `resolve.alias` 来定义别名——这些选项应该在顶级定义,而不是在 `test` 属性内部。
-在 [项目](/guide/projects) 配置里不被支持的选项,会在旁边标注 。这表示这些选项只能在 Vitest 的根配置中进行设置。
-:::
-
-### include
-
-- **类型:** `string[]`
-- **默认值:** `['**/*.{test,spec}.?(c|m)[jt]s?(x)']`
-
-匹配包含测试文件的 glob 规则。
-
-::: tip NOTE
-使用 coverage 时,Vitest 会自动将测试文件的 `include` 模式添加到 coverage 的默认 `exclude` 模式中。请参见 [`coverage.exclude`](#coverage-exclude)。
-:::
-
-### exclude
-
-- **类型:** `string[]`
-- **默认值:** `['**/node_modules/**', '**/.git/**']`
-- **命令行终端:** `vitest --exclude "**/excluded-file" --exclude "*/other-files/*.js"`
-
-匹配排除测试文件的 glob 规则。
-
-### includeSource
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-
-包括源代码中的测试文件的通配符。
-
-当定义时,Vitest 将运行所有包含 `import.meta.vitest` 的匹配文件。
-
-### name
-
-- **类型:** `string | { label: string, color?: LabelColor }`
-
-你可以为测试项目或 Vitest 进程指定一个自定义名称,这个名称会在命令行界面(CLI)和用户界面(UI)中显示,同时也能通过 Node.js API 中的 [`project.name`](/advanced/api/test-project#name) 获取。
-
-此外,如果你提供一个包含 color 属性的对象,还可以自定义 CLI 和 UI 中显示名称的颜色。
-
-### server {#server}
-
-- **类型:** `{ sourcemap?, deps?, ... }`
-- **版本:** Since Vitest 0.34.0
-
-Vite-Node 服务端选项。
-
-#### server.sourcemap
-
-- **类型:** `'inline' | boolean`
-- **默认值:** `'inline'`
-
-通过内联方式注入到模块。
-
-#### server.debug
-
-- **类型:** `{ dumpModules?, loadDumppedModules? }`
-
-Vite-Node 调试器选项。
-
-#### server.debug.dumpModules
-
-- **类型:** `boolean | string`
-
-将转换后的模块转储到文件系统。传递字符串将转储到指定路径。
-
-#### server.debug.loadDumppedModules
-
-- **类型:** `boolean`
-
-不管是否存在,就从文件系统中读取转储的模块。通过修改文件系统的转储结果对于调试会有帮助。
-
-#### server.deps
-
-- **类型:** `{ external?, inline?, ... }`
-
-对依赖关系进行内联或外联的处理
-
-#### server.deps.external
-
-- **类型:** `(string | RegExp)[]`
-- **默认值:** `[/\/node_modules\//]`
-
-外部化(Externalize)意味着 Vite 将绕过原生 Node 的包。外部化依赖不会应用于 Vite 的转换器和解析器,因此它们不支持重新加载时的 HMR。 `node_modules` 下的所有包都被外部化。
-
-这些选项支持在 `node_modules` 中编写的包名称或在 [`deps.moduleDirectories`](#deps-moduledirectories) 中指定的包名称。例如,位于 `packages/some-name` 内的包`@company/some-name` 应指定为 `some-name`,并且 `packages` 应包含在 `deps.moduleDirectories` 中。基本上,Vitest 总是检查文件路径,而不是实际的包名称。
-
-如果使用正则匹配,Vitest 会在 _file path_ 上调用它,而不是包名称。
-
-#### server.deps.inline
-
-- **类型:** `(string | RegExp)[] | true`
-- **默认值:** `[]`
-
-Vite 将处理内联模块。这可能有助于处理以 ESM 格式传送 `.js` 的包(Node 无法处理)。
-
-如果设置为 `true`,则每个依赖项都将被内联。默认情况下,将内联 [`ssr.noExternal`](https://cn.vitejs.dev/guide/ssr.html#ssr-externals) 中指定的所有依赖项。
-
-#### server.deps.fallbackCJS
-
-- **类型** `boolean`
-- **默认值:** `false`
-
-当依赖项是有效的 ESM 包时,尝试根据路径猜测 cjs 版本。如果依赖项是有错误的 ESM 文件,这可能会有所帮助。
-
-如果包在 ESM 和 CJS 模式下具有不同的逻辑,这可能会导致一些错位。
-
-#### server.deps.cacheDir
-
-- **类型** `string`
-- **默认值**: `'node_modules/.vite'`
-
-保存缓存文件的目录。
-
-### deps
-
-- **类型:** `{ optimizer?, ... }`
-
-处理依赖关系解析。
-
-#### deps.optimizer {#deps-optimizer}
-
-- **类型:** `{ ssr?, client? }`
-- **参考:** [依赖优化选项](https://vitejs.dev/config/dep-optimization-options.html)
-
-启用依赖优化。如果你有很多测试,这可能会提高它们的性能。
-
-当 Vitest 遇到 `include` 中列出的外部库时,它将使用 esbuild 打包到单个文件中,并作为整个模块导入。这很好,原因如下:
-
-- 导入大量导入的包很昂贵。通过将它们捆绑到一个文件中,我们可以节省大量时间
-- 导入 UI 库很昂贵,因为它们并不意味着在 Node.js 中运行
-- 你的 `alias` 配置现在在捆绑包中得到处理
-- 测试中的代码更接近于它在浏览器中的运行方式
-
-仅当包名出现在 `deps.optimizer?.[mode].include` 中时,才会被预打包(如 Svelte 等插件会自动填充)。完整选项见 [Vite 文档](https://cn.vitejs.dev/config/dep-optimization-options.html)(Vitest 暂不支持 `disable` 与 `noDiscovery`)。
-
-默认策略:
-
-- `jsdom` / `happy-dom` → `optimizer.client`
-
-- `node` / `edge` → `optimizer.ssr`
-
-此选项还继承了你的 `optimizeDeps` 配置(对于 web 环境, Vitest 将会继承 `optimizeDeps`,对于 ssr 则是 `ssr.optimizeDeps`)。如果你在 `deps.experimentalOptimizer` 中重新定义 `include`/`exclude`/`entries` 选项,它将在运行测试时覆盖你的 `optimizeDeps`。如果它们在 `exclude` 中配置,Vitest 会自动从 `include` 中删除相同的选项。
-
-::: tip
-你将无法编辑用于调试的 `node_modules` 代码,因为该代码实际上位于你的 `cacheDir` 或 `test.cache.dir` 目录中。如果你想使用 `console.log` 语句进行调试,请直接编辑它或使用 `deps.experimentalOptimizer?.[mode].force` 选项强制重新绑定。
-:::
-
-#### deps.optimizer.{mode}.enabled
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-启用依赖优化。
-
-#### deps.client {#deps-client}
-
-#### deps.web 0.34.2+
-
-仅当环境设为 `client` 时,下列选项才会作用于外部文件。
-
-默认映射:
-
-- `jsdom`、`happy-dom` → `client`
-
-- `node`、`edge` → `ssr`
-
-故这些选项对后者中的文件无效。
-
-- **类型:** `{ transformAssets?, ... }`
-
-当转换模式设置为 `web` 时应用于外部文件的选项。默认情况下,`jsdom` 和 `happy-dom` 使用 `web` 模式,而 `node` 和 `edge` 环境使用 `ssr` 转换模式,因此这些选项不会影响这些环境中的文件。
-
-通常,`node_modules` 内的文件是外部化的,但这些选项也会影响 [`server.deps.external`](#server-deps-external) 中的文件。
-
-#### deps.client.transformAssets
-
-- **类型:** `boolean`
-- **默认值:** `true`
-
-Vitest 是否应该像 Vite 在浏览器中一样处理静态资源(.png、.svg、.jpg 等)文件并解析它们。
-
-如果未指定查询,此模块将具有等同于静态资源路径的默认导出。
-
-::: warning
-目前,此选项适用于 [`vmThreads`](#vmthreads) 和 [`vmForks`](#vmForks) 池。
-:::
-
-#### deps.client.transformCss
-
-- **类型:** `boolean`
-- **默认值:** `true`
-
-Vitest 是否应该像 Vite 在浏览器中一样处理静态资源(.css, .scss, .sass 等)文件并解析它们。
-
-如果使用 [`css`](#css) 选项禁用 CSS 文件,则此选项只会消除 `ERR_UNKNOWN_FILE_EXTENSION` 错误。
-
-::: warning
-目前,此选项仅适用于 [`vmThreads`](#vmthreads) 和 [`vmForks`](#vmForks) 池。
-:::
-
-#### deps.client.transformGlobPattern
-
-- **类型:** `RegExp | RegExp[]`
-- **默认值:** `[]`
-
-正则表达式模式匹配应转换的外部文件。
-
-默认情况下,`node_modules` 内的文件是外部化的,不会被转换,除非它是 CSS 或静态资源,并且相应的选项不会被禁用。
-
-::: warning
-目前,此选项仅适用于 [`vmThreads`](#vmthreads) 和 [`vmForks`](#vmForks) 池。
-:::
-
-#### deps.interopDefault
-
-- **类型:** `boolean`
-- **默认值:** `true`
-
-将 CJS 模块的默认值视为命名导出。某些依赖项仅捆绑 CJS 模块,不使用命名导出,Node.js 可以在使用 `import` 语法而不是 `require` 导入包时对其进行静态分析。使用命名导出在 Node 环境中导入此类依赖项时,你将看到此错误:
-
-```
-import { read } from 'fs-jetpack';
- ^^^^
-SyntaxError: Named export 'read' not found. The requested module 'fs-jetpack' is a CommonJS module, which may not support all module.exports as named exports.
-CommonJS modules can always be imported via the default export.
-```
-
-Vitest 不进行静态分析,并且不会在你运行代码之前失败,因此当该特性禁用时你在运行测试时很可能会看到此错误:
-
-```
-TypeError: createAsyncThunk is not a function
-TypeError: default is not a function
-```
-
-默认情况下,Vitest 假设你使用的是打包工具来绕过此问题,不会失败,但如果代码未被处理,你可以手动禁用此行为。
-
-#### deps.moduleDirectories
-
-- **类型:** `string[]`
-- **默认值**: `['node_modules']`
-
-配置一个视为模块目录的目录列表。此配置选项会影响 [`vi.mock`](/api/vi#vi-mock) 的行为:当未提供工厂并且你正在模拟的路径与 `moduleDirectories` 值之一匹配时,Vitest 将尝试 通过在项目的 [root](/config/#root) 中查找 `__mocks__` 文件夹来解析 mock。
-
-此选项还将影响在外部化依赖项时是否应将文件视为模块。默认情况下,Vitest 绕过 Vite 转换步骤导入带有原生 Node.js 的外部模块。
-
-设置此选项将 _覆盖_ 默认值,如果你仍希望搜索 `node_modules` 包包括它连同任何其他选项:
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- deps: {
- moduleDirectories: ['node_modules', path.resolve('../../packages')],
- },
- },
-})
-```
-
-### runner
-
-- **类型**: `VitestRunnerConstructor`
-- **默认值**: 运行测试时为`node`,运行基准测试时为 `benchmark`
-
-自定义测试运行器的路径。这是一项高级功能,应与自定义库运行器一起使用。你可以在 [文档](/advanced/runner) 中阅读更多相关信息。
-
-### benchmark
-
-- **类型:** `{ include?, exclude?, ... }`
-
-运行 `vitest bench` 时使用的选项。
-
-#### benchmark.include
-
-- **类型:** `string[]`
-- **默认值:** `['**/*.{bench,benchmark}.?(c|m)[jt]s?(x)']`
-
-匹配包含基准测试文件的 glob 规则。
-
-#### benchmark.exclude
-
-- **类型:** `string[]`
-- **默认值:** `['node_modules', 'dist', '.idea', '.git', '.cache']`
-
-匹配排除基准测试文件的 glob 规则。
-
-#### benchmark.includeSource
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-
-匹配包含内联基准测试文件的 glob 规则。此选项类似于 [`includeSource`](#includesource)。
-
-定义后,Vitest 将运行所有匹配的文件,其中包含 `import.meta.vitest`。
-
-#### benchmark.reporters
-
-- **类型:** `Arrayable`
-- **默认值:** `'default'`
-
-用于定义输出的自定义报告器。它可以包含一个或多个内置报告名称、报告实例和(或)自定义报告的路径。
-
-#### benchmark.outputFile
-
-已弃用,尝试使用 `benchmark.outputJson`。
-
-#### benchmark.outputJson {#benchmark-outputJson}
-
-- **类型:** `string | undefined`
-- **默认值:** `undefined`
-
-存储基准测试结果的文件路径,可用于稍后的 `--compare` 选项。
-
-例如:
-
-```sh
-# 保存主分支的结果。
-git checkout main
-vitest bench --outputJson main.json
-
-# 切换到另一个分支并与主分支进行比较。
-git checkout feature
-vitest bench --compare main.json
-```
-
-#### benchmark.compare {#benchmark-compare}
-
-- **类型:** `string | undefined`
-- **默认值:** `undefined`
-
-与当前运行结果进行比较的以前基准结果的文件路径。
-
-### alias
-
-- **类型:** `Record | Array<{ find: string | RegExp, replacement: string, customResolver?: ResolverFunction | ResolverObject }>`
-
-在测试内部运行时定义自定义别名。它们将与来自 `resolve.alias` 的别名合并。
-
-::: warning
-Vitest 使用 Vite SSR 基元来运行测试,这有 [一定的缺陷](https://vitejs.dev/guide/ssr.html#ssr-externals)。
-
-1. 别名只影响由 [inlined](#server-deps-inline) 模块直接用 `import` 关键字导入的模块(默认情况下所有源代码都是内联的)。
-2. Vitest 不支持对 `require` 调用进行别名。
-3. 如果我们要别名外部依赖(例如,`react` -> `preact`),我们可能需要别名实际的 `node_modules` 包,以使其适用于外部依赖。[Yarn](https://classic.yarnpkg.com/en/docs/cli/add/#toc-yarn-add-alias) 和 [pnpm](https://pnpm.io/aliases/) 都支持通过 `npm:` 前缀进行别名。
-:::
-
-### globals
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **命令行终端:** `--globals`, `--globals=false`
-
-默认情况下,`vitest` 不显式提供全局 API。如果你更倾向于使用类似 jest 中的全局 API,可以将 `--globals` 选项传递给 CLI 或在配置中添加 `globals: true`。
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- globals: true,
- },
-})
-```
-
-为了可以让全局 API 支持 TypeScript,请将 `vitest/globals` 添加到 `tsconfig.json` 中的 `types` 选项中
-
-```json [tsconfig.json]
-{
- "compilerOptions": {
- "types": ["vitest/globals"]
- }
-}
-```
-
-如果你在 TypeScript 配置中修改了 [`typeRoots`](https://www.typescriptlang.org/tsconfig/#typeRoots) ,以便编译时引入更多类型,那么你需要重新把 `node_modules` 加回到 `typeRoots` 中,这样才能让 `vitest/globals` 被正确识别。
-
-```json [tsconfig.json]
-{
- "compilerOptions": {
- "typeRoots": ["./types", "./node_modules/@types", "./node_modules"],
- "types": ["vitest/globals"]
- }
-}
-```
-
-如果你的项目中已经集成了 [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import) 插件,那么可以直接用它来自动引入这些 API,而无需手动导入。
-
-```ts [vitest.config.js]
-import AutoImport from 'unplugin-auto-import/vite'
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- plugins: [
- AutoImport({
- imports: ['vitest'],
- dts: true, // 生成 TypeScript 声明
- }),
- ],
-})
-```
-
-### environment
-
-- **类型:** `'node' | 'jsdom' | 'happy-dom' | 'edge-runtime' | string`
-- **默认值:** `'node'`
-- **命令行终端:** `--environment=`
-
-Vitest 中的默认测试环境是一个 Node.js 环境。如果你正在构建 Web 端应用,你可以使用 [`jsdom`](https://github.com/jsdom/jsdom) 或 [`happy-dom`](https://github.com/capricorn86/happy-dom) 这种类似浏览器(browser-like)的环境来替代 Node.js。
-如果你正在构建边缘计算函数,你可以使用 [`edge-runtime`](https://edge-runtime.vercel.app/packages/vm) 环境
-
-::: tip
-你还可以使用 [浏览器模式](/guide/browser/) 在浏览器中运行集成或单元测试,而无需模拟环境。
-:::
-
-你可以通过在文件顶部添加包含 `@vitest-environment` 的文档块或注释,为某个测试文件中的所有测试指定环境:
-
-文档块格式:
-
-```js
-/**
- * @vitest-environment jsdom
- */
-
-test('use jsdom in this test file', () => {
- const element = document.createElement('div')
- expect(element).not.toBeNull()
-})
-```
-
-注释格式:
-
-```js
-// @vitest-environment happy-dom
-
-test('use happy-dom in this test file', () => {
- const element = document.createElement('div')
- expect(element).not.toBeNull()
-})
-```
-
-为了与 Jest 兼容,还存在一个配置 `@jest-environment`:
-
-```js
-/**
- * @jest-environment jsdom
- */
-
-test('use jsdom in this test file', () => {
- const element = document.createElement('div')
- expect(element).not.toBeNull()
-})
-```
-
-如果使用 [`--isolate=false`](#isolate) 运行 Vitest,测试将按以下顺序运行:`node`、`jsdom`、`happy-dom`、`edge-runtime`、`custom environments`。也就是说,具有相同环境的每个测试都会被分组,但仍会按顺序运行。
-
-从 0.23.0 开始,你还可以定义自定义环境。 当使用非内置环境时,Vitest 将尝试加载包 `vitest-environment-${name}`。 该包应导出一个具有 `Environment` 属性的对象:
-
-```ts [environment.js]
-import type { Environment } from 'vitest'
-
-export default {
- name: 'custom',
- viteEnvironment: 'ssr',
- setup() {
- // 自定义设置
- return {
- teardown() {
- // 在所有使用此环境的测试运行完毕后调用。
- },
- }
- },
-}
-```
-
-Vitest 还通过 `vitest/environments` 入口导出 `builtinEnvironments`,以防你只想扩展它。 你可以在 [测试环境指南](/guide/environment) 中阅读有关扩展测试环境的更多信息。
-
-::: tip
-jsdom 环境变量导出了等同于当前 [JSDOM](https://github.com/jsdom/jsdom) 的 `jsdom` 全局变量实例。如果你想让 TypeScript 识别它,可以在使用此环境时将 `vitest/jsdom`添加到 `tsconfig.json` 中:
-
-```json [tsconfig.json]
-{
- "compilerOptions": {
- "types": ["vitest/jsdom"]
- }
-}
-```
-
-:::
-
-### environmentOptions
-
-- **类型:** `Record<'jsdom' | string, unknown>`
-- **默认值:** `{}`
-
-这些选项被传递给当前 [`environment`](#environment) 的 `setup` 方法。 默认情况下,如果你将其用作测试环境,则只能配置 JSDOM 选项。
-
-### update
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **命令行终端:** `-u`, `--update`, `--update=false`
-
-更新快照文件。这将更新所有更改的快照并删除过时的快照。
-
-### watch
-
-- **类型:** `boolean`
-- **默认值:** `!process.env.CI && process.stdin.isTTY`
-- **命令行终端:** `-w`, `--watch`, `--watch=false`
-
-启动监听模式
-
-交互式环境中,默认启用监听模式,除非显式传入 `--run`。
-
-在 CI 或非交互式 shell 中,监听模式默认关闭,需手动加此标志开启。
-
-### watchTriggerPatterns 3.2.0 {#watchtriggerpatterns}
-
-- **类型:** `WatcherTriggerPattern[]`
-
-Vitest 依据静态与动态 `import` 语句生成的模块图来决定重新执行哪些测试。但若测试读取文件系统或向代理拉取数据,这些依赖便无法被自动探测。
-
-要触发相关测试重新运行,可定义一条正则及一个返回待执行测试文件列表的函数。
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- watchTriggerPatterns: [
- {
- pattern: /^src\/(mailers|templates)\/(.*)\.(ts|html|txt)$/,
- testsToRun: (id, match) => {
- // 相对于 root 值
- return `./api/tests/mailers/${match[2]}.test.ts`
- },
- },
- ],
- },
-})
-```
-
-::: warning
-返回的文件应该是绝对的或相对于 root 的。 请注意,这是一个全局选项,不能在 [project](/guide/projects) 配置内部使用。
-:::
-
-### root
-
-- **类型:** `string`
-- **命令行终端:** `-r `, `--root=`
-
-项目的根目录
-
-### dir
-
-- **类型:** `string`
-- **命令行终端:** `--dir=`
-- **默认值:** same as `root`
-
-扫描测试文件的基本目录。如果我们的根目录覆盖整个项目,我们可以指定此选项以加快测试发现速度
-
-### reporters
-
-- **类型:** `Reporter | Reporter[]`
-- **默认值:** `'default'`
-- **命令行终端:** `--reporter=`, `--reporter= --reporter=`
-
-用于输出的自定义 reporters 。 Reporters 可以是 [一个 Reporter 实例](https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/node/types/reporter.ts) 或选择内置的 reporters 字符串:
-
-- `'default'` - 当他们经过测试套件
-- `'basic'` - 给定一个类似于 CI 中的默认报告实例
-- `'verbose'` - 保持完整的任务树可见
-- `'dot'` - 将每个任务显示为一个点
-- `'junit'` - JUnit XML 报告器(你可以使用 `VITEST_JUNIT_SUITE_NAME` 环境变量配置 `test suites` 标签名称)
-- `'json'` - 给出一个简单的 JSON 总结
-- `'html'` - 根据 [`@vitest/ui`](/guide/ui) 输出 HTML 报告
-- `'hanging-process'` - 如果 Vitest 无法安全退出进程,则显示挂起进程列表。 这可能是一个复杂的操作,只有在 Vitest 始终无法退出进程时才启用它
-- 自定义报告的路径 (例如 `'./path/to/reporter.ts'`, `'@scope/reporter'`)
-
-### outputFile
-
-- **类型:** `string | Record`
-- **命令行终端:** `--outputFile=`, `--outputFile.json=./path`
-
-当指定 `--reporter=json`、`--reporter=html` 或 `--reporter=junit` 时,将测试结果写入一个文件。通过提供对象而不是字符串,你可以在使用多个报告器时定义单独的输出。
-
-### pool {#pool}
-
-- **类型:** `'threads' | 'forks' | 'vmThreads' | 'vmForks'`
-- **默认值:** `'forks'`
-- **命令行终端:** `--pool=threads`
-
-用于运行测试的线程池。
-
-#### threads
-
-使用 [tinypool](https://github.com/tinylibs/tinypool)(一个轻量级的 [Piscina](https://github.com/piscinajs/piscina) 分支)来启用多线程。当使用线程时,你无法使用与进程相关的 API,如 `process.chdir()` 。一些使用原生语言编写的库,如 Prisma 、`bcrypt` 和 `canvas` ,在多线程环境下可能会遇到问题并导致段错误。在这些情况下,建议使用 `forks` 线程池。
-
-#### forks
-
-与 `threads` 线程池类似,但是使用 `child_process` 而不是 `worker_threads` ,通过 [tinypool](https://github.com/tinylibs/tinypool) 实现。与 `threads` 线程池相比,测试与主进程之间的通信速度不够快。在 `forks` 线程池中,可以使用与进程相关的 API ,如 `process.chdir()` 。
-
-#### vmThreads
-
-在 `threads` 线程池中使用 [VM 上下文](https://nodejs.org/api/vm.html)(在沙箱环境中)运行测试。
-
-这样可以加快测试速度,但是当运行 [ESM 代码](https://github.com/nodejs/node/issues/37648) 时,VM 模块可能不稳定。你的测试可能会 [泄漏内存](https://github.com/nodejs/node/issues/33439),为了解决这个问题,考虑手动编辑 [`poolOptions.vmThreads.memoryLimit`](#pooloptions-vmthreads-memorylimit) 的值。
-
-::: warning
-在沙箱中运行代码有一些优点(测试速度更快),但也有许多缺点。
-
-- 原生模块中的全局变量,例如(`fs`、`path`等),与测试环境中存在的全局变量不同。因此,这些原生模块引发的任何错误都将引用与代码中使用的错误构造函数不同的错误构造函数:
-
-```ts
-try {
- fs.writeFileSync('/doesnt exist')
-}
-catch (err) {
- console.log(err instanceof Error) // false
-}
-```
-
-- 导入 ES 模块会无限期地缓存它们,如果你有很多上下文(测试文件),这会导致内存泄漏。Node.js 中没有可以清除该缓存的 API。
-- 在沙盒环境中访问全局变量[需要更长的时间](https://github.com/nodejs/node/issues/31658)。
-
-使用此选项时请注意这些问题。Vitest 团队无法解决我们这边的任何问题。
-:::
-
-#### vmForks
-
-与 `vmThreads` 池类似,但通过 [tinypool](https://github.com/tinylibs/tinypool) 使用 `child_process` 而不使用 `worker_threads`。测试与主进程之间的通信速度虽然不如 `vmThreads` 快。但进程相关的 API(如 `process.chdir()` )在 `vmForks` 中却可以使用。请注意,这个与 `vmThreads` 中列出的池具有相同的缺陷。
-
-### poolOptions {#pooloptions}
-
-- **类型:** `Record<'threads' | 'forks' | 'vmThreads' | 'vmForks', {}>`
-- **默认值:** `{}`
-
-#### poolOptions.threads
-
-`threads` 池的选项。
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- poolOptions: {
- threads: {
- // 此处是与线程相关的选项
- },
- },
- },
-})
-```
-
-##### poolOptions.threads.maxThreads
-
-- **类型:** `number | string`
-- **默认值:** _可用 CPU 核心数_
-
-最大线程数或百分比。还可以使用`VITEST_MAX_THREADS`环境变量进行设置。
-
-##### poolOptions.threads.singleThread
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-在单个工作线程内使用相同的环境运行所有测试。 这将禁用内置模块隔离(我们的源代码或 [inlined](#server-deps-inline) 代码仍将针对每个测试重新评估),但可以提高测试性能。
-
-::: warning
-尽管此选项将强制测试一个接一个地运行,但此选项与 Jest 的 `--runInBand` 不同。 Vitest 使用工作线程不仅可以并行运行测试,还可以提供隔离。 通过禁用此选项,你的测试将按顺序运行,但在相同的全局上下文中,因此你必须自己提供隔离。
-
-如果你依赖全局状态(前端框架通常这样做)或者你的代码依赖于为每个测试单独定义的环境,这可能会导致各种问题。 但可以提高你的测试速度(最多快 3 倍),这不一定依赖于全局状态,也可以轻松绕过它。
-:::
-
-##### poolOptions.threads.useAtomics
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-使用 Atomics 来同步线程。
-
-这在某些情况下可以提高性能,但可能会导致旧 Node 版本中出现段错误。
-
-##### poolOptions.threads.isolate
-
-- **类型:** `boolean`
-- **默认值:** `true`
-
-隔离每个测试文件的环境。
-
-##### poolOptions.threads.execArgv
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-
-在线程中向 `node` 传递附加参数。更多信息,具体可以浏览 [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) 。
-
-::: warning
-使用时要小心,因为某些选项(如--prof、--title)可能会导致 worker 崩溃。具体信息可以浏览 https://github.com/nodejs/node/issues/41103。
-:::
-
-#### poolOptions.forks
-
-`forks` 池相关选项。
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- poolOptions: {
- forks: {
- // 此处是 Fork 相关的选项
- },
- },
- },
-})
-```
-
-##### poolOptions.forks.maxForks
-
-- **类型:** `number | string`
-- **默认值:** _可用 CPU 核心数_
-
-最大分支数量或百分比。你也可以使用 `VITEST_MAX_FORKS` 环境变量。
-
-##### poolOptions.forks.isolate
-
-- **类型:** `boolean`
-- **默认值:** `true`
-
-隔离每个测试文件的环境。
-
-##### poolOptions.forks.singleFork
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-在单个子进程中使用相同的环境运行所有测试。 这将禁用内置模块隔离(你的源代码或 [inlined](#server-deps-inline) 代码仍将针对每个测试重新评估),但可以提高测试性能。
-
-::: warning
-尽管此选项将强制测试一个接一个地运行,但此选项与 Jest 的 `--runInBand` 不同。 Vitest 使用子进程不仅可以并行运行测试,还可以提供隔离。 通过禁用此选项,你的测试将按顺序运行,但在相同的全局上下文中,因此你必须自己提供隔离。
-
-如果你依赖全局状态(前端框架通常这样做)或者你的代码依赖于为每个测试单独定义的环境,这可能会导致各种问题。 但可以提高你的测试速度(最多快 3 倍),这不一定依赖于全局状态,也可以轻松绕过它。
-:::
-
-##### poolOptions.forks.execArgv
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-
-向子进程中的 `node` 进程传递附加参数。更多信息,详细信息可以浏览 [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) 。
-
-:::warning
-使用时要小心,因为某些选项(如 --prof、--title )可能会导致 worker 崩溃。详细信息可以浏览 https://github.com/nodejs/node/issues/41103。
-:::
-
-#### poolOptions.vmThreads
-
-`vmThreads` 池的选项。
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- poolOptions: {
- vmThreads: {
- // 此处是与虚拟线程相关的选项
- },
- },
- },
-})
-```
-
-##### poolOptions.vmThreads.maxThreads
-
-- **类型:** `number | string`
-- **默认值:** _可用 CPU 核心数_
-
-最大线程数或百分比。还可以使用`VITEST_MAX_THREADS`环境变量进行设置。
-
-##### poolOptions.vmThreads.memoryLimit
-
-- **类型:** `string | number`
-- **命令行终端:** `1 / CPU Cores`
-
-指定工作线程被回收之前的内存限制。该值在很大程度上取决于你的运行环境,因此最好手动指定它,而不是依赖默认值。
-
-::: tip
-该实现基于 Jest 的 [`workerIdleMemoryLimit`](https://jestjs.io/docs/configuration#workeridlememorylimit-numberstring)。
-
-可以通过多种不同的方式指定限制,无论结果是什么,`Math.floor` 都用于将其转换为整数值:
-
-- `<= 1` - 该值假定为系统内存的百分比。所以 0.5 将 worker 的内存限制设置为系统总内存的一半。
-- `\> 1` - 假设是固定字节值。由于之前的规则,如果你想要 1 字节的值(我不知道为什么),你可以使用 1.1。
-- 有单位时
- - `50%` - 如上,占系统总内存的百分比
- - `100KB`, `65MB`, 等 - 用单位表示固定的内存限制
- - `K` / `KB` - 千字节 (x1000)
- - `KiB` - 千字节 (x1024)
- - `M` / `MB`- 千字节
- - `MiB` - 兆字节
- - `G` / `GB` - 千兆字节
- - `GiB` - 千兆字节
-:::
-
-::: warning
-由于系统内存报告不正确,基于百分比的内存限制[在 Linux CircleCI 上不起作用](https://github.com/jestjs/jest/issues/11956#issuecomment-1212925677)。
-:::
-
-##### poolOptions.vmThreads.useAtomics
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-使用 Atomics 来同步线程。
-
-这在某些情况下可以提高性能,但可能会在旧的 Node 版本中抛出错误。
-
-##### poolOptions.vmThreads.execArgv
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-
-将附加参数传递给虚拟机上下文中的 `node` 进程。更多信息,详细信息可以浏览 [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) 。
-
-:::warning
-使用时要小心,因为某些选项(如 --prof、--title )可能会导致 worker 崩溃。详细信息可以浏览 https://github.com/nodejs/node/issues/41103。
-:::
-
-#### poolOptions.vmForks
-
-`vmForks` 池相关选项
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- poolOptions: {
- vmForks: {
- // 此处是虚拟 Fork 相关的选项
- },
- },
- },
-})
-```
-
-##### poolOptions.vmForks.maxForks
-
-- **类型:** `number | string`
-- **默认值:** _可用 CPU 核心数_
-
-最大线程数或百分比。你也可以使用 `VITEST_MAX_FORKS` 环境变量。
-
-##### poolOptions.vmForks.memoryLimit
-
-- **类型:** `string | number`
-- **默认值:** `1 / CPU Cores`
-
-指定 Worker 被回收前的内存限制。该值在很大程度上取决于环境,因此最好手动指定,而不是依赖默认值。该值的计算方法查看 [`poolOptions.vmThreads.memoryLimit`](#pooloptions-vmthreads-memorylimit)
-
-##### poolOptions.vmForks.execArgv
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-
-将附加参数传递给虚拟机上下文中的 `node` 进程。更多信息,查看 [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) 了解更多详情。。
-
-:::warning
-使用时要小心,因为某些选项(如 `--prof` 、`--title`)可能会导致 worker 崩溃。查看 https://github.com/nodejs/node/issues/41103 了解更多详情。
-:::
-
-### fileParallelism {#fileparallelism}
-
-- **类型:** `boolean`
-- **默认值:** `true`
-- **命令行终端:** `--no-file-parallelism`, `--fileParallelism=false`
-
-所有测试文件应该并行运行。将其设置为 `false` 将覆盖 `maxWorkers` 和 `minWorkers` 选项为 `1`。
-
-::: tip
-此选项不会影响在同一文件中运行的测试。如果你想并行运行这些程序,请在 [description](/api/#describe-concurrent) 或通过 [配置](#sequence-concurrent) 上使用 `concurrent` 选项。
-:::
-
-### maxWorkers {#maxworkers}
-
-- **类型:** `number | string`
-
-运行测试时设置的最大工作线程数或百分比。`poolOptions。{threads,vmThreads}.maxThreads `/`poolOptions.forks.maxForks` 具有更高的优先级。
-
-### testTimeout
-
-- **类型:** `number`
-- **默认值:** 在 Node.js 环境下为 `5_000`,当 browser.enabled 为 `true` 时为 `15_000`
-- **命令行终端:** `--test-timeout=5000`, `--testTimeout=5000`
-
-测试的默认超时时间(以毫秒为单位)。使用 `0` 完全禁用超时。
-
-### hookTimeout
-
-- **类型:** `number`
-- **默认值:** 在 Node.js 环境下为 `10_000`,当 browser.enabled 为 `true` 时为 `30_000`
-- **命令行终端:** `--hook-timeout=10000`, `--hookTimeout=10000`
-
-钩子(hook)的默认超时时间(以毫秒为单位)。使用 `0` 完全禁用超时。
-
-### teardownTimeout
-
-- **类型:** `number`
-- **默认值:** `1000`
-- **命令行终端:** `--teardown-timeout=5000`, `--teardownTimeout=5000`
-
-Vitest 关闭时等待关闭的默认超时时间,以毫秒为单位
-
-### silent
-
-- **类型:** `boolean | 'passed-only'`
-- **默认值:** `false`
-- **命令行终端:** `--silent`, `--silent=false`
-
-静默模式下启动测试。
-
-使用 `'passed-only'` 来查看失败测试的日志。失败测试的日志在测试完成后打印。
-
-### setupFiles
-
-- **类型:** `string | string[]`
-
-setup 文件的路径。它们将在每个测试文件之前运行。
-
-::: info 提示
-编辑设置文件将自动触发所有测试的重新运行。
-:::
-
-你可以在全局设置文件中使用 `process.env.VITEST_POOL_ID`(类似整数的字符串)来区分不同的线程。
-
-:::tip
-请注意,如果运行 [`--isolate=false`](#isolate) ,这个配置文件将在全局范围内多次运行。这意味着每次测试前都要访问同一个全局对象,因此请确保不要重复做同一件事。
-:::
-
-比如,你可能依赖于一个全局变量:
-
-```ts
-import { config } from '@some-testing-lib'
-
-if (!globalThis.defined) {
- config.plugins = [myCoolPlugin]
- computeHeavyThing()
- globalThis.defined = true
-}
-
-// Hook 在每个套件之前重置
-afterEach(() => {
- cleanup()
-})
-
-globalThis.resetBeforeEachTest = true
-```
-
-### provide 2.1.0 {#provide}
-
-- **类型:** `Partial`
-
-使用 `inject` 方法定义可在测试中访问的值。
-
-:::code-group
-```ts [vitest.config.js]
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- provide: {
- API_KEY: '123',
- },
- },
-})
-```
-```ts [api.test.js]
-import { expect, inject, test } from 'vitest'
-
-test('api key is defined', () => {
- expect(inject('API_KEY')).toBe('123')
-})
-```
-:::
-
-::: warning
-属性必须是字符串,值必须是 [可序列化](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types),因为该对象将在不同进程之间传输。
-:::
-
-::: tip
-如果使用的是 TypeScript,则需要增强 `ProvidedContext` 类型,以实现类型安全访问:
-
-```ts [vitest.shims.d.ts]
-declare module 'vitest' {
- export interface ProvidedContext {
- API_KEY: string
- }
-}
-
-// 将此文件标记为模块,以便增强正常工作
-export {}
-```
-:::
-
-### globalSetup
-
-- **类型:** `string | string[]`
-
-全局的 setup 文件的路径,相对于项目的根目录。
-
-全局的 setup 文件可以导出命名函数 `setup` 和 `teardown` 或返回拆卸函数的 `default` 函数([示例](https://github.com/vitest-dev/vitest/blob/main/test/global-setup/vitest.config.ts))。
-
-::: info 提示
-可以存在多个 globalSetup。setup 和 teardown 依次执行,而 teardown 则以相反的顺序执行。
-:::
-
-::: warning
-全局设置只有在至少有一个正在运行的测试时才运行。这意味着在测试文件更改后,全局安装程序可能会在监视模式下开始运行(测试文件将等待全局安装程序完成后再运行)。
-
-请注意,全局设置在不同的全局范围内运行,因此你的测试无法访问此处定义的变量。悬停,从 1.0.0 开始,你可以通过 [`provide`](#provide) 方法将可序列化数据传递给测试:
-
-:::code-group
-```ts [example.test.js]
-import { inject } from 'vitest'
-
-inject('wsPort') === 3000
-```
-```ts [globalSetup.ts 3.0.0]
-import type { TestProject } from 'vitest/node'
-
-export default function setup(project: TestProject) {
- project.provide('wsPort', 3000)
-}
-
-declare module 'vitest' {
- export interface ProvidedContext {
- wsPort: number
- }
-}
-```
-```ts [globalSetup.ts 2.0.0]
-import type { GlobalSetupContext } from 'vitest/node'
-
-export default function setup({ provide }: GlobalSetupContext) {
- provide('wsPort', 3000)
-}
-
-declare module 'vitest' {
- export interface ProvidedContext {
- wsPort: number
- }
-}
-```
-:::
-自 Vitest 3起,我们可以定义一个自定义回调函数,在 Vitest 重新运行测试时被调用。如果该函数是异步的,运行器将在执行测试前等待其完成。请注意,我们不能像 `{ onTestsRerun }` 那样解构 `project` ,因为它依赖于上下文环境。
-
-```ts [globalSetup.ts]
-import type { TestProject } from 'vitest/node'
-
-export default function setup(project: TestProject) {
- project.onTestsRerun(async () => {
- await restartDb()
- })
-}
-```
-
-### forceRerunTriggers
-
-- **类型**: `string[]`
-- **默认值:** `['**/package.json/**', '**/vitest.config.*/**', '**/vite.config.*/**']`
-
-将触发整个套件重新运行的文件路径的全局 glob 模式。 如果在 git diff 中找到触发器,则与 --changed 参数配对时,将运行整个测试套件。
-
-如果你正在测试调用 CLI 命令时很有用,因为 Vite 无法构建模块依赖树:
-
-```ts
-test('execute a script', async () => {
- // 如果 `dist/index.js` 的内容发生变化,Vitest 无法重新运行此测试
- await execa('node', ['dist/index.js'])
-})
-```
-
-:::tip 提醒
-请确保我们的文件没有被 [`server.watch.ignored`](https://vitejs.dev/config/server-options.html#server-watch)排除在外。
-:::
-
-### coverage
-
-你可以选择 [`v8`](/guide/coverage.html#v8-provider)、[`istanbul`](/guide/coverage.html#istanbul-provider) ,或者 [自定义覆盖率工具](/guide/coverage#custom-coverage-provider) 来进行代码覆盖率统计。
-
-你可以使用点符号向 CLI 提供覆盖选项:
-
-```sh
-npx vitest --coverage.enabled --coverage.provider=istanbul
-```
-
-::: warning
-如果你使用带点符号的覆盖选项,请不要忘记指定 `--coverage.enabled`。 在这种情况下,不要提供单个 --coverage 选项。
-:::
-
-#### coverage.provider
-
-- **类型:** `'v8' | 'istanbul' | 'custom'`
-- **默认值:** `'v8'`
-- **命令行终端:** `--coverage.provider=`
-
-使用 `provider` 选择收集测试覆盖率的工具。
-
-#### coverage.enabled
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.enabled`, `--coverage.enabled=false`
-
-是否启用收集测试覆盖率。可以使用 `--coverage` 覆盖 CLI 选项。
-
-#### coverage.include
-
-- **类型:** `string[]`
-- **默认值:** 在执行测试过程中所引入的文件。
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.include=`, `--coverage.include= --coverage.include=`
-
-以 glob 模式指定需要统计覆盖率的文件列表。默认情况下,只有被测试实际执行到的文件会被纳入覆盖率统计。
-
-建议在 glob 模式中明确包含文件扩展名。
-
-可以参考 [如何在覆盖率报告中包含或排除文件](/guide/coverage.html#including-and-excluding-files-from-coverage-report) 里的示例。
-
-#### coverage.exclude
-
-- **类型:** `string[]`
-- **默认值:** : `[]`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.exclude=`, `--coverage.exclude= --coverage.exclude=`
-
-可以参考 [如何在覆盖率报告中包含或排除文件](/guide/coverage.html#including-and-excluding-files-from-coverage-report) 里的示例。
-
-#### coverage.clean
-
-- **类型:** `boolean`
-- **默认值:** `true`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.clean`, `--coverage.clean=false`
-
-运行测试之前是否清除覆盖率结果
-
-#### coverage.cleanOnRerun
-
-- **类型:** `boolean`
-- **默认值:** `true`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.cleanOnRerun`, `--coverage.cleanOnRerun=false`
-
-监视重新运行时是否清除覆盖率报告。设置为 `false` 可保留观察模式下上次运行的覆盖结果。
-
-#### coverage.reportsDirectory
-
-- **类型:** `string`
-- **默认值:** `'./coverage'`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.reportsDirectory=`
-
-::: warning
-如果启用了 `coverage.clean`(默认值),Vitest 会在运行测试前删除此目录。
-:::
-
-配置测试覆盖率报告写入的目录。
-
-要预览覆盖范围报告,请使用 [HTML 报告器](/guide/reporters.html#html-reporter), 该选项必须设置为 html 报告目录的子目录 (比如 `./html/coverage`).
-
-#### coverage.reporter
-
-- **类型:** `string | string[] | [string, {}][]`
-- **默认值:** `['text', 'html', 'clover', 'json']`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.reporter=`, `--coverage.reporter= --coverage.reporter=`
-
-配置要使用的测试覆盖率报告器。查看 [istanbul 文档](https://istanbul.js.org/docs/advanced/alternative-reporters/) 来了解报告详情。有关报告特定选项的详细信息,请参阅 [`@types/istanbul-reporter`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/276d95e4304b3670eaf6e8e5a7ea9e265a14e338/types/istanbul-reports/index.d.ts)。
-
-该报告器支持三种不同的类型:
-
-- 单个报告器: `{ reporter: 'html' }`
-- 无配置的多个报告器: `{ reporter: ['html', 'json'] }`
-- 有配置的单个或多个报告器:
-
- ```ts
- {
- reporter: [
- ["lcov", { projectRoot: "./src" }],
- ["json", { file: "coverage.json" }],
- ["text"],
- ];
- }
- ```
-
-我们还可以传递自定义覆盖报告器。查看 [自定义覆盖率的报告器](/guide/coverage#custom-coverage-reporter) 了解更多详情。
-
-
-
-```ts
-{
- reporter: [
- // 使用 NPM 包的名称指定报告器
- "@vitest/custom-coverage-reporter",
- ["@vitest/custom-coverage-reporter", { someOption: true }],
-
- // 使用本地路径指定报告器
- "/absolute/path/to/custom-reporter.cjs",
- ["/absolute/path/to/custom-reporter.cjs", { someOption: true }],
- ];
-}
-```
-
-我们可以在 Vitest UI 中查看覆盖率报告:查看 [UI 模式](/guide/coverage#vitest-ui) 了解更多详情。
-
-#### coverage.reportOnFailure {#coverage-reportonfailure}
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.reportOnFailure`, `--coverage.reportOnFailure=false`
-
-即使测试失败也会生成覆盖率报告。
-
-#### coverage.allowExternal
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.allowExternal`, `--coverage.allowExternal=false`
-
-收集 [项目`root`](#root) 之外文件的覆盖率。
-
-#### coverage.excludeAfterRemap 2.1.0 {#coverage-exclude-after-remap}
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.excludeAfterRemap`, `--coverage.excludeAfterRemap=false`
-
-在覆盖范围重新映射到原始源后再次应用排除。
-当你的源文件被转译并且可能包含非源文件的源映射时,这很有用。
-
-当你看到报告中显示的文件与你的 `coverage.exclude` 模式匹配时,请使用此选项。
-
-#### coverage.skipFull
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.skipFull`, `--coverage.skipFull=false`
-
-是否显示具有 100% 语句、分支和函数的测试覆盖率的文件。
-
-#### coverage.thresholds
-
-覆盖率阈值选项。
-
-如果将阈值设置为正数,则将其解释为所需的最小覆盖率百分比。例如,将行阈值设置为 `90` 意味着必须覆盖 90% 的行。
-
-如果将阈值设置为负数,则将其视为允许的最大未覆盖项数量。例如,将行阈值设置为 `-10` 意味着未覆盖的行数不得超过 10 行。
-
-
-```ts
-{
- coverage: {
- thresholds: {
- // 需要 90% 的功能覆盖率
- functions: 90,
-
- // 要求不超过10行被覆盖
- lines: -10,
- }
- }
-}
-```
-
-##### coverage.thresholds.lines
-
-- **类型:** `number`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.thresholds.lines=`
-
-lines 的全局阈值。
-
-##### coverage.thresholds.functions
-
-- **类型:** `number`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.thresholds.functions=`
-
-functions 的全局阈值。
-
-##### coverage.thresholds.branches
-
-- **类型:** `number`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.thresholds.branches=`
-
-branches 的全局阈值。
-
-##### coverage.thresholds.statements
-
-- **类型:** `number`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.thresholds.statements=`
-
-statements 的全局阈值。
-
-##### coverage.thresholds.perFile
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.thresholds.perFile`, `--coverage.thresholds.perFile=false`
-
-检查每个文件的阈值。
-
-##### coverage.thresholds.autoUpdate
-
-- **类型:** `boolean | function`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.thresholds.autoUpdate=`
-
-如果当前覆盖率优于配置的阈值时,将所有阈值 `lines`、`functions`、`branches` 和 `statements` 更新到配置文件中。
-此选项有助于在覆盖率提高时保持阈值不变。
-
-你还可以传递一个函数来格式化更新的阈值:
-
-
-```ts
-{
- coverage: {
- thresholds: {
- // 更新不带小数的阈值
- autoUpdate: (newThreshold) => Math.floor(newThreshold),
-
- // 95.85 -> 95
- functions: 95,
- }
- }
-}
-```
-
-##### coverage.thresholds.100
-
-- **类型:** `boolean`
-- **默认值:** `false`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.thresholds.100`, `--coverage.thresholds.100=false`
-
-将全局阈值设置为 100。
-这是 `--coverage.thresholds.lines 100 --coverage.thresholds.functions 100 --coverage.thresholds.branches 100 --coverage.thresholds.statements 100` 的快捷方式。
-
-##### coverage.thresholds[glob-pattern]
-
-- **类型:** `{ statements?: number functions?: number branches?: number lines?: number }`
-- **默认值:** `undefined`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-
-设置与 glob 模式匹配的文件的阈值。
-
-::: tip NOTE
-Vitest 会将所有文件,包括那些被 glob 模式覆盖的文件,计入全局覆盖率阈值。
-这与 Jest 的行为不同。
-:::
-
-
-
-```ts
-{
- coverage: {
- thresholds: {
- // 所有文件的阈值
- functions: 95,
- branches: 70,
-
- // 匹配全局模式的阈值
- 'src/utils/**.ts': {
- statements: 95,
- functions: 90,
- branches: 85,
- lines: 80,
- },
-
- // 匹配此模式的文件将仅设置行阈值。
- // 全局阈值不会被继承。
- '**/math.ts': {
- lines: 100,
- }
- }
- }
-}
-```
-
-##### coverage.thresholds[glob-pattern].100 2.1.0 {#coverage-thresholds-glob-pattern-100}
-
-- **类型:** `boolean`
-- **Default:** `false`
-- **Available for providers:** `'v8' | 'istanbul'`
-
-将匹配全局模式的文件的阈值设置为 100。
-
-
-```ts
-{
- coverage: {
- thresholds: {
- // 所有文件的阈值
- functions: 95,
- branches: 70,
-
- // 匹配全局模式的阈值
- 'src/utils/**.ts': { 100: true },
- '**/math.ts': { 100: true }
- }
- }
-}
-```
-
-#### coverage.ignoreClassMethods
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.ignoreClassMethods=`
-
-设置为要忽略覆盖率的类方法名称数组。参考 [istanbul 文档](https://github.com/istanbuljs/nyc#ignoring-methods) 来了解详情。
-
-#### coverage.watermarks
-
-- **类型:**
-
-
-```ts
-{
- statements?: [number, number],
- functions?: [number, number],
- branches?: [number, number],
- lines?: [number, number]
-}
-```
-
-- **默认值:**
-
-
-```ts
-{
- statements: [50, 80],
- functions: [50, 80],
- branches: [50, 80],
- lines: [50, 80]
-}
-```
-
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.watermarks.statements=50,80`, `--coverage.watermarks.branches=50,80`
-
-语句、行、分支和函数的水印。有关更多信息,请参见 [istanbul 文档](https://github.com/istanbuljs/nyc#high-and-low-watermarks)。
-
-#### coverage.processingConcurrency
-
-- **类型:** `boolean`
-- **默认值:** `Math.min(20, os.availableParallelism?.() ?? os.cpus().length)`
-- **可用的测试提供者:** `'v8' | 'istanbul'`
-- **命令行终端:** `--coverage.processingConcurrency=`
-
-处理覆盖率结果时使用的并发限制。
-
-#### coverage.customProviderModule
-
-- **类型:** `string`
-- **可用的测试提供者:** `'custom'`
-- **命令行终端:** `--coverage.customProviderModule=`
-
-指定自定义覆盖率提供者的模块名称或路径。有关详细信息,请参阅[指南 - 自定义覆盖率提供者](/guide/coverage#custom-coverage-provider)。
-
-### testNamePattern
-
-- **类型** `string | RegExp`
-- **命令行终端:** `-t `, `--testNamePattern=`, `--test-name-pattern=`
-
-使用与模式匹配的全名运行测试。
-如果你将 `OnlyRunThis` 添加到此属性,将跳过测试名称中不包含单词 `OnlyRunThis` 的测试。
-
-```js
-import { expect, test } from 'vitest'
-
-// 运行
-test('OnlyRunThis', () => {
- expect(true).toBe(true)
-})
-
-// 跳过
-test('doNotRun', () => {
- expect(true).toBe(true)
-})
-```
-
-### open
-
-- **类型:** `boolean`
-- **默认值:** `!process.env.CI`
-- **命令行终端:** `--open`, `--open=false`
-
-打开 Vitest UI (WIP: 赞助者计划可用)
-
-### api
-
-- **类型:** `boolean | number`
-- **默认值:** `false`
-- **命令行终端:** `--api`, `--api.port`, `--api.host`, `--api.strictPort`
-
-提供 API 服务的端口。当设置为 true 时,默认端口为 51204
-
-### browser 实验性 {#browser}
-
-- **默认值:** `{ enabled: false }`
-- **命令行终端:** `--browser=`, `--browser.name=chrome --browser.headless`
-
-运行浏览器测试的配置。请参阅 [“浏览器配置”](/guide/browser/config)。
-
-::: warning
-这是一项实验性功能。重大更改可能不会遵循 semver,请在使用时锁定 Vitest 的版本。
-:::
-
-### clearMocks
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-每次测试前,都会对所有 momo 调用 [`.mockClear()`](/api/mock#mockclear)。这将清除模拟历史记录,而不会影响模拟实现。
-
-### mockReset
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-每个测试开始前自动调用 [`vi.resetAllMocks()`](/api/vi#vi-resetallmocks),既清空 mock 调用记录,又将所有实现重置。
-
-### restoreMocks
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-每个测试开始前自动调用 [`vi.restoreAllMocks()`](/api/vi#vi-restoreallmocks),恢复所有由 [`vi.spyOn`](#vi-spyon) 创建的 spy 的原始实现。
-
-### unstubEnvs {#unstubenvs}
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-将在每次测试前调用 [`vi.unstubAllEnvs`](/api/#vi-unstuballenvs)。
-
-### unstubGlobals {#unstubglobals}
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-将在每次测试前调用 [`vi.unstubAllGlobals`](/api/#vi-unstuballglobals)。
-
-### snapshotFormat
-
-- **类型:** `PrettyFormatOptions`
-
-快照测试的格式选项。这些选项被传递给我们 fork 的 [`pretty-format`](https://www.npmjs.com/package/pretty-format)。除了 `pretty-format` 选项外,我们还支持 `printShadowRoot: boolean`。
-
-::: tip
-请注意,此对象上的 `plugins` 字段将被忽略。
-
-如果你需要通过 pretty-format 插件扩展快照序列器,请使用 [`expect.addSnapshotSerializer`](/api/expect#expect-addsnapshotserializer) 或 [snapshotSerializers](#snapshotserializers) 选项。
-:::
-
-### snapshotSerializers {#snapshotserializers}
-
-- **类型:** `string[]`
-- **默认值:** `[]`
-
-快照测试的快照序列化程序模块的路径列表,如果要添加自定义快照序列化器,则非常有用。有关详细信息,请参阅 [自定义序列化器](/guide/snapshot#custom-serializer)。
-
-### resolveSnapshotPath
-
-- **类型**: `(testPath: string, snapExtension: string, context: { config: SerializedConfig }) => string`
-- **默认值**: 将快照文件存储在 `__snapshots__` 目录中
-
-覆盖快照的默认路径。例如,要在测试文件旁边存储一下快照:
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- resolveSnapshotPath: (testPath, snapExtension) => testPath + snapExtension,
- },
-})
-```
-
-### allowOnly
-
-- **类型**: `boolean`
-- **默认值**: `!process.env.CI`
-- **命令行终端:** `--allowOnly`, `--allowOnly=false`
-
-允许标记为 only 的测试和套件。
-
-### dangerouslyIgnoreUnhandledErrors
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端:** `--dangerouslyIgnoreUnhandledErrors` `--dangerouslyIgnoreUnhandledErrors=false`
-
-忽略发生的任何未处理的错误。
-
-### passWithNoTests
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端:** `--passWithNoTests`, `--passWithNoTests=false`
-
-如果没有找到测试,Vitest 不会失败。
-
-### logHeapUsage
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端:** `--logHeapUsage`, `--logHeapUsage=false`
-
-每次测试后显示堆的使用情况。用于调试内存是否泄漏。
-
-### css
-
-- **类型**: `boolean | { include?, exclude?, modules? }`
-
-配置是否应处理 CSS。 排除后,CSS 文件将被替换为空字符串以绕过后续处理。 CSS 模块将返回一个代理以不影响运行时。
-
-#### css.include
-
-- **类型**: `RegExp | RegExp[]`
-- **默认值**: `[]`
-
-将返回匹配正则表达式并将由 Vite 管道处理的实际 CSS 文件。
-
-:::tip
-如果需要处理所有 CSS 文件,请使用 `/.+/`。
-:::
-
-#### css.exclude
-
-- **类型**: `RegExp | RegExp[]`
-- **默认值**: `[]`
-
-将返回匹配正则表达式的空 CSS 文件。
-
-#### css.modules
-
-- **类型**: `{ classNameStrategy? }`
-- **默认值**: `{}`
-
-#### css.modules.classNameStrategy
-
-- **类型**: `'stable' | 'scoped' | 'non-scoped'`
-- **默认值**: `'stable'`
-
-如果你决定处理 CSS 文件,你可以配置 CSS 模块中的类名是否在限定范围内。 默认情况下,Vitest 会导出一个代理,绕过 CSS 模块处理。 你可以选择以下选项之一:
-
-- `stable`: 类名将生成为`_${name}_${hashedFilename}`,这意味着如果 CSS 内容发生变化,生成的类将保持不变,但如果文件名被修改,或者文件名将发生变化 被移动到另一个文件夹。 如果你使用快照功能,此设置很有用。
-- `scoped`: 类名将照常生成,遵照 `css.modules.generateScopedName` 方法,如果你有的话。 默认情况下,文件名将生成为`_${name}_${hash}`,其中 hash 包括文件名和文件内容。
-- `non-scoped`: 类名将保留 CSS 中定义的名称。
-
-::: warning
-在默认的情况下,Vitest 导出代理会绕过 CSS 模块处理。 如果你依赖类的 CSS 属性,就必须使用 `include` 选项启用 CSS 处理。
-:::
-
-### maxConcurrency
-
-- **类型**: `number`
-- **默认值**: `5`
-- **命令行终端**: `--max-concurrency=10`, `--maxConcurrency=10`
-
-使用 `test.concurrent` 标记允许同时运行的最大测试数量。
-
-当出现可用插槽时,超过此限制的测试将排队运行。
-
-### cache
-
-- **类型**: `false`
-- **命令行终端**: `--no-cache`, `--cache=false`
-
-如果要禁用缓存功能,请使用此选项。目前,Vitest 会对测试结果进行缓存,优先运行时间较长和失败的测试。
-
-缓存目录由 Vite 的 [`cacheDir`](https://vitejs.dev/config/shared-options.html#cachedir) 选项控制:
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- cacheDir: 'custom-folder/.vitest'
-})
-```
-
-我们可以使用 `process.env.VITEST` 来限制目录,使其仅用于 Vitest:
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- cacheDir: process.env.VITEST ? 'custom-folder/.vitest' : undefined
-})
-```
-
-### sequence
-
-- **类型**: `{ sequencer?, shuffle?, seed?, hooks?, setupFiles?, groupOrder }`
-
-配置测试运行顺序的选项。
-
-你可以使用点符号向 CLI 提供序列选项:
-
-```sh
-npx vitest --sequence.shuffle --sequence.seed=1000
-```
-
-#### sequence.sequencer
-
-- **类型**: `TestSequencerConstructor`
-- **默认值**: `BaseSequencer`
-
-定义分片和排序的自定义类。你可以从 `vitest/node` 扩展 `BaseSequencer`,如果你只需要重新定义 `sort` 和 `shard` 方法之一,但两者都应该存在。
-
-分片是在排序之前进行的,并且只有提供了 `--shard` 选项的情况下才会生效。
-
-如果指定了 [`sequencer.groupOrder`](#grouporder),则将为每个组和池调用一次定序器。
-
-#### groupOrder 3.2.0 {#grouporder}
-
-- **类型:** `number`
-- **Default:** `0`
-
-控制使用多个[项目](/guide/projects) 时该项目运行测试的顺序。
-
-- 具有相同组序号的项目将一起运行,并且组从低到高运行。
-- 如果不设置此选项,所有项目将并行运行。
-- 如果多个项目使用相同的组序,它们将同时运行。
-
-此设置仅影响项目运行的顺序,而不影响项目中测试的顺序。
-要控制项目内的测试隔离或测试顺序,请使用 [`isolate`](#isolate) 和 [`sequence.sequencer`](#sequence-sequencer) 选项。
-
-::: details 示例
-考虑这个例子:
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- projects: [
- {
- test: {
- name: 'slow',
- sequence: {
- groupOrder: 0,
- },
- },
- },
- {
- test: {
- name: 'fast',
- sequence: {
- groupOrder: 0,
- },
- },
- },
- {
- test: {
- name: 'flaky',
- sequence: {
- groupOrder: 1,
- },
- },
- },
- ],
- },
-})
-```
-
-这些项目中的测试将按以下顺序运行:
-
-```
- 0. slow |
- |> 一起运行
- 0. fast |
-
- 1. flaky |> 在 slow 和 fast 之后单独运行
-```
-:::
-
-#### sequence.shuffle
-
-- **类型**: `boolean | { files?, tests? }`
-- **默认值**: `false`
-- **命令行终端**: `--sequence.shuffle`, `--sequence.shuffle=false`
-
-如果你希望测试随机运行,可以使用此选项或 CLI 参数 [`--sequence.shuffle`](/guide/cli) 启用它。
-
-Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试会更早开始,这会使测试运行得更快。如果你的测试将以随机顺序运行,你将失去这种性能改进,但跟踪意外依赖于先前运行的测试可能很有用。
-
-#### sequence.shuffle.files
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端**: `--sequence.shuffle.files`, `--sequence.shuffle.files=false`
-
-是否随机执行测试文件顺序。请注意,若启用此选项,耗时较长的测试将不会提前开始执行。
-
-#### sequence.shuffle.tests
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端**: `--sequence.shuffle.tests`, `--sequence.shuffle.tests=false`
-
-是否随机执行测试顺序。
-
-#### sequence.concurrent
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端**: `--sequence.concurrent`, `--sequence.concurrent=false`
-
-如果你希望测试并行运行,可以使用此选项或 CLI 参数 [`--sequence.concurrent`](/guide/cli) 启用它。
-
-#### sequence.seed
-
-- **类型**: `number`
-- **默认值**: `Date.now()`
-- **命令行终端**: `--sequence.seed=1000`
-
-如果测试以随机顺序运行,则设置随机化种子。
-
-#### sequence.hooks
-
-- **类型**: `'stack' | 'list' | 'parallel'`
-- **默认值**: `'stack'`
-- **命令行终端**: `--sequence.hooks=`
-
-更改钩子的执行顺序。
-
-- `stack` 将以相反的顺序排列 "after" 钩子,"before" 钩子将按照它们定义的顺序运行
-- `list` 将按照定义的顺序对所有钩子进行排序
-- `parallel` 将并行运行单个组中的钩子(父套件中的钩子仍将在当前套件的钩子之前运行)
-
-::: tip
-该选项不会影响 [`onTestFinished`](/api/#ontestfinished)。它总是以相反的顺序调用。
-:::
-
-#### sequence.setupFiles {#sequence-setupfiles}
-
-- **类型**: `'list' | 'parallel'`
-- **默认值**: `'parallel'`
-- **命令行终端**: `--sequence.setupFiles=`
-
-更改安装文件的执行顺序。
-
-- `list` 将按照定义的顺序运行安装文件
-- `parallel` 将并行运行设置文件
-
-### typecheck
-
-[类型测试](/guide/testing-types) 测试环境的配置选项。
-
-#### typecheck.enabled {#typecheck-enabled}
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端**: `--typecheck`, `--typecheck.enabled`
-
-在常规测试的同时启用类型检查。
-
-#### typecheck.only {#typecheck-only}
-
-- **类型**: `boolean`
-- **默认值**: `false`
-- **命令行终端**: `--typecheck.only`
-
-启用类型检查时,仅运行类型检查测试。使用 CLI 时,此选项将自动启用类型检查。
-
-#### typecheck.checker
-
-- **类型**: `'tsc' | 'vue-tsc' | string`
-- **默认值**: `tsc`
-
-设置类型检查的检测器。Vitest 将根据类型生成具有某些参数的进程,以便于解析。 Checker 应该实现与 `tsc` 相同的输出格式。
-
-你需要安装一个包才能使用 typecheker:
-
-- `tsc` requires `typescript` package
-- `vue-tsc` requires `vue-tsc` package
-
-你还可以将路径传递到自定义二进制文件或命令名称,该路径会产生与 `tsc --noEmit --pretty false` 相同的输出。
-
-#### typecheck.include
-
-- **类型**: `string[]`
-- **默认值**: `['**/*.{test,spec}-d.?(c|m)[jt]s?(x)']`
-
-匹配包含测试文件的 glob 规则。
-
-#### typecheck.exclude
-
-- **类型**: `string[]`
-- **默认值**: `['**/node_modules/**', '**/dist/**', '**/cypress/**', '**/.{idea,git,cache,output,temp}/**']`
-
-匹配排除测试文件的 glob 规则。
-
-#### typecheck.allowJs
-
-- **类型**: `boolean`
-- **默认值**: `false`
-
-检查有 `@ts-check` 注释的 JS 文件。 如果你在 tsconfig 中启用它,则不会覆盖它。
-
-#### typecheck.ignoreSourceErrors
-
-- **类型**: `boolean`
-- **默认值**: `false`
-
-如果 Vitest 在测试文件之外发现错误,不要失败。 这根本不会向你显示非测试错误。
-
-默认情况下,如果 Vitest 发现源错误,它将测试套件中抛出失败。
-
-#### typecheck.tsconfig
-
-- **类型**: `string`
-- **默认值**: _tries to find closest tsconfig.json_
-
-自定义 tsconfig 的路径,相对于项目根目录。
-
-#### typecheck.spawnTimeout
-
-- **Type**: `number`
-- **Default**: `10_000`
-
-生成类型检查器所需的最短时间(以毫秒为单位)。
-
-### slowTestThreshold
-
-- **类型**: `number`
-- **默认值**: `300`
-- **命令行终端:**:`--slow-test-threshold=`, `--slowTestThreshold=`
-
-测试或测试套件执行超过该毫秒数即被视为缓慢,并在结果中相应标注。
-
-### chaiConfig {#chaiconfig}
-
-- **类型:** `{ includeStack?, showDiff?, truncateThreshold? }`
-- **默认值:** `{ includeStack: false, showDiff: true, truncateThreshold: 40 }`
-
-等同于 [Chai 配置](https://github.com/chaijs/chai/blob/4.x.x/lib/chai/config.js)。
-
-#### chaiConfig.includeStack
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-影响断言错误消息中是否包含堆栈跟踪。默认值为 false,在错误消息中抑制堆栈跟踪。
-
-#### chaiConfig.showDiff
-
-- **类型:** `boolean`
-- **默认值:** `true`
-
-影响是否应在抛出的 AssertionErrors 中包含 `showDiff` 标志。`false` 始终为 `false`;`true` 将在断言请求显示差异时为 `true`。
-
-#### chaiConfig.truncateThreshold
-
-- **类型:** `number`
-- **默认值:** `40`
-
-设置断言错误中实际值和期望值的长度阈值。如果超过此阈值,例如对于大型数据结构,该值将被替换为类似 `[ Array(3) ]` 或 `{ Object (prop1, prop2) }` 的内容。如果要完全禁用截断,请将其设置为 `0`。
-
-此配置选项影响在 `test.each` 标题和断言错误消息中截断值的方式。
-
-### bail {#bail}
-
-- **类型:** `number`
-- **默认值:** `0`
-- **命令行终端**: `--bail=`
-
-当给定数量的测试失败时停止测试执行。
-
-默认情况下,即使其中一些测试失败,Vitest 也会运行你的所有测试用例。这可能不适用于 CI 构建,你只对 100% 成功的构建感兴趣,并且希望在测试失败时尽早停止测试执行。`bail` 选项可用于通过在发生故障时防止运行更多测试来加速 CI 运行。
-
-### retry {#retry}
-
-- **类型:** `number`
-- **默认值:** `0`
-- **命令行终端:** `--retry=`
-
-如果测试失败,请重试特定次数的测试。
-
-### onConsoleLog
-
-```ts
-function onConsoleLog(
- log: string,
- type: 'stdout' | 'stderr',
- entity: TestModule | TestSuite | TestCase | undefined,
-): boolean | void
-```
-
-用于自定义处理测试中调用的 `console` 方法。如果返回值是 `false` , Vitest 将不会将日志打印到控制台。需要注意的是, Vitest 会忽略除 `false` 之外的其他假值。
-
-这在过滤掉来自第三方库的日志时会非常有用。
-
-```ts
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- onConsoleLog(log: string, type: 'stdout' | 'stderr'): boolean | void {
- return !(log === 'message from third party library' && type === 'stdout')
- },
- },
-})
-```
-
-### onStackTrace {#onstacktrace}
-
-- **类型**: `(error: Error, frame: ParsedStack) => boolean | void`
-
-在处理错误时,对每个堆栈的每个帧应用过滤功能。第一个参数 `error` 是一个与标准 `Error` 具有相同属性的对象,但它不是实际实例。
-
-可用于从第三方库中筛选堆栈跟踪帧。
-
-```ts
-import type { ParsedStack } from 'vitest'
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- onStackTrace(error: Error, { file }: ParsedStack): boolean | void {
- // 如果我们遇到引用错误,显示整个堆栈。
- if (error.name === 'ReferenceError') {
- return
- }
-
- // 拒绝来自第三方库的所有框架。
- if (file.includes('node_modules')) {
- return false
- }
- },
- },
-})
-```
-
-### onUnhandledError {#onunhandlederror}
-
-- **类型:** `(error: (TestError | Error) & { type: string }) => boolean | void`
-
-自定义处理程序,用于过滤掉不应报告的未处理错误。 如果过滤掉错误,则不会再影响测试结果。
-
-如果你希望报告未处理的错误而不影响测试结果,可以考虑使用 [`dangerouslyIgnoreUnhandledErrors`](#dangerouslyIgnoreUnhandledErrors) 选项
-
-```ts
-import type { ParsedStack } from 'vitest'
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- onUnhandledError(error): boolean | void {
- // 忽略名为 “MySpecialError” 的所有错误。
- if (error.name === 'MySpecialError') {
- return false
- }
- },
- },
-})
-```
-
-### diff
-
-- **类型:** `string`
-- **命令行终端:** `--diff=`
-
-`DiffOptions` 对象或者是一个导出 `DiffOptions` 的模块路径。如果我们想要自定义差异显示,这将非常有用。
-
-例如,作为一个配置对象:
-
-```ts
-import c from 'picocolors'
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- diff: {
- aIndicator: c.bold('--'),
- bIndicator: c.bold('++'),
- omitAnnotationLines: true,
- },
- },
-})
-```
-
-Or as a module:
-
-:::code-group
-```ts [vitest.config.js]
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- diff: './vitest.diff.ts',
- },
-})
-```
-
-```ts [vitest.diff.ts]
-import type { DiffOptions } from 'vitest'
-import c from 'picocolors'
-
-export default {
- aIndicator: c.bold('--'),
- bIndicator: c.bold('++'),
- omitAnnotationLines: true,
-} satisfies DiffOptions
-```
-:::
-
-#### diff.expand
-
-- **类型**: `boolean`
-- **默认值**: `true`
-- **命令行终端:** `--diff.expand=false`
-
-Expand all common lines.
-
-#### diff.truncateThreshold
-
-- **类型**: `number`
-- **默认值**: `0`
-- **命令行终端:** `--diff.truncateThreshold=`
-
-要显示的差异结果的最大长度。超过此阈值的差异将被截断。
-默认值为 0 时,截断不会生效。
-
-#### diff.truncateAnnotation
-
-- **类型**: `string`
-- **默认值**: `'... Diff result is truncated'`
-- **命令行终端:** `--diff.truncateAnnotation=`
-
-在 diff 结果末尾输出的注释(如果被截断)。
-
-#### diff.truncateAnnotationColor
-
-- **类型**: `DiffOptionsColor = (arg: string) => string`
-- **默认值**: `noColor = (string: string): string => string`
-
-截断注释的颜色,默认为无色输出。
-
-#### diff.printBasicPrototype
-
-- **类型**: `boolean`
-- **默认值**: `false`
-
-在差异输出中打印基本原型 `Object` 和 `Array`
-
-#### diff.maxDepth
-
-- **类型**: `number`
-- **默认值**: `20`(当比较不同类型时或 `8` )
-
-打印嵌套对象时限制递归深度
-
-### fakeTimers
-
-- **类型:** `FakeTimerInstallOpts`
-
-当使用 [`vi.useFakeTimers()`](/api/vi#vi-usefaketimers)时,Vitest 将向 [`@sinon/fake-timers`](https://www.npmjs.com/package/@sinonjs/fake-timers) 传递的选项。
-
-#### fakeTimers.now
-
-- **类型:** `number | Date`
-- **默认值:** `Date.now()`
-
-用指定的 unix 时间安装假计时器。
-
-#### fakeTimers.toFake
-
-- **类型:** `('setTimeout' | 'clearTimeout' | 'setImmediate' | 'clearImmediate' | 'setInterval' | 'clearInterval' | 'Date' | 'nextTick' | 'hrtime' | 'requestAnimationFrame' | 'cancelAnimationFrame' | 'requestIdleCallback' | 'cancelIdleCallback' | 'performance' | 'queueMicrotask')[]`
-- **默认值:** 除 `nextTick` 和 `queueMicrotask` 外的所有全局可用方法
-
-包含要伪造的全局方法和 API 名称的数组。
-
-要只模拟 `setTimeout()` 和 `nextTick()` ,请将此属性指定为 `['setTimeout','nextTick']`。
-
-使用 `--pool=forks` 在 `node:child_process` 内运行 Vitest 时,不支持模拟 `nextTick`。NodeJS 在 `node:child_process` 中内部使用了 `process.nextTick`,当模拟它时会挂起。使用 `--pool=threads` 运行 Vitest 时支持模拟 `nextTick`。
-
-#### fakeTimers.loopLimit
-
-- **类型:** `number`
-- **默认值:** `10_000`
-
-调用 [`vi.runAllTimers()`](/api/vi#vi-runalltimers) 时将运行的计时器的最大数量。
-
-#### fakeTimers.shouldAdvanceTime
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-告诉 @sinonjs/fake-timers 根据实际系统时间的变化自动递增模拟时间(例如,实际系统时间每变化 20 毫秒,模拟时间就递增 20 毫秒)。
-
-#### fakeTimers.advanceTimeDelta
-
-- **类型:** `number`
-- **默认值:** `20`
-
-只有在和 `shouldAdvanceTime: true` 一起使用时才相关。实际系统时间每发生一次 advanceTimeDelta ms 变化,模拟时间就增加一次 advanceTimeDelta ms。
-
-#### fakeTimers.shouldClearNativeTimers
-
-- **类型:** `boolean`
-- **默认值:** `true`
-
-通过委托各自的处理程序,告诉假冒计时器清除 "native"(即非假冒)计时器。禁用时,如果计时器在启动假计时器会话之前已经存在,则可能导致意外行为。
-
-### projects {#projects}
-
-- **类型:** `TestProjectConfiguration[]`
-- **默认值:** `[]`
-
-一个由多个 [项目](/guide/projects) 组成的数组。
-
-### isolate
-
-- **类型:** `boolean`
-- **默认值:** `true`
-- **命令行终端:** `--no-isolate`, `--isolate=false`
-
-在隔离的环境中运行测试。此选项对 `vmThreads` 和 `vmForks` 池没有影响。
-
-如果你的代码不依赖于副作用(这在 `node` 环境的项目通常如此),禁用此选项可能会 [性能提升](/guide/improving-performance)。
-
-::: tip
-你可以使用 [`poolOptions`](#poolOptions) 属性禁用特定池的隔离。
-:::
-
-### includeTaskLocation {#includeTaskLocation}
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-Vitest API 在 [reporters](#reporters) 中接收任务时是否应包含`location`属性。如果我们有大量测试,这可能会导致性能小幅下降。
-
-`location` 属性的 `列` 和 `行` 值与原始文件中的 `test` 或 `describe` 位置相对应。
-
-如果我们没有明确禁用该选项,并且在运行 Vitest 时使用了该选项,则该选项将自动启用:
-- [Vitest UI](/guide/ui)
-- 或使用不带 [headless](/guide/browser/#headless) 模式的 [浏览器模式](/guide/browser/)
-- 或使用[HTML 报告器](/guide/reporters#html-reporter)
-
-::: tip
-如果不使用依赖于该选项的自定义代码,该选项将不起作用。
-:::
-
-### snapshotEnvironment {#snapshotEnvironment}
-
-- **类型:** `string`
-
-自定义快照环境实现的路径。如果在不支持 Node.js API 的环境中运行测试,该选项将非常有用。此选项对浏览器运行程序没有任何影响。
-
-该对象应具有 `SnapshotEnvironment` 的形状,用于解析和读/写快照文件:
-
-```ts
-export interface SnapshotEnvironment {
- getVersion: () => string
- getHeader: () => string
- resolvePath: (filepath: string) => Promise
- resolveRawPath: (testPath: string, rawPath: string) => Promise
- saveSnapshotFile: (filepath: string, snapshot: string) => Promise
- readSnapshotFile: (filepath: string) => Promise
- removeSnapshotFile: (filepath: string) => Promise
-}
-```
-
-如果只需覆盖部分 API,可从 `vitest/snapshot` 入口扩展默认的 `VitestSnapshotEnvironment` 。
-
-::: warning
-这是一个低级选项,仅适用于无法访问默认 Node.js API 的高级情况。
-
-如果只需要配置快照功能,请使用 [`snapshotFormat`](#snapshotformat)或 [`resolveSnapshotPath`](#resolvesnapshotpath)选项。
-:::
-
-### env {#env}
-
-- **类型:** `Partial`
-
-测试期间在 `process.env` 和 `import.meta.env` 中可用的环境变量。这些变量在主进程中不可用(例如在 `globalSetup` 中)。
-
-### expect
-
-- **类型:** `ExpectOptions`
-
-#### expect.requireAssertions
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-与每次测试开始时调用 [`expect.hasAssertions()`](/api/expect#expect-hasassertions) 相同。这可确保不会意外通过任何测试。
-
-::: tip
-这仅适用于 Vitest 的`expect`。如果我们使用`assert`或`.should`断言,它们将不计算在内,并且我们的测试将因缺少 expect 断言而失败。
-
-我们可以通过调用 `vi.setConfig({ expect: { requireAssertions: false } })` 来更改此值。该配置将应用于每个后续 `expect` 调用,直到手动调用 `vi.resetConfig`。
-:::
-
-#### expect.poll
-
-[`expect.poll`](/api/expect#poll) 的全局配置选项。这些选项与我们可以传递给 `expect.poll(condition, options)` 的选项相同。
-
-##### expect.poll.interval
-
-- **类型:** `number`
-- **默认值:** `50`
-
-轮询间隔(以毫秒为单位)
-
-##### expect.poll.timeout
-
-- **类型:** `number`
-- **默认值:** `1000`
-
-轮询超时时间(以毫秒为单位)
-
-### printConsoleTrace
-
-- **类型:** `boolean`
-- **默认值:** `false`
-
-每次调用 `console` 方法时都输出堆栈追踪信息,这对于排查问题非常有帮助。
-
-### attachmentsDir 3.2.0 {#attachmentsdir}
-
-- **类型:** `string`
-- **默认值:** `'.vitest-attachments'`
-
-相对于项目根目录,用于保存通过 [`context.annotate`](/guide/test-context#annotate) 方法生成的附件文件的目录路径。
+
+Configuration options that are not supported inside a [project](/guide/projects) config have icon next to them. This means they can only be set in the root Vitest config.
diff --git a/config/isolate.md b/config/isolate.md
new file mode 100644
index 00000000..a92f055e
--- /dev/null
+++ b/config/isolate.md
@@ -0,0 +1,18 @@
+---
+title: isolate | Config
+outline: deep
+---
+
+# isolate
+
+- **Type:** `boolean`
+- **Default:** `true`
+- **CLI:** `--no-isolate`, `--isolate=false`
+
+Run tests in an isolated environment. This option has no effect on `vmThreads` and `vmForks` pools.
+
+Disabling this option might [improve performance](/guide/improving-performance) if your code doesn't rely on side effects (which is usually true for projects with `node` environment).
+
+::: tip
+You can disable isolation for specific test files by using Vitest workspaces and disabling isolation per project.
+:::
diff --git a/config/logheapusage.md b/config/logheapusage.md
new file mode 100644
index 00000000..a29f251c
--- /dev/null
+++ b/config/logheapusage.md
@@ -0,0 +1,12 @@
+---
+title: logHeapUsage | Config
+outline: deep
+---
+
+# logHeapUsage
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI:** `--logHeapUsage`, `--logHeapUsage=false`
+
+Show heap usage after each test. Useful for debugging memory leaks.
diff --git a/config/maxconcurrency.md b/config/maxconcurrency.md
new file mode 100644
index 00000000..6026efe7
--- /dev/null
+++ b/config/maxconcurrency.md
@@ -0,0 +1,14 @@
+---
+title: maxConcurrency | Config
+outline: deep
+---
+
+# maxConcurrency
+
+- **Type**: `number`
+- **Default**: `5`
+- **CLI**: `--max-concurrency=10`, `--maxConcurrency=10`
+
+A number of tests that are allowed to run at the same time marked with `test.concurrent`.
+
+Test above this limit will be queued to run when available slot appears.
diff --git a/config/maxworkers.md b/config/maxworkers.md
new file mode 100644
index 00000000..4aa63778
--- /dev/null
+++ b/config/maxworkers.md
@@ -0,0 +1,54 @@
+---
+title: maxWorkers | Config
+outline: deep
+---
+
+# maxWorkers
+
+- **Type:** `number | string`
+- **Default:**
+ - if [`watch`](/config/watch) is disabled, uses all available parallelism
+ - if [`watch`](/config/watch) is enabled, uses half of all available parallelism
+
+Defines the maximum concurrency for test workers. Accepts either a number or a percentage string.
+
+- Number: spawns up to the specified number of workers.
+- Percentage string (e.g., "50%"): computes the worker count as the given percentage of the machine’s available parallelism.
+
+## Example
+
+### Number
+
+::: code-group
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ maxWorkers: 4,
+ },
+})
+```
+```bash [CLI]
+vitest --maxWorkers=4
+```
+:::
+
+### Percent
+
+::: code-group
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ maxWorkers: '50%',
+ },
+})
+```
+```bash [CLI]
+vitest --maxWorkers=50%
+```
+:::
+
+Vitest uses [`os.availableParallelism`](https://nodejs.org/api/os.html#osavailableparallelism) to know the maximum amount of parallelism available.
diff --git a/config/mockreset.md b/config/mockreset.md
new file mode 100644
index 00000000..fac9b6b7
--- /dev/null
+++ b/config/mockreset.md
@@ -0,0 +1,23 @@
+---
+title: mockReset | Config
+outline: deep
+---
+
+# mockReset
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Should Vitest automatically call [`vi.resetAllMocks()`](/api/vi#vi-resetallmocks) before each test.
+
+This will clear mock history and reset each implementation.
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ mockReset: true,
+ },
+})
+```
diff --git a/config/mode.md b/config/mode.md
new file mode 100644
index 00000000..5e45a97e
--- /dev/null
+++ b/config/mode.md
@@ -0,0 +1,12 @@
+---
+title: mode | Config
+outline: deep
+---
+
+# mode
+
+- **Type:** `string`
+- **CLI:** `--mode=staging`
+- **Default:** `'test'`
+
+Overrides Vite mode
diff --git a/config/name.md b/config/name.md
new file mode 100644
index 00000000..26b8c6fa
--- /dev/null
+++ b/config/name.md
@@ -0,0 +1,115 @@
+---
+title: name | Config
+---
+
+# name
+
+- **Type:**
+
+```ts
+interface UserConfig {
+ name?: string | { label: string; color?: LabelColor }
+}
+```
+
+Assign a custom name to the test project or Vitest process. The name will be visible in the CLI and UI, and available in the Node.js API via [`project.name`](/api/advanced/test-project#name).
+
+The color used by the CLI and UI can be changed by providing an object with a `color` property.
+
+## Colors
+
+The displayed colors depend on your terminal’s color scheme. In the UI, colors match their CSS equivalents.
+
+- black
+- red
+- green
+- yellow
+- blue
+- magenta
+- cyan
+- white
+
+## Example
+
+::: code-group
+```js [string]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ name: 'unit',
+ },
+})
+```
+```js [object]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ name: {
+ label: 'unit',
+ color: 'blue',
+ },
+ },
+})
+```
+:::
+
+This property is mostly useful if you have several projects as it helps distinguish them in your terminal:
+
+```js{7,11} [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ name: 'unit',
+ include: ['./test/*.unit.test.js'],
+ },
+ {
+ name: 'e2e',
+ include: ['./test/*.e2e.test.js'],
+ },
+ ],
+ },
+})
+```
+
+::: tip
+Vitest automatically assigns a name when none is provided. Resolution order:
+
+- If the project is specified by a config file or directory, Vitest uses the package.json's `name` field.
+- If there is no `package.json`, Vitest falls back to the project folder's basename.
+- If the project is defined inline in the `projects` array (an object), Vitest assigns a numeric name equal to that project's array index (0-based).
+:::
+
+::: warning
+Note that projects cannot have the same name. Vitest will throw an error during the config resolution.
+:::
+
+You can also assign different names to different browser [instances](/config/browser/instances):
+
+```js{10,11} [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+import { playwright } from '@vitest/browser-playwright'
+
+export default defineConfig({
+ test: {
+ browser: {
+ enabled: true,
+ provider: playwright(),
+ instances: [
+ { browser: 'chromium', name: 'Chrome' },
+ { browser: 'firefox', name: 'Firefox' },
+ ],
+ },
+ },
+})
+```
+
+::: tip
+Browser instances inherit their parent project's name with the browser name appended in parentheses. For example, a project named `browser` with a chromium instance will be shown as `browser (chromium)`.
+
+If the parent project has no name, or instances are defined at the root level (not inside a named project), the instance name defaults to the browser value (e.g. `chromium`). To override this behavior, set an explicit `name` on the instance.
+:::
diff --git a/config/onconsolelog.md b/config/onconsolelog.md
new file mode 100644
index 00000000..bd4d3417
--- /dev/null
+++ b/config/onconsolelog.md
@@ -0,0 +1,30 @@
+---
+title: onConsoleLog | Config
+outline: deep
+---
+
+# onConsoleLog
+
+```ts
+function onConsoleLog(
+ log: string,
+ type: 'stdout' | 'stderr',
+ entity: TestModule | TestSuite | TestCase | undefined,
+): boolean | void
+```
+
+Custom handler for `console` methods in tests. If you return `false`, Vitest will not print the log to the console. Note that Vitest ignores all other falsy values.
+
+Can be useful for filtering out logs from third-party libraries.
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ onConsoleLog(log: string, type: 'stdout' | 'stderr'): boolean | void {
+ return !(log === 'message from third party library' && type === 'stdout')
+ },
+ },
+})
+```
diff --git a/config/onstacktrace.md b/config/onstacktrace.md
new file mode 100644
index 00000000..920284a0
--- /dev/null
+++ b/config/onstacktrace.md
@@ -0,0 +1,37 @@
+---
+title: onStackTrace | Config
+outline: deep
+---
+
+# onStackTrace
+
+- **Type**: `(error: Error, frame: ParsedStack) => boolean | void`
+
+Apply a filtering function to each frame of each stack trace when handling errors. This does not apply to stack traces printed by [`printConsoleTrace`](#printConsoleTrace). The first argument, `error`, is a `TestError`.
+
+Can be useful for filtering out stack trace frames from third-party libraries.
+
+::: tip
+The stack trace's total size is also typically limited by V8's [`Error.stackTraceLimit`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stackTraceLimit) number. You could set this to a high value in your test setup function to prevent stacks from being truncated.
+:::
+
+```ts
+import type { ParsedStack, TestError } from 'vitest'
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ onStackTrace(error: TestError, { file }: ParsedStack): boolean | void {
+ // If we've encountered a ReferenceError, show the whole stack.
+ if (error.name === 'ReferenceError') {
+ return
+ }
+
+ // Reject all frames from third party libraries.
+ if (file.includes('node_modules')) {
+ return false
+ }
+ },
+ },
+})
+```
diff --git a/config/onunhandlederror.md b/config/onunhandlederror.md
new file mode 100644
index 00000000..ec7b2dbe
--- /dev/null
+++ b/config/onunhandlederror.md
@@ -0,0 +1,40 @@
+---
+title: onUnhandledError | Config
+outline: deep
+---
+
+# onUnhandledError 4.0.0
+
+- **Type:**
+
+```ts
+function onUnhandledError(
+ error: (TestError | Error) & { type: string }
+): boolean | void
+```
+
+A custom callback for filtering unhandled errors that should not be reported. When an error is filtered out, it no longer affects the result of the test run.
+
+To report unhandled errors without affecting the test outcome, use the [`dangerouslyIgnoreUnhandledErrors`](/config/dangerouslyignoreunhandlederrors) option instead.
+
+::: tip
+This callback is called on the main thread, it doesn't have access to your test context.
+:::
+
+## Example
+
+```ts
+import type { ParsedStack } from 'vitest'
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ onUnhandledError(error): boolean | void {
+ // Ignore all errors with the name "MySpecialError".
+ if (error.name === 'MySpecialError') {
+ return false
+ }
+ },
+ },
+})
+```
diff --git a/config/open.md b/config/open.md
new file mode 100644
index 00000000..65c2c08f
--- /dev/null
+++ b/config/open.md
@@ -0,0 +1,12 @@
+---
+title: open | Config
+outline: deep
+---
+
+# open
+
+- **Type:** `boolean`
+- **Default:** `!process.env.CI`
+- **CLI:** `--open`, `--open=false`
+
+Open Vitest UI automatically if it's [enabled](/config/ui).
diff --git a/config/outputfile.md b/config/outputfile.md
new file mode 100644
index 00000000..fc87b029
--- /dev/null
+++ b/config/outputfile.md
@@ -0,0 +1,12 @@
+---
+title: outputFile | Config
+outline: deep
+---
+
+# outputFile {#outputfile}
+
+- **Type:** `string | Record`
+- **CLI:** `--outputFile=`, `--outputFile.json=./path`
+
+Write test results to a file when the `--reporter=json`, `--reporter=html` or `--reporter=junit` option is also specified.
+By providing an object instead of a string you can define individual outputs when using multiple reporters.
diff --git a/config/passwithnotests.md b/config/passwithnotests.md
new file mode 100644
index 00000000..eb4bbe2e
--- /dev/null
+++ b/config/passwithnotests.md
@@ -0,0 +1,12 @@
+---
+title: passWithNoTests | Config
+outline: deep
+---
+
+# passWithNoTests
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI:** `--passWithNoTests`, `--passWithNoTests=false`
+
+Vitest will not fail, if no tests will be found.
diff --git a/config/pool.md b/config/pool.md
new file mode 100644
index 00000000..f9d1eac2
--- /dev/null
+++ b/config/pool.md
@@ -0,0 +1,50 @@
+---
+title: pool | Config
+outline: deep
+---
+
+# pool
+
+- **Type:** `'threads' | 'forks' | 'vmThreads' | 'vmForks'`
+- **Default:** `'forks'`
+- **CLI:** `--pool=threads`
+
+Pool used to run tests in.
+
+## threads
+
+Enable multi-threading. When using threads you are unable to use process related APIs such as `process.chdir()`. Some libraries written in native languages, such as Prisma, `bcrypt` and `canvas`, have problems when running in multiple threads and run into segfaults. In these cases it is advised to use `forks` pool instead.
+
+## forks
+
+Similar as `threads` pool but uses `child_process` instead of `worker_threads`. Communication between tests and main process is not as fast as with `threads` pool. Process related APIs such as `process.chdir()` are available in `forks` pool.
+
+## vmThreads
+
+Run tests using [VM context](https://nodejs.org/api/vm.html) (inside a sandboxed environment) in a `threads` pool.
+
+This makes tests run faster, but the VM module is unstable when running [ESM code](https://github.com/nodejs/node/issues/37648). Your tests will [leak memory](https://github.com/nodejs/node/issues/33439) - to battle that, consider manually editing [`vmMemoryLimit`](#vmMemorylimit) value.
+
+::: warning
+Running code in a sandbox has some advantages (faster tests), but also comes with a number of disadvantages.
+
+- The globals within native modules, such as (`fs`, `path`, etc), differ from the globals present in your test environment. As a result, any error thrown by these native modules will reference a different Error constructor compared to the one used in your code:
+
+```ts
+try {
+ fs.writeFileSync('/doesnt exist')
+}
+catch (err) {
+ console.log(err instanceof Error) // false
+}
+```
+
+- Importing ES modules caches them indefinitely which introduces memory leaks if you have a lot of contexts (test files). There is no API in Node.js that clears that cache.
+- Accessing globals [takes longer](https://github.com/nodejs/node/issues/31658) in a sandbox environment.
+
+Please, be aware of these issues when using this option. Vitest team cannot fix any of the issues on our side.
+:::
+
+## vmForks
+
+Similar as `vmThreads` pool but uses `child_process` instead of `worker_threads`. Communication between tests and the main process is not as fast as with `vmThreads` pool. Process related APIs such as `process.chdir()` are available in `vmForks` pool. Please be aware that this pool has the same pitfalls listed in `vmThreads`.
diff --git a/config/printconsoletrace.md b/config/printconsoletrace.md
new file mode 100644
index 00000000..8552b6cd
--- /dev/null
+++ b/config/printconsoletrace.md
@@ -0,0 +1,11 @@
+---
+title: printConsoleTrace | Config
+outline: deep
+---
+
+# printConsoleTrace
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Always print console traces when calling any `console` method. This is useful for debugging.
diff --git a/config/projects.md b/config/projects.md
new file mode 100644
index 00000000..761861d1
--- /dev/null
+++ b/config/projects.md
@@ -0,0 +1,11 @@
+---
+title: projects | Config
+outline: deep
+---
+
+# projects
+
+- **Type:** `TestProjectConfiguration[]`
+- **Default:** `[]`
+
+An array of [projects](/guide/projects).
diff --git a/config/provide.md b/config/provide.md
new file mode 100644
index 00000000..6eb1347b
--- /dev/null
+++ b/config/provide.md
@@ -0,0 +1,50 @@
+---
+title: provide | Config
+outline: deep
+---
+
+# provide
+
+- **Type:** `Partial`
+
+Define values that can be accessed inside your tests using `inject` method.
+
+:::code-group
+```ts [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ provide: {
+ API_KEY: '123',
+ },
+ },
+})
+```
+```ts [api.test.js]
+import { expect, inject, test } from 'vitest'
+
+test('api key is defined', () => {
+ expect(inject('API_KEY')).toBe('123')
+})
+```
+:::
+
+::: warning
+Properties have to be strings and values need to be [serializable](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types) because this object will be transferred between different processes.
+:::
+
+::: tip
+If you are using TypeScript, you will need to augment `ProvidedContext` type for type safe access:
+
+```ts [vitest.shims.d.ts]
+declare module 'vitest' {
+ export interface ProvidedContext {
+ API_KEY: string
+ }
+}
+
+// mark this file as a module so augmentation works correctly
+export {}
+```
+:::
diff --git a/config/reporters.md b/config/reporters.md
new file mode 100644
index 00000000..d79ae59c
--- /dev/null
+++ b/config/reporters.md
@@ -0,0 +1,72 @@
+---
+title: reporters | Config
+---
+
+# reporters
+
+- **Type:**
+
+```ts
+interface UserConfig {
+ reporters?: ConfigReporter | Array
+}
+
+type ConfigReporter = string | Reporter | [string, object?]
+```
+
+- **Default:** [`'default'`](/guide/reporters#default-reporter)
+- **CLI:**
+ - `--reporter=tap` for a single reporter
+ - `--reporter=verbose --reporter=github-actions` for multiple reporters
+
+This option defines a single reporter or a list of reporters available to Vitest during the test run.
+
+Alongside built-in reporters, you can also pass down a custom implementation of a [`Reporter` interface](/api/advanced/reporters), or a path to a module that exports it as a default export (e.g. `'./path/to/reporter.ts'`, `'@scope/reporter'`).
+
+You can configure a reporter by providing a tuple: `[string, object]`, where the string is a reporter name, and the object is the reporter's options.
+
+::: warning
+Note that the [coverage](/guide/coverage) feature uses a different [`coverage.reporter`](/config/coverage#reporter) option instead of this one.
+:::
+
+## Built-in Reporters
+
+- [`default`](/guide/reporters#default-reporter)
+- [`verbose`](/guide/reporters#verbose-reporter)
+- [`tree`](/guide/reporters#tree-reporter)
+- [`dot`](/guide/reporters#dot-reporter)
+- [`junit`](/guide/reporters#junit-reporter)
+- [`json`](/guide/reporters#json-reporter)
+- [`html`](/guide/reporters#html-reporter)
+- [`tap`](/guide/reporters#tap-reporter)
+- [`tap-flat`](/guide/reporters#tap-flat-reporter)
+- [`hanging-process`](/guide/reporters#hanging-process-reporter)
+- [`github-actions`](/guide/reporters#github-actions-reporter)
+- [`blob`](/guide/reporters#blob-reporter)
+
+## Example
+
+::: code-group
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ reporters: [
+ 'default',
+ // conditional reporter
+ process.env.CI ? 'github-actions' : {},
+ // custom reporter from npm package
+ // options are passed down as a tuple
+ [
+ 'vitest-sonar-reporter',
+ { outputFile: 'sonar-report.xml' }
+ ],
+ ]
+ }
+})
+```
+```bash [CLI]
+vitest --reporter=github-actions --reporter=junit
+```
+:::
diff --git a/config/resolvesnapshotpath.md b/config/resolvesnapshotpath.md
new file mode 100644
index 00000000..981ff412
--- /dev/null
+++ b/config/resolvesnapshotpath.md
@@ -0,0 +1,21 @@
+---
+title: resolveSnapshotPath | Config
+outline: deep
+---
+
+# resolveSnapshotPath
+
+- **Type**: `(testPath: string, snapExtension: string, context: { config: SerializedConfig }) => string`
+- **Default**: stores snapshot files in `__snapshots__` directory
+
+Overrides default snapshot path. For example, to store snapshots next to test files:
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ resolveSnapshotPath: (testPath, snapExtension) => testPath + snapExtension,
+ },
+})
+```
diff --git a/config/restoremocks.md b/config/restoremocks.md
new file mode 100644
index 00000000..00638008
--- /dev/null
+++ b/config/restoremocks.md
@@ -0,0 +1,23 @@
+---
+title: restoreMocks | Config
+outline: deep
+---
+
+# restoreMocks
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Should Vitest automatically call [`vi.restoreAllMocks()`](/api/vi#vi-restoreallmocks) before each test.
+
+This restores all original implementations on spies created manually with [`vi.spyOn`](/api/vi#vi-spyon).
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ restoreMocks: true,
+ },
+})
+```
diff --git a/config/retry.md b/config/retry.md
new file mode 100644
index 00000000..48c0e8f1
--- /dev/null
+++ b/config/retry.md
@@ -0,0 +1,12 @@
+---
+title: retry | Config
+outline: deep
+---
+
+# retry
+
+- **Type:** `number`
+- **Default:** `0`
+- **CLI:** `--retry=`
+
+Retry the test specific number of times if it fails.
diff --git a/config/root.md b/config/root.md
new file mode 100644
index 00000000..3b4a429c
--- /dev/null
+++ b/config/root.md
@@ -0,0 +1,11 @@
+---
+title: root | Config
+outline: deep
+---
+
+# root
+
+- **Type:** `string`
+- **CLI:** `-r `, `--root=`
+
+Project root
diff --git a/config/runner.md b/config/runner.md
new file mode 100644
index 00000000..aaf20871
--- /dev/null
+++ b/config/runner.md
@@ -0,0 +1,11 @@
+---
+title: runner | Config
+outline: deep
+---
+
+# runner
+
+- **Type**: `VitestRunnerConstructor`
+- **Default**: `node`, when running tests, or `benchmark`, when running benchmarks
+
+Path to a custom test runner. This is an advanced feature and should be used with custom library runners. You can read more about it in [the documentation](/api/advanced/runner).
diff --git a/config/sequence.md b/config/sequence.md
new file mode 100644
index 00000000..491a24f6
--- /dev/null
+++ b/config/sequence.md
@@ -0,0 +1,163 @@
+---
+title: sequence | Config
+outline: deep
+---
+
+# sequence
+
+- **Type**: `{ sequencer?, shuffle?, seed?, hooks?, setupFiles?, groupOrder }`
+
+Options for how tests should be sorted.
+
+You can provide sequence options to CLI with dot notation:
+
+```sh
+npx vitest --sequence.shuffle --sequence.seed=1000
+```
+
+## sequence.sequencer
+
+- **Type**: `TestSequencerConstructor`
+- **Default**: `BaseSequencer`
+
+A custom class that defines methods for sharding and sorting. You can extend `BaseSequencer` from `vitest/node`, if you only need to redefine one of the `sort` and `shard` methods, but both should exist.
+
+Sharding is happening before sorting, and only if `--shard` option is provided.
+
+If [`sequencer.groupOrder`](#grouporder) is specified, the sequencer will be called once for each group and pool.
+
+## groupOrder
+
+- **Type:** `number`
+- **Default:** `0`
+
+Controls the order in which this project runs its tests when using multiple [projects](/guide/projects).
+
+- Projects with the same group order number will run together, and groups are run from lowest to highest.
+- If you don't set this option, all projects run in parallel.
+- If several projects use the same group order, they will run at the same time.
+
+This setting only affects the order in which projects run, not the order of tests within a project.
+To control test isolation or the order of tests inside a project, use the [`isolate`](#isolate) and [`sequence.sequencer`](#sequence-sequencer) options.
+
+::: details Example
+Consider this example:
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ test: {
+ name: 'slow',
+ sequence: {
+ groupOrder: 0,
+ },
+ },
+ },
+ {
+ test: {
+ name: 'fast',
+ sequence: {
+ groupOrder: 0,
+ },
+ },
+ },
+ {
+ test: {
+ name: 'flaky',
+ sequence: {
+ groupOrder: 1,
+ },
+ },
+ },
+ ],
+ },
+})
+```
+
+Tests in these projects will run in this order:
+
+```
+ 0. slow |
+ |> running together
+ 0. fast |
+
+ 1. flaky |> runs after slow and fast alone
+```
+:::
+
+## sequence.shuffle
+
+- **Type**: `boolean | { files?, tests? }`
+- **Default**: `false`
+- **CLI**: `--sequence.shuffle`, `--sequence.shuffle=false`
+
+If you want files and tests to run randomly, you can enable it with this option, or CLI argument [`--sequence.shuffle`](/guide/cli).
+
+Vitest usually uses cache to sort tests, so long running tests start earlier - this makes tests run faster. If your files and tests will run in random order you will lose this performance improvement, but it may be useful to track tests that accidentally depend on another run previously.
+
+### sequence.shuffle.files {#sequence-shuffle-files}
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI**: `--sequence.shuffle.files`, `--sequence.shuffle.files=false`
+
+Whether to randomize files, be aware that long running tests will not start earlier if you enable this option.
+
+### sequence.shuffle.tests {#sequence-shuffle-tests}
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI**: `--sequence.shuffle.tests`, `--sequence.shuffle.tests=false`
+
+Whether to randomize tests.
+
+## sequence.concurrent {#sequence-concurrent}
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI**: `--sequence.concurrent`, `--sequence.concurrent=false`
+
+If you want tests to run in parallel, you can enable it with this option, or CLI argument [`--sequence.concurrent`](/guide/cli).
+
+::: warning
+When you run tests with `sequence.concurrent` and `expect.requireAssertions` set to `true`, you should use [local expect](/guide/test-context.html#expect) instead of the global one. Otherwise, this may cause false negatives in [some situations (#8469)](https://github.com/vitest-dev/vitest/issues/8469).
+:::
+
+## sequence.seed
+
+- **Type**: `number`
+- **Default**: `Date.now()`
+- **CLI**: `--sequence.seed=1000`
+
+Sets the randomization seed, if tests are running in random order.
+
+## sequence.hooks
+
+- **Type**: `'stack' | 'list' | 'parallel'`
+- **Default**: `'stack'`
+- **CLI**: `--sequence.hooks=`
+
+Changes the order in which hooks are executed.
+
+- `stack` will order "after" hooks in reverse order, "before" hooks will run in the order they were defined
+- `list` will order all hooks in the order they are defined
+- `parallel` will run hooks in a single group in parallel (hooks in parent suites will still run before the current suite's hooks)
+
+::: tip
+This option doesn't affect [`onTestFinished`](/api/#ontestfinished). It is always called in reverse order.
+:::
+
+## sequence.setupFiles {#sequence-setupfiles}
+
+- **Type**: `'list' | 'parallel'`
+- **Default**: `'parallel'`
+- **CLI**: `--sequence.setupFiles=`
+
+Changes the order in which setup files are executed.
+
+- `list` will run setup files in the order they are defined
+- `parallel` will run setup files in parallel
diff --git a/config/server.md b/config/server.md
new file mode 100644
index 00000000..a999b7cf
--- /dev/null
+++ b/config/server.md
@@ -0,0 +1,73 @@
+---
+title: server | Config
+outline: deep
+---
+
+# server
+
+Before Vitest 4, this option was used to define the configuration for the `vite-node` server.
+
+At the moment, this option allows you to configure the inlining and externalization mechanisms, along with the module runner debugging configuration.
+
+::: warning
+These options should be used only as the last resort to improve performance by externalizing auto-inlined dependencies or to fix issues by inlining invalid external dependencies.
+
+Normally, Vitest should do this automatically.
+:::
+
+## deps
+
+### external
+
+- **Type:** `(string | RegExp)[]`
+- **Default:** files inside [`moduleDirectories`](/config/deps#moduledirectories)
+
+Specifies modules that should not be transformed by Vite and should instead be processed directly by the engine. These modules are imported via native dynamic `import` and bypass both transformation and resolution phases.
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ server: {
+ deps: {
+ external: ['react'],
+ },
+ },
+ },
+})
+```
+
+External modules and their dependencies are not present in the module graph and will not trigger test restarts when they change.
+
+Typically, packages under `node_modules` are externalized.
+
+::: tip
+If a string is provided, it is first normalized by prefixing the `/node_modules/` or other [`moduleDirectories`](/config/deps#moduledirectories) segments (for example, `'react'` becomes `/node_modules/react/`), and the resulting string is then matched against the full file path. For example, package `@company/some-name` located inside `packages/some-name` should be specified as `some-name`, and `packages` should be included in `deps.moduleDirectories`.
+
+If a `RegExp` is provided, it is matched against the full file path.
+:::
+
+### inline
+
+- **Type:** `(string | RegExp)[] | true`
+- **Default:** everything that is not externalized
+
+Specifies modules that should be transformed and resolved by Vite. These modules are run by Vite's [module runner](https://vite.dev/guide/api-environment-runtimes#modulerunner).
+
+Typically, your source files are inlined.
+
+::: tip
+If a string is provided, it is first normalized by prefixing the `/node_modules/` or other [`moduleDirectories`](/config/deps#moduledirectories) segments (for example, `'react'` becomes `/node_modules/react/`), and the resulting string is then matched against the full file path. For example, package `@company/some-name` located inside `packages/some-name` should be specified as `some-name`, and `packages` should be included in `deps.moduleDirectories`.
+
+If a `RegExp` is provided, it is matched against the full file path.
+:::
+
+### fallbackCJS
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+When a dependency is a valid ESM package, try to guess the cjs version based on the path. This might be helpful, if a dependency has the wrong ESM file.
+
+This might potentially cause some misalignment if a package has different logic in ESM and CJS mode.
diff --git a/config/setupfiles.md b/config/setupfiles.md
new file mode 100644
index 00000000..f07fc0ea
--- /dev/null
+++ b/config/setupfiles.md
@@ -0,0 +1,39 @@
+---
+title: setupFiles | Config
+outline: deep
+---
+
+# setupFiles
+
+- **Type:** `string | string[]`
+
+Path to setup files. They will be run before each test file.
+
+:::info
+Editing a setup file will automatically trigger a rerun of all tests.
+:::
+
+You can use `process.env.VITEST_POOL_ID` (integer-like string) inside to distinguish between workers.
+
+:::tip
+Note, that if you are running [`--isolate=false`](#isolate), this setup file will be run in the same global scope multiple times. Meaning, that you are accessing the same global object before each test, so make sure you are not doing the same thing more than you need.
+:::
+
+For example, you may rely on a global variable:
+
+```ts
+import { config } from '@some-testing-lib'
+
+if (!globalThis.defined) {
+ config.plugins = [myCoolPlugin]
+ computeHeavyThing()
+ globalThis.defined = true
+}
+
+// hooks are reset before each suite
+afterEach(() => {
+ cleanup()
+})
+
+globalThis.resetBeforeEachTest = true
+```
diff --git a/config/silent.md b/config/silent.md
new file mode 100644
index 00000000..d7f11fff
--- /dev/null
+++ b/config/silent.md
@@ -0,0 +1,14 @@
+---
+title: silent | Config
+outline: deep
+---
+
+# silent {#silent}
+
+- **Type:** `boolean | 'passed-only'`
+- **Default:** `false`
+- **CLI:** `--silent`, `--silent=false`
+
+Silent console output from tests.
+
+Use `'passed-only'` to see logs from failing tests only. Logs from failing tests are printed after a test has finished.
diff --git a/config/slowtestthreshold.md b/config/slowtestthreshold.md
new file mode 100644
index 00000000..84f9594d
--- /dev/null
+++ b/config/slowtestthreshold.md
@@ -0,0 +1,12 @@
+---
+title: slowTestThreshold | Config
+outline: deep
+---
+
+# slowTestThreshold
+
+- **Type**: `number`
+- **Default**: `300`
+- **CLI**: `--slow-test-threshold=`, `--slowTestThreshold=`
+
+The number of milliseconds after which a test or suite is considered slow and reported as such in the results.
diff --git a/config/snapshotenvironment.md b/config/snapshotenvironment.md
new file mode 100644
index 00000000..889b5684
--- /dev/null
+++ b/config/snapshotenvironment.md
@@ -0,0 +1,32 @@
+---
+title: snapshotEnvironment | Config
+outline: deep
+---
+
+# snapshotEnvironment
+
+- **Type:** `string`
+
+Path to a custom snapshot environment implementation. This is useful if you are running your tests in an environment that doesn't support Node.js APIs. This option doesn't have any effect on a browser runner.
+
+This object should have the shape of `SnapshotEnvironment` and is used to resolve and read/write snapshot files:
+
+```ts
+export interface SnapshotEnvironment {
+ getVersion: () => string
+ getHeader: () => string
+ resolvePath: (filepath: string) => Promise
+ resolveRawPath: (testPath: string, rawPath: string) => Promise
+ saveSnapshotFile: (filepath: string, snapshot: string) => Promise
+ readSnapshotFile: (filepath: string) => Promise
+ removeSnapshotFile: (filepath: string) => Promise
+}
+```
+
+You can extend default `VitestSnapshotEnvironment` from `vitest/snapshot` entry point if you need to overwrite only a part of the API.
+
+::: warning
+This is a low-level option and should be used only for advanced cases where you don't have access to default Node.js APIs.
+
+If you just need to configure snapshots feature, use [`snapshotFormat`](#snapshotformat) or [`resolveSnapshotPath`](#resolvesnapshotpath) options.
+:::
diff --git a/config/snapshotformat.md b/config/snapshotformat.md
new file mode 100644
index 00000000..d0e00fc3
--- /dev/null
+++ b/config/snapshotformat.md
@@ -0,0 +1,16 @@
+---
+title: snapshotFormat | Config
+outline: deep
+---
+
+# snapshotFormat
+
+- **Type:** `PrettyFormatOptions`
+
+Format options for snapshot testing. These options are passed down to our fork of [`pretty-format`](https://www.npmjs.com/package/pretty-format). In addition to the `pretty-format` options we support `printShadowRoot: boolean`.
+
+::: tip
+Beware that `plugins` field on this object will be ignored.
+
+If you need to extend snapshot serializer via pretty-format plugins, please, use [`expect.addSnapshotSerializer`](/api/expect#expect-addsnapshotserializer) API or [snapshotSerializers](#snapshotserializers) option.
+:::
diff --git a/config/snapshotserializers.md b/config/snapshotserializers.md
new file mode 100644
index 00000000..0a1ae9a7
--- /dev/null
+++ b/config/snapshotserializers.md
@@ -0,0 +1,11 @@
+---
+title: snapshotSerializers | Config
+outline: deep
+---
+
+# snapshotSerializers
+
+- **Type:** `string[]`
+- **Default:** `[]`
+
+A list of paths to snapshot serializer modules for snapshot testing, useful if you want add custom snapshot serializers. See [Custom Serializer](/guide/snapshot#custom-serializer) for more information.
diff --git a/config/teardowntimeout.md b/config/teardowntimeout.md
new file mode 100644
index 00000000..1fc9365a
--- /dev/null
+++ b/config/teardowntimeout.md
@@ -0,0 +1,12 @@
+---
+title: teardownTimeout | Config
+outline: deep
+---
+
+# teardownTimeout {#teardowntimeout}
+
+- **Type:** `number`
+- **Default:** `10000`
+- **CLI:** `--teardown-timeout=5000`, `--teardownTimeout=5000`
+
+Default timeout to wait for close when Vitest shuts down, in milliseconds
diff --git a/config/testnamepattern.md b/config/testnamepattern.md
new file mode 100644
index 00000000..7e4b4098
--- /dev/null
+++ b/config/testnamepattern.md
@@ -0,0 +1,26 @@
+---
+title: testNamePattern | Config
+outline: deep
+---
+
+# testNamePattern {#testnamepattern}
+
+- **Type** `string | RegExp`
+- **CLI:** `-t `, `--testNamePattern=`, `--test-name-pattern=`
+
+Run tests with full names matching the pattern.
+If you add `OnlyRunThis` to this property, tests not containing the word `OnlyRunThis` in the test name will be skipped.
+
+```js
+import { expect, test } from 'vitest'
+
+// run
+test('OnlyRunThis', () => {
+ expect(true).toBe(true)
+})
+
+// skipped
+test('doNotRun', () => {
+ expect(true).toBe(true)
+})
+```
diff --git a/config/testtimeout.md b/config/testtimeout.md
new file mode 100644
index 00000000..9132d255
--- /dev/null
+++ b/config/testtimeout.md
@@ -0,0 +1,12 @@
+---
+title: testTimeout | Config
+outline: deep
+---
+
+# testTimeout
+
+- **Type:** `number`
+- **Default:** `5_000` in Node.js, `15_000` if `browser.enabled` is `true`
+- **CLI:** `--test-timeout=5000`, `--testTimeout=5000`
+
+Default timeout of a test in milliseconds. Use `0` to disable timeout completely.
diff --git a/config/typecheck.md b/config/typecheck.md
new file mode 100644
index 00000000..cae1854a
--- /dev/null
+++ b/config/typecheck.md
@@ -0,0 +1,82 @@
+---
+title: typecheck | Config
+outline: deep
+---
+
+# typecheck {#typecheck}
+
+Options for configuring [typechecking](/guide/testing-types) test environment.
+
+## typecheck.enabled {#typecheck-enabled}
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI**: `--typecheck`, `--typecheck.enabled`
+
+Enable typechecking alongside your regular tests.
+
+## typecheck.only {#typecheck-only}
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **CLI**: `--typecheck.only`
+
+Run only typecheck tests, when typechecking is enabled. When using CLI, this option will automatically enable typechecking.
+
+## typecheck.checker
+
+- **Type**: `'tsc' | 'vue-tsc' | string`
+- **Default**: `tsc`
+
+What tools to use for type checking. Vitest will spawn a process with certain parameters for easier parsing, depending on the type. Checker should implement the same output format as `tsc`.
+
+You need to have a package installed to use typechecker:
+
+- `tsc` requires `typescript` package
+- `vue-tsc` requires `vue-tsc` package
+
+You can also pass down a path to custom binary or command name that produces the same output as `tsc --noEmit --pretty false`.
+
+## typecheck.include
+
+- **Type**: `string[]`
+- **Default**: `['**/*.{test,spec}-d.?(c|m)[jt]s?(x)']`
+
+Glob pattern for files that should be treated as test files
+
+## typecheck.exclude
+
+- **Type**: `string[]`
+- **Default**: `['**/node_modules/**', '**/dist/**', '**/cypress/**', '**/.{idea,git,cache,output,temp}/**']`
+
+Glob pattern for files that should not be treated as test files
+
+## typecheck.allowJs
+
+- **Type**: `boolean`
+- **Default**: `false`
+
+Check JS files that have `@ts-check` comment. If you have it enabled in tsconfig, this will not overwrite it.
+
+## typecheck.ignoreSourceErrors
+
+- **Type**: `boolean`
+- **Default**: `false`
+
+Do not fail, if Vitest found errors outside the test files. This will not show you non-test errors at all.
+
+By default, if Vitest finds source error, it will fail test suite.
+
+## typecheck.tsconfig
+
+- **Type**: `string`
+- **Default**: _tries to find closest tsconfig.json_
+
+Path to custom tsconfig, relative to the project root.
+
+## typecheck.spawnTimeout
+
+- **Type**: `number`
+- **Default**: `10_000`
+
+Minimum time in milliseconds it takes to spawn the typechecker.
diff --git a/config/ui.md b/config/ui.md
new file mode 100644
index 00000000..e3bac62a
--- /dev/null
+++ b/config/ui.md
@@ -0,0 +1,16 @@
+---
+title: ui | Config
+outline: deep
+---
+
+# ui
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **CLI:** `--ui`, `--ui=false`
+
+Enable [Vitest UI](/guide/ui).
+
+::: warning
+This features requires a [`@vitest/ui`](https://www.npmjs.com/package/@vitest/ui) package to be installed. If you do not have it already, Vitest will install it when you run the test command for the first time.
+:::
diff --git a/config/unstubenvs.md b/config/unstubenvs.md
new file mode 100644
index 00000000..9deaabda
--- /dev/null
+++ b/config/unstubenvs.md
@@ -0,0 +1,21 @@
+---
+title: unstubEnvs | Config
+outline: deep
+---
+
+# unstubEnvs
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Should Vitest automatically call [`vi.unstubAllEnvs()`](/api/vi#vi-unstuballenvs) before each test.
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ unstubEnvs: true,
+ },
+})
+```
diff --git a/config/unstubglobals.md b/config/unstubglobals.md
new file mode 100644
index 00000000..6c0d984b
--- /dev/null
+++ b/config/unstubglobals.md
@@ -0,0 +1,21 @@
+---
+title: unstubGlobals | Config
+outline: deep
+---
+
+# unstubGlobals
+
+- **Type:** `boolean`
+- **Default:** `false`
+
+Should Vitest automatically call [`vi.unstubAllGlobals()`](/api/vi#vi-unstuballglobals) before each test.
+
+```js [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ unstubGlobals: true,
+ },
+})
+```
diff --git a/config/update.md b/config/update.md
new file mode 100644
index 00000000..8668b8e2
--- /dev/null
+++ b/config/update.md
@@ -0,0 +1,12 @@
+---
+title: update | Config
+outline: deep
+---
+
+# update {#update}
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **CLI:** `-u`, `--update`, `--update=false`
+
+Update snapshot files. This will update all changed snapshots and delete obsolete ones.
diff --git a/config/vmmemorylimit.md b/config/vmmemorylimit.md
new file mode 100644
index 00000000..118d9bb1
--- /dev/null
+++ b/config/vmmemorylimit.md
@@ -0,0 +1,35 @@
+---
+title: vmMemoryLimit | Config
+outline: deep
+---
+
+# vmMemoryLimit
+
+- **Type:** `string | number`
+- **Default:** `1 / CPU Cores`
+
+This option affects only `vmForks` and `vmThreads` pools.
+
+Specifies the memory limit for workers before they are recycled. This value heavily depends on your environment, so it's better to specify it manually instead of relying on the default.
+
+::: tip
+The implementation is based on Jest's [`workerIdleMemoryLimit`](https://jestjs.io/docs/configuration#workeridlememorylimit-numberstring).
+
+The limit can be specified in a number of different ways and whatever the result is `Math.floor` is used to turn it into an integer value:
+
+- `<= 1` - The value is assumed to be a percentage of system memory. So 0.5 sets the memory limit of the worker to half of the total system memory
+- `\> 1` - Assumed to be a fixed byte value. Because of the previous rule if you wanted a value of 1 byte (I don't know why) you could use 1.1.
+- With units
+ - `50%` - As above, a percentage of total system memory
+ - `100KB`, `65MB`, etc - With units to denote a fixed memory limit.
+ - `K` / `KB` - Kilobytes (x1000)
+ - `KiB` - Kibibytes (x1024)
+ - `M` / `MB` - Megabytes
+ - `MiB` - Mebibytes
+ - `G` / `GB` - Gigabytes
+ - `GiB` - Gibibytes
+:::
+
+::: warning
+Percentage based memory limit [does not work on Linux CircleCI](https://github.com/jestjs/jest/issues/11956#issuecomment-1212925677) workers due to incorrect system memory being reported.
+:::
diff --git a/config/watch.md b/config/watch.md
new file mode 100644
index 00000000..22fe6a5e
--- /dev/null
+++ b/config/watch.md
@@ -0,0 +1,16 @@
+---
+title: watch | Config
+outline: deep
+---
+
+# watch {#watch}
+
+- **Type:** `boolean`
+- **Default:** `!process.env.CI && process.stdin.isTTY`
+- **CLI:** `-w`, `--watch`, `--watch=false`
+
+Enable watch mode
+
+In interactive environments, this is the default, unless `--run` is specified explicitly.
+
+In CI, or when run from a non-interactive shell, "watch" mode is not the default, but can be enabled explicitly with this flag.
diff --git a/config/watchtriggerpatterns.md b/config/watchtriggerpatterns.md
new file mode 100644
index 00000000..2041def7
--- /dev/null
+++ b/config/watchtriggerpatterns.md
@@ -0,0 +1,34 @@
+---
+title: watchTriggerPatterns | Config
+outline: deep
+---
+
+# watchTriggerPatterns 3.2.0
+
+- **Type:** `WatcherTriggerPattern[]`
+
+Vitest reruns tests based on the module graph which is populated by static and dynamic `import` statements. However, if you are reading from the file system or fetching from a proxy, then Vitest cannot detect those dependencies.
+
+To correctly rerun those tests, you can define a regex pattern and a function that returns a list of test files to run.
+
+```ts
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ watchTriggerPatterns: [
+ {
+ pattern: /^src\/(mailers|templates)\/(.*)\.(ts|html|txt)$/,
+ testsToRun: (id, match) => {
+ // relative to the root value
+ return `./api/tests/mailers/${match[2]}.test.ts`
+ },
+ },
+ ],
+ },
+})
+```
+
+::: warning
+Returned files should be either absolute or relative to the root. Note that this is a global option, and it cannot be used inside of [project](/guide/projects) configs.
+:::
diff --git a/eslint.config.js b/eslint.config.js
index dd5c2319..29738e34 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -1,42 +1,74 @@
import antfu, { GLOB_SRC } from '@antfu/eslint-config'
-export default antfu({
- stylistic: true,
- typescript: true,
- vue: true,
- jsonc: false,
- yaml: false,
- ignores: [
- 'dist',
- 'node_modules',
- '*.svelte',
- '*.snap',
- '*.d.ts',
- 'coverage',
- '!.vitepress',
- // contains technically invalid code to display pretty diff
- 'guide/snapshot.md',
- // uses invalid js example
- 'advanced/api/import-example.md',
- 'guide/examples/*.md',
- ],
- rules: {
- 'no-restricted-globals': 'off',
- 'no-empty-pattern': 'off',
+export default antfu(
+ {
+ stylistic: true,
+ typescript: true,
+ vue: true,
+ jsonc: false,
+ yaml: false,
+ ignores: [
+ 'dist',
+ 'node_modules',
+ '*.svelte',
+ '*.snap',
+ '*.d.ts',
+ 'coverage',
+ '!.vitepress',
+ // contains technically invalid code to display pretty diff
+ 'guide/snapshot.md',
+ // uses invalid js example
+ 'advanced/api/import-example.md',
+ 'api/advanced/import-example.md',
+ 'guide/examples/*.md',
+ ],
},
-}, {
- files: [
- `**/*.md`,
- `**/*.md/${GLOB_SRC}`,
- ],
- rules: {
- 'perfectionist/sort-imports': 'off',
- 'style/max-statements-per-line': 'off',
- 'import/newline-after-import': 'off',
- 'import/first': 'off',
- 'unused-imports/no-unused-imports': 'off',
- 'ts/method-signature-style': 'off',
- 'no-self-compare': 'off',
- 'import/no-mutable-exports': 'off',
+ {
+ rules: {
+ // prefer global Buffer to not initialize the whole module
+ 'node/prefer-global/buffer': 'off',
+ 'node/prefer-global/process': 'off',
+ 'no-empty-pattern': 'off',
+ 'antfu/indent-binary-ops': 'off',
+ 'unused-imports/no-unused-imports': 'error',
+ 'style/member-delimiter-style': [
+ 'error',
+ {
+ multiline: { delimiter: 'none' },
+ singleline: { delimiter: 'semi' },
+ },
+ ],
+ // let TypeScript handle this
+ 'no-undef': 'off',
+ 'ts/no-invalid-this': 'off',
+ 'eslint-comments/no-unlimited-disable': 'off',
+ 'curly': ['error', 'all'],
+
+ // TODO: migrate and turn it back on
+ 'ts/ban-types': 'off',
+ 'ts/no-unsafe-function-type': 'off',
+
+ 'no-restricted-imports': [
+ 'error',
+ {
+ paths: ['path'],
+ },
+ ],
+ 'import/no-named-as-default': 'off',
+ 'style/max-statements-per-line': 'off',
+ },
+ },
+ {
+ files: [`**/*.md`, `**/*.md/${GLOB_SRC}`],
+ rules: {
+ 'perfectionist/sort-imports': 'off',
+ 'import/newline-after-import': 'off',
+ 'import/first': 'off',
+ 'unused-imports/no-unused-imports': 'off',
+ 'ts/method-signature-style': 'off',
+ 'no-self-compare': 'off',
+ 'import/no-mutable-exports': 'off',
+ 'no-restricted-globals': 'off',
+ },
},
-})
+)
diff --git a/advanced/api/index.md b/guide/advanced/index.md
similarity index 90%
rename from advanced/api/index.md
rename to guide/advanced/index.md
index 24e75512..f5b40893 100644
--- a/advanced/api/index.md
+++ b/guide/advanced/index.md
@@ -2,7 +2,7 @@
title: Advanced API
---
-# 快速起步 {#getting-started}
+# 快速起步 advanced {#getting-started}
::: warning
本指南列出了通过 Node.js 脚本运行测试的高级 API。如果你只是想 [运行测试](/guide/),你可能不需要这些内容。这些 API 主要用于库作者。
@@ -32,7 +32,7 @@ const vitest = await startVitest('test')
await vitest.close()
```
-`startVitest` 函数如果可以启动测试,将返回一个 [`Vitest`](/advanced/api/vitest) 实例。
+`startVitest` 函数如果可以启动测试,将返回一个 [`Vitest`](/api/advanced/vitest) 实例。
如果未启用监视模式,Vitest 将自动调用 `close` 方法。
@@ -42,7 +42,7 @@ await vitest.close()
此外,你可以使用第三个参数传递 CLI 参数,这些参数将覆盖任何测试配置选项。或者,你可以将完整的 Vite 配置作为第四个参数传递,这将优先于任何其他用户定义的选项。
-运行测试后,你可以从 [`state.getTestModules`](/advanced/api/test-module) API 获取结果:
+运行测试后,你可以从 [`state.getTestModules`](/api/advanced/test-module) API 获取结果:
```ts
import type { TestModule } from 'vitest/node'
@@ -53,7 +53,7 @@ console.log(vitest.state.getTestModules()) // [TestModule]
```
::: tip
-[“运行测试”](/advanced/guide/tests#startvitest) 指南中有使用示例。
+[“运行测试”](/guide/advanced/tests#startvitest) 指南中有使用示例。
:::
## createVitest
@@ -67,7 +67,7 @@ function createVitest(
): Promise
```
-你可以使用 `createVitest` 函数创建一个 Vitest 实例。它返回与 `startVitest` 相同的 [`Vitest`](/advanced/api/vitest) 实例,但不会启动测试也不会验证已安装的包。
+你可以使用 `createVitest` 函数创建一个 Vitest 实例。它返回与 `startVitest` 相同的 [`Vitest`](/api/advanced/vitest) 实例,但不会启动测试也不会验证已安装的包。
```js
import { createVitest } from 'vitest/node'
@@ -78,7 +78,7 @@ const vitest = await createVitest('test', {
```
::: tip
-[“运行测试”](/advanced/guide/tests#createvitest) 指南中有使用示例。
+[“运行测试”](/guide/advanced/tests#createvitest) 指南中有使用示例。
:::
## resolveConfig
diff --git a/guide/advanced/pool.md b/guide/advanced/pool.md
new file mode 100644
index 00000000..635d04e3
--- /dev/null
+++ b/guide/advanced/pool.md
@@ -0,0 +1,148 @@
+# Custom Pool advanced {#custom-pool}
+
+::: warning
+This is an advanced, experimental and very low-level API. If you just want to [run tests](/guide/), you probably don't need this. It is primarily used by library authors.
+:::
+
+Vitest runs tests in a pool. By default, there are several pool runners:
+
+- `threads` to run tests using `node:worker_threads` (isolation is provided with a new worker context)
+- `forks` to run tests using `node:child_process` (isolation is provided with a new `child_process.fork` process)
+- `vmThreads` to run tests using `node:worker_threads` (but isolation is provided with `vm` module instead of a new worker context)
+- `browser` to run tests using browser providers
+- `typescript` to run typechecking on tests
+
+::: tip
+See [`vitest-pool-example`](https://www.npmjs.com/package/vitest-pool-example) for example of a custom pool runner implementation.
+:::
+
+## Usage
+
+You can provide your own pool runner by a function that returns `PoolRunnerInitializer`.
+
+```ts [vitest.config.ts]
+import { defineConfig } from 'vitest/config'
+import customPool from './my-custom-pool.ts'
+
+export default defineConfig({
+ test: {
+ // will run every file with a custom pool by default
+ pool: customPool({
+ customProperty: true,
+ })
+ },
+})
+```
+
+If you need to run tests in different pools, use the [`projects`](/guide/projects) feature:
+
+```ts [vitest.config.ts]
+import customPool from './my-custom-pool.ts'
+
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ extends: true,
+ test: {
+ pool: 'threads',
+ },
+ },
+ {
+ extends: true,
+ test: {
+ pool: customPool({
+ customProperty: true,
+ })
+ }
+ }
+ ],
+ },
+})
+```
+
+## API
+
+The `pool` option accepts a `PoolRunnerInitializer` that can be used for custom pool runners. The `name` property should indicate name of the custom pool runner. It should be identical with your worker's `name` property.
+
+```ts [my-custom-pool.ts]
+import type { PoolRunnerInitializer } from 'vitest/node'
+
+export function customPool(customOptions: CustomOptions): PoolRunnerInitializer {
+ return {
+ name: 'custom-pool',
+ createPoolWorker: options => new CustomPoolWorker(options, customOptions),
+ }
+}
+```
+
+In your `CustomPoolWorker` you need to define all required methods:
+
+```ts [my-custom-pool.ts]
+import type { PoolOptions, PoolWorker, WorkerRequest } from 'vitest/node'
+
+class CustomPoolWorker implements PoolWorker {
+ name = 'custom-pool'
+ private customOptions: CustomOptions
+
+ constructor(options: PoolOptions, customOptions: CustomOptions) {
+ this.customOptions = customOptions
+ }
+
+ send(message: WorkerRequest): void {
+ // Provide way to send your worker a message
+ }
+
+ on(event: string, callback: (arg: any) => void): void {
+ // Provide way to listen to your workers events, e.g. message, error, exit
+ }
+
+ off(event: string, callback: (arg: any) => void): void {
+ // Provide way to unsubscribe `on` listeners
+ }
+
+ async start() {
+ // do something when the worker is started
+ }
+
+ async stop() {
+ // cleanup the state
+ }
+
+ deserialize(data) {
+ return data
+ }
+}
+```
+
+Your `CustomPoolRunner` will be controlling how your custom test runner worker life cycles and communication channel works. For example, your `CustomPoolRunner` could launch a `node:worker_threads` `Worker`, and provide communication via `Worker.postMessage` and `parentPort`.
+
+In your worker file, you can import helper utilities from `vitest/worker`:
+
+```ts [my-worker.ts]
+import { init, runBaseTests, setupEnvironment } from 'vitest/worker'
+
+init({
+ post: (response) => {
+ // Provide way to send this message to CustomPoolRunner's onWorker as message event
+ },
+ on: (callback) => {
+ // Provide a way to listen CustomPoolRunner's "postMessage" calls
+ },
+ off: (callback) => {
+ // Optional, provide a way to remove listeners added by "on" calls
+ },
+ teardown: () => {
+ // Optional, provide a way to teardown worker, e.g. unsubscribe all the `on` listeners
+ },
+ serialize: (value) => {
+ // Optional, provide custom serializer for `post` calls
+ },
+ deserialize: (value) => {
+ // Optional, provide custom deserializer for `on` callbacks
+ },
+ runTests: (state, traces) => runBaseTests('run', state, traces),
+ collectTests: (state, traces) => runBaseTests('collect', state, traces),
+ setup: setupEnvironment,
+})
+```
diff --git a/advanced/reporters.md b/guide/advanced/reporters.md
similarity index 96%
rename from advanced/reporters.md
rename to guide/advanced/reporters.md
index b5be3978..0be4f479 100644
--- a/advanced/reporters.md
+++ b/guide/advanced/reporters.md
@@ -1,4 +1,4 @@
-# 扩展默认报告器 {#extending-reporters}
+# 扩展默认报告器 advanced {#extending-reporters}
::: warning
这是一个高级 API。如果我们只是想配置内置报告器,请阅读 [报告器](/guide/reporters) 指南。
diff --git a/advanced/guide/tests.md b/guide/advanced/tests.md
similarity index 89%
rename from advanced/guide/tests.md
rename to guide/advanced/tests.md
index c5cb5004..e7178f59 100644
--- a/advanced/guide/tests.md
+++ b/guide/advanced/tests.md
@@ -1,4 +1,4 @@
-# 运行测试 {#running-tests}
+# 运行测试 advanced {#running-tests}
::: warning 注意
本指南介绍如何使用高级 API 通过 Node.js 脚本运行测试。如果您只想[运行测试](/guide/),则可能不需要这个。它主要被库的作者使用。
@@ -30,12 +30,12 @@ for (const testModule of testModules) {
```
::: tip
-[`TestModule`](/advanced/api/test-module), [`TestSuite`](/advanced/api/test-suite) 和 [`TestCase`](/advanced/api/test-case) API 从 Vitest 2.1 开始不再是实验性的,并且遵循 SemVer。
+[`TestModule`](/api/advanced/test-module), [`TestSuite`](/api/advanced/test-suite) 和 [`TestCase`](/api/advanced/test-case) API 从 Vitest 2.1 开始不再是实验性的,并且遵循 SemVer。
:::
## `createVitest`
-创建一个 [Vitest](/advanced/api/vitest) 实例而不运行测试。
+创建一个 [Vitest](/api/advanced/vitest) 实例而不运行测试。
`createVitest` 方法不会验证是否已安装所需的软件包。此方法也不遵循 `config.standalone` 或 `config.mergeReports`。即使 `watch` 被禁用,Vitest 也不会自动关闭。
@@ -71,9 +71,9 @@ finally {
}
```
-如果我们打算保留 `Vitest` 实例,请确保至少调用 [`init`](/advanced/api/vitest#init) 。这将初始化报告器和覆盖率提供者,但不会运行任何测试。即使我们不打算使用 Vitest 观察器,但希望保持实例运行,也建议启用 `watch` 模式。Vitest 依赖此标志使其某些功能在连续过程中正常工作。
+如果我们打算保留 `Vitest` 实例,请确保至少调用 [`init`](/api/advanced/vitest#init) 。这将初始化报告器和覆盖率提供者,但不会运行任何测试。即使我们不打算使用 Vitest 观察器,但希望保持实例运行,也建议启用 `watch` 模式。Vitest 依赖此标志使其某些功能在连续过程中正常工作。
-报告器初始化后,如果需要手动运行测试,可以使用 [`runTestSpecifications`](/advanced/api/vitest#runtestspecifications) 或 [`rerunTestSpecifications`](/advanced/api/vitest#reruntestspecifications) 来运行测试。
+报告器初始化后,如果需要手动运行测试,可以使用 [`runTestSpecifications`](/api/advanced/vitest#runtestspecifications) 或 [`rerunTestSpecifications`](/api/advanced/vitest#reruntestspecifications) 来运行测试。
```ts
watcher.on('change', async (file) => {
diff --git a/guide/browser/component-testing.md b/guide/browser/component-testing.md
index f1f8e9b8..2904b900 100644
--- a/guide/browser/component-testing.md
+++ b/guide/browser/component-testing.md
@@ -181,7 +181,7 @@ test('Solid component handles user interaction', async () => {
确保测试在真实浏览器环境中运行以获得最准确的测试结果。浏览器模式提供准确的CSS渲染、真实的浏览器API和正确的事件处理。
### 2. 测试用户交互 {#_2-test-user-interactions}
-使用Vitest的[交互API](/guide/browser/interactivity-api)模拟真实用户行为。使用`page.getByRole()`和`userEvent`方法,如我们的[高级测试模式](#advanced-testing-patterns)所示:
+使用Vitest的[交互API](/api/browser/interactivity)模拟真实用户行为。使用`page.getByRole()`和`userEvent`方法,如我们的 [高级测试模式](#advanced-testing-patterns) 所示:
```tsx
// Good: Test actual user interactions
@@ -257,27 +257,24 @@ test('ShoppingCart manages items correctly', async () => {
```
### 测试带有数据获取的异步组件 {#testing-async-components-with-data-fetching}
-
+
```tsx
// Option 1: Recommended - Use MSW (Mock Service Worker) for API mocking
import { http, HttpResponse } from 'msw'
-import { setupServer } from 'msw/node'
+import { setupWorker } from 'msw/browser'
-// Set up MSW server with API handlers
-const server = setupServer(
+// Set up MSW worker with API handlers
+const worker = setupWorker(
http.get('/api/users/:id', ({ params }) => {
- const { id } = params
- if (id === '123') {
- return HttpResponse.json({ name: 'John Doe', email: 'john@example.com' })
- }
- return HttpResponse.json({ error: 'User not found' }, { status: 404 })
+ // Describe the happy path
+ return HttpResponse.json({ id: params.id, name: 'John Doe', email: 'john@example.com' })
})
)
-// Start server before all tests
-beforeAll(() => server.listen())
-afterEach(() => server.resetHandlers())
-afterAll(() => server.close())
+// Start the worker before all tests
+beforeAll(() => worker.start())
+afterEach(() => worker.resetHandlers())
+afterAll(() => worker.stop())
test('UserProfile handles loading, success, and error states', async () => {
// Test success state
@@ -287,7 +284,7 @@ test('UserProfile handles loading, success, and error states', async () => {
await expect.element(getByText('john@example.com')).toBeInTheDocument()
// Test error state by overriding the handler for this test
- server.use(
+ worker.use(
http.get('/api/users/:id', () => {
return HttpResponse.json({ error: 'User not found' }, { status: 404 })
})
@@ -298,7 +295,11 @@ test('UserProfile handles loading, success, and error states', async () => {
})
```
-### 测试组件通信 {#testing-component-communication}
+::: tip
+See more details on [using MSW in the browser](https://mswjs.io/docs/integrations/browser).
+:::
+
+### Testing Component Communication
```tsx
// Test parent-child component interaction
@@ -570,6 +571,6 @@ import { render } from 'vitest-browser-react' // [!code ++]
## 了解更多 {#learn-more}
- [浏览器模式文档](/guide/browser/)
-- [断言API](/guide/browser/assertion-api)
-- [交互性API](/guide/browser/interactivity-api)
+- [断言API](/api/browser/assertions)
+- [交互性API](/api/browser/interactivity)
- [示例仓库](https://github.com/vitest-tests/browser-examples)
diff --git a/guide/browser/index.md b/guide/browser/index.md
index 48346c3d..8394b96d 100644
--- a/guide/browser/index.md
+++ b/guide/browser/index.md
@@ -2,10 +2,10 @@
title: Browser Mode | Guide
outline: deep
---
+
+# Browser Mode {#browser-mode}
-# 浏览器模式 实验性 {#browser-mode}
-
-此页面提供有关 Vitest API 中实验性浏览器模式功能的信息,该功能允许你在浏览器中本地运行测试,提供对窗口和文档等浏览器全局变量的访问。此功能目前正在开发中,API 未来可能会更改。
+This page provides information about the browser mode feature in the Vitest API, which allows you to run your tests in the browser natively, providing access to browser globals like window and document.
::: tip
如果你需要 `expect` 、`vi` ,或者像测试项目、类型测试等通用 API 的文档,请查看 [“快速起步” 指南](/guide/)。
@@ -34,28 +34,32 @@ bunx vitest init browser
:::
### 手动安装 {#manual-installation}
+
+You can also install packages manually. Vitest always requires a provider to be defined. You can chose either [`preview`](/config/browser/preview), [`playwright`](/config/browser/playwright) or [`webdriverio`](/config/browser/webdriverio).
-我们也可以手动安装软件包。默认情况下,浏览器模式不需要任何额外的端到端 provider 就能在本地运行测试,因为它会复用你现有的浏览器。
+If you want to just preview how your tests look, you can use the `preview` provider:
::: code-group
```bash [npm]
-npm install -D vitest @vitest/browser
+npm install -D vitest @vitest/browser-preview
```
```bash [yarn]
-yarn add -D vitest @vitest/browser
+yarn add -D vitest @vitest/browser-preview
```
```bash [pnpm]
-pnpm add -D vitest @vitest/browser
+pnpm add -D vitest @vitest/browser-preview
```
```bash [bun]
-bun add -D vitest @vitest/browser
+bun add -D vitest @vitest/browser-preview
```
:::
::: warning
不过,要在 CI 中运行测试,我们需要安装 [`playwright`](https://npmjs.com/package/playwright) 或 [`webdriverio`](https://www.npmjs.com/package/webdriverio) 。我们还建议在本地测试时切换到这两个选项中的一个,而不是使用默认的 `preview` 提供程序,因为它依赖于模拟事件而不是使用 Chrome DevTools 协议。
-如果我们尚未使用这些工具中的任何一个,我们建议从 Playwright 开始,因为它支持并行执行,这可以使我们的测试运行得更快。此外,Playwright 使用的是 [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) ,通常比 WebDriver 更快。
+
+
+If you don't already use one of these tools, we recommend starting with Playwright because it supports parallel execution, which makes your tests run faster.
::: tabs key:provider
== Playwright
@@ -63,16 +67,16 @@ bun add -D vitest @vitest/browser
::: code-group
```bash [npm]
-npm install -D vitest @vitest/browser playwright
+npm install -D vitest @vitest/browser-playwright
```
```bash [yarn]
-yarn add -D vitest @vitest/browser playwright
+yarn add -D vitest @vitest/browser-playwright
```
```bash [pnpm]
-pnpm add -D vitest @vitest/browser playwright
+pnpm add -D vitest @vitest/browser-playwright
```
```bash [bun]
-bun add -D vitest @vitest/browser playwright
+bun add -D vitest @vitest/browser-playwright
```
== WebdriverIO
@@ -80,16 +84,16 @@ bun add -D vitest @vitest/browser playwright
::: code-group
```bash [npm]
-npm install -D vitest @vitest/browser webdriverio
+npm install -D vitest @vitest/browser-webdriverio
```
```bash [yarn]
-yarn add -D vitest @vitest/browser webdriverio
+yarn add -D vitest @vitest/browser-webdriverio
```
```bash [pnpm]
-pnpm add -D vitest @vitest/browser webdriverio
+pnpm add -D vitest @vitest/browser-webdriverio
```
```bash [bun]
-bun add -D vitest @vitest/browser webdriverio
+bun add -D vitest @vitest/browser-webdriverio
```
:::
@@ -117,8 +121,8 @@ export default defineConfig({
::: info
Vitest 默认分配端口号 `63315` 以避免与开发服务器冲突,允许我们同时并行运行两者。我们可以通过 [`browser.api`](/config/#browser-api) 选项来更改这个端口号。
-
-自 Vitest 2.1.5 版本起,命令行界面(CLI)不再自动打印 Vite 的 URL。当我们在观察模式下运行时,可以通过按 "b" 键来打印 URL。
+
+The CLI does not prints the Vite server URL automatically. You can press "b" to print the URL when running in watch mode.
:::
如果之前未使用过 Vite,请确保已安装框架插件并在配置中指定。有些框架可能需要额外配置才能运行,请查看其 Vite 相关文档以确定。
@@ -397,7 +401,7 @@ test('properly handles form inputs', async () => {
如果你的框架没有被包含在内,请随时创建你自己的软件包——它是一个简单的封装,围绕着框架渲染器和 `page.elementLocator` API。我们会在本页面添加指向它的链接。请确保其名称以 `vitest-browser-` 开头。
-除了渲染组件和定位元素外,你还需要进行断言。Vitest 基于 [`@testing-library/jest-dom`](https://github.com/testing-library/jest-dom) 库提供了一整套开箱即用的 DOM 断言。更多信息请参阅 [Assertions API](/guide/browser/assertion-api)。
+除了渲染组件和定位元素外,你还需要进行断言。Vitest 基于 [`@testing-library/jest-dom`](https://github.com/testing-library/jest-dom) 库提供了一整套开箱即用的 DOM 断言。更多信息请参阅 [Assertions API](/api/browser/assertions)。
```ts
import { expect } from 'vitest'
@@ -406,7 +410,7 @@ import { page } from 'vitest/browser'
await expect.element(page.getByText('Hello World')).toBeInTheDocument()
```
-Vitest 暴露了一个 [上下文 API](/guide/browser/context),其中包含一组在测试中可能对你有用的实用程序。例如,如果你需要进行交互操作,比如点击元素或在输入框中输入文本,你可以使用来自 `vitest/browser` 的 `userEvent`。更多内容请参阅 [交互性 API](/guide/browser/interactivity-api)。
+Vitest 暴露了一个 [上下文 API](/api/browser/context),其中包含一组在测试中可能对你有用的实用程序。例如,如果你需要进行交互操作,比如点击元素或在输入框中输入文本,你可以使用来自 `vitest/browser` 的 `userEvent`。更多内容请参阅 [交互性 API](/api/browser/interactivity)。
```ts
import { page, userEvent } from 'vitest/browser'
@@ -526,7 +530,7 @@ Vitest 并不支持所有开箱即用的框架,但我们可以使用外部工
我们还可以在 [`browser-examples`](https://github.com/vitest-tests/browser-examples) 中查看更多的案例。
::: warning
-`testing-library` 提供了一个软件包 `@testing-library/user-event`。我们不建议直接使用它,因为它会模拟事件而非实际触发事件--相反,请使用从 `vitest/browser`导入的 [`userEvent`](/guide/browser/interactivity-api),它在引擎盖下使用 Chrome DevTools 协议或 Webdriver(取决于provider)。
+`testing-library` 提供了一个软件包 `@testing-library/user-event`。我们不建议直接使用它,因为它会模拟事件而非实际触发事件--相反,请使用从 `vitest/browser`导入的 [`userEvent`](/api/browser/interactivity),它在引擎盖下使用 Chrome DevTools 协议或 Webdriver(取决于provider)。
:::
::: code-group
diff --git a/guide/browser/multiple-setups.md b/guide/browser/multiple-setups.md
index e20d8d5f..faca0c27 100644
--- a/guide/browser/multiple-setups.md
+++ b/guide/browser/multiple-setups.md
@@ -1,6 +1,6 @@
# 多环境配置 {#multiple-setups}
-你可以使用 [`browser.instances`](/guide/browser/config#browser-instances) 选项来指定多个不同的浏览器设置。
+你可以使用 [`browser.instances`](/config/browser/instances) 选项来指定多个不同的浏览器设置。
与 [测试项目](/guide/projects) 相比,使用 `browser.instances` 的最大好处在于缓存效率更高。所有项目会共享同一个 Vite 服务器,因此文件转换和 [依赖的预打包](https://vite.dev/guide/dep-pre-bundling.html) 只需进行一次即可。
diff --git a/guide/browser/retry-ability.md b/guide/browser/retry-ability.md
index 8b6a90f9..f64b34f6 100644
--- a/guide/browser/retry-ability.md
+++ b/guide/browser/retry-ability.md
@@ -1,5 +1,5 @@
---
-title: Retry-ability | Browser Mode
+title: Retry-ability | 浏览器模式
---
# Retry-ability
diff --git a/guide/browser/trace-view.md b/guide/browser/trace-view.md
index d20cf84e..68ecaf54 100644
--- a/guide/browser/trace-view.md
+++ b/guide/browser/trace-view.md
@@ -1,9 +1,9 @@
# 追踪视图 {#trace-view}
-Vitest 浏览器模式支持生成 Playwright 的 [追踪文件](https://playwright.dev/docs/trace-viewer#viewing-remote-traces)。要启用追踪功能,需要在 `test.browser` 配置中设置 [`trace`](/guide/browser/config#browser-trace) 选项。
+Vitest 浏览器模式支持生成 Playwright 的 [追踪文件](https://playwright.dev/docs/trace-viewer#viewing-remote-traces)。要启用追踪功能,需要在 `test.browser` 配置中设置 [`trace`](/config/browser/trace) 选项。
::: warning
-生成追踪文件仅在使用 [Playwright provider](/guide/browser/playwright) 时可用。
+生成追踪文件仅在使用 [Playwright provider](/config/browser/playwright) 时可用。
:::
::: code-group
@@ -69,6 +69,6 @@ npx playwright show-trace "path-to-trace-file"
或者,你可以在浏览器中打开 https://trace.playwright.dev 并在那里上传追踪文件。
-## 限制 {#limitations}
+## 局限性 {#limitations}
目前,Vitest 无法填充 Trace Viewer 中的 "Sources" 标签页。这意味着虽然你可以看到测试期间捕获的操作和截图,但无法直接在 Trace Viewer 中查看测试的源代码。你需要返回代码编辑器查看测试实现。
diff --git a/guide/browser/visual-regression-testing.md b/guide/browser/visual-regression-testing.md
index 4037932c..0d0c2b19 100644
--- a/guide/browser/visual-regression-testing.md
+++ b/guide/browser/visual-regression-testing.md
@@ -36,7 +36,7 @@ Vitest 原生支持可视化回归测试。它会自动截取 UI 组件或页面
要获得稳定结果,应使用相同的测试环境。**推荐**采用云端服务(如 [Azure App Testing](https://azure.microsoft.com/en-us/products/playwright-testing))或基于 [Docker containers](https://playwright.dev/docs/docker) 的环境。
:::
-在 Vitest 中,可通过 [`toMatchScreenshot` assertion](/guide/browser/assertion-api.html#tomatchscreenshot) 断言运行可视化回归测试:
+在 Vitest 中,可通过 [`toMatchScreenshot` assertion](/api/browser/assertions.html#tomatchscreenshot) 断言运行可视化回归测试:
```ts
import { expect, test } from 'vitest'
@@ -101,12 +101,31 @@ $ vitest --update
提交前务必核对更新后的截图,确保改动符合预期。
+
+## How Visual Tests Work
+
+Visual regression tests need stable screenshots to compare against. But pages aren't instantly stable as images load, animations finish, fonts render, and layouts settle.
+
+Vitest handles this automatically through "Stable Screenshot Detection":
+
+1. Vitest takes a first screenshot (or uses the reference screenshot if available) as baseline
+1. It takes another screenshot and compares it with the baseline
+ - If the screenshots match, the page is stable and testing continues
+ - If they differ, Vitest uses the newest screenshot as the baseline and repeats
+1. This continues until stability is achieved or the timeout is reached
+
+This ensures that transient visual changes (like loading spinners or animations) don't cause false failures. If something never stops animating though, you'll hit the timeout, so consider [disabling animations during testing](#disable-animations).
+
+If a stable screenshot is captured after retries (one or more) and a reference screenshot exists, Vitest performs a final comparison with the reference using `createDiff: true`. This will generate a diff image if they don't match.
+
+During stability detection, Vitest calls comparators with `createDiff: false` since it only needs to know if screenshots match. This keeps the detection process fast.
+
## 配置可视化测试 {#configuring-visual-tests}
### 全局配置 {#global-configuration}
-可在 [Vitest 配置文件](/guide/browser/config#browser-expect-tomatchscreenshot) 中设定可视化回归测试的默认规则:
-
+可在 [Vitest 配置文件](/config/browser/expect#tomatchscreenshot) 中设定可视化回归测试的默认规则:
+
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
@@ -132,7 +151,7 @@ export default defineConfig({
### 单测试配置 {#per-test-configuration}
若某个测试需要不同的比较标准,可在调用时覆盖全局设置:
-
+
```ts
await expect(element).toMatchScreenshot('button-hover', {
comparatorName: 'pixelmatch',
@@ -148,7 +167,7 @@ await expect(element).toMatchScreenshot('button-hover', {
### 聚焦测试目标元素 {#test-specific-elements}
除非确实需要测试整个页面,否则应优先只对目标组件截图,这能显著减少因页面其他部分变化而造成的误报。
-
+
```ts
// ❌ Captures entire page; prone to unrelated changes
await expect(page).toMatchScreenshot()
@@ -614,7 +633,7 @@ export default defineConfig({
```
该服务会提供两个关键环境变量:
-
+
- `PLAYWRIGHT_SERVICE_URL`:指示 Playwright 连接的服务器地址
- `PLAYWRIGHT_SERVICE_ACCESS_TOKEN`:你的身份验证令牌
diff --git a/guide/browser/why.md b/guide/browser/why.md
index c633ee5b..e9df080f 100644
--- a/guide/browser/why.md
+++ b/guide/browser/why.md
@@ -1,13 +1,13 @@
---
-title: Why Browser Mode | Browser Mode
+title: Why Browser Mode | 浏览器模式
outline: deep
---
# 什么是浏览器模式? {#why-browser-mode}
## 动机 {#motivation}
-
-我们开发了 Vitest 浏览器模式功能,以帮助改进测试工作流程并实现更准确、可靠的测试结果。这个实验性的测试 API 增加了在本地浏览器环境中运行测试的功能。在本节中,我们将探讨这个功能背后的动机以及它对测试的好处。
+
+We developed the Vitest browser mode feature to help improve testing workflows and achieve more accurate and reliable test results. This addition to our testing API allows developers to run tests in a native browser environment. In this section, we'll explore the motivations behind this feature and its benefits for testing.
### 不同的测试方式 {#different-ways-of-testing}
diff --git a/guide/cli-generated.md b/guide/cli-generated.md
index 02bfa67d..ffde836a 100644
--- a/guide/cli-generated.md
+++ b/guide/cli-generated.md
@@ -1,7 +1,7 @@
### root
- **命令行终端:** `-r, --root `
-- **配置:** [root](/config/#root)
+- **配置:** [root](/config/root)
根路径
@@ -14,42 +14,41 @@
### update
- **命令行终端:** `-u, --update`
-- **配置:** [update](/config/#update)
+- **配置:** [update](/config/update)
更新快照
### watch
- **命令行终端:** `-w, --watch`
-- **配置:** [watch](/config/#watch)
+- **配置:** [watch](/config/watch)
启用观察模式
### testNamePattern
- **命令行终端:** `-t, --testNamePattern `
-- **配置:** [testNamePattern](/config/#testnamepattern)
+- **配置:** [testNamePattern](/config/testnamepattern)
使用符合指定 regexp 模式的运行测试
### dir
- **命令行终端:** `--dir `
-- **配置:** [dir](/config/#dir)
+- **配置:** [dir](/config/dir)
扫描测试文件的基本目录
### ui
- **命令行终端:** `--ui`
-- **配置:** [ui](/config/#ui)
启用 UI 模式
### open
- **命令行终端:** `--open`
-- **配置:** [open](/config/#open)
+- **配置:** [open](/config/open)
自动打开用户界面(默认值:`!process.env.CI`)
@@ -74,7 +73,7 @@
### silent
- **命令行终端:** `--silent [value]`
-- **配置:** [silent](/config/#silent)
+- **配置:** [silent](/config/silent)
测试的静默控制台输出。使用 `'passed-only'` 仅查看失败测试的日志
@@ -87,112 +86,112 @@
### reporters
- **命令行终端:** `--reporter `
-- **配置:** [reporters](/config/#reporters)
+- **配置:** [reporters](/config/reporters)
指定报告器(default、blob、verbose、dot、json、tap、tap-flat、junit、tree、hanging-process、github-actions)
### outputFile
- **命令行终端:** `--outputFile `
-- **配置:** [outputFile](/config/#outputfile)
+- **配置:** [outputFile](/config/outputfile)
如果还指定了支持报告程序,则将测试结果写入文件,使用 cac 的点符号表示多个报告程序的单个输出结果 (比如: `--outputFile.tap=./tap.txt`)
### coverage.provider
- **命令行终端:** `--coverage.provider `
-- **配置:** [coverage.provider](/config/#coverage-provider)
+- **配置:** [coverage.provider](/config/coverage#coverage-provider)
选择覆盖范围采集工具,可用值为: "v8", "istanbul" and "custom"
### coverage.enabled
- **命令行终端:** `--coverage.enabled`
-- **配置:** [coverage.enabled](/config/#coverage-enabled)
+- **配置:** [coverage.enabled](/config/coverage#coverage-enabled)
启用覆盖范围收集。可使用 `--coverage` CLI 选项覆盖(默认值:`false`)
### coverage.include
- **命令行终端:** `--coverage.include `
-- **配置:** [coverage.include](/config/#coverage-include)
+- **配置:** [coverage.include](/config/coverage#coverage-include)
作为通配符模式包含在覆盖率中的文件。在使用多个模式时可以指定多次。默认情况下,只包含被测试覆盖的文件
### coverage.exclude
- **命令行终端:** `--coverage.exclude `
-- **配置:** [coverage.exclude](/config/#coverage-exclude)
+- **配置:** [coverage.exclude](/config/coverage#coverage-exclude)
覆盖范围中要排除的文件。使用多个扩展名时,可指定多次
### coverage.clean
- **命令行终端:** `--coverage.clean`
-- **配置:** [coverage.clean](/config/#coverage-clean)
+- **配置:** [coverage.clean](/config/coverage#coverage-clean)
运行测试前清除覆盖结果(默认值:true)
### coverage.cleanOnRerun
- **命令行终端:** `--coverage.cleanOnRerun`
-- **配置:** [coverage.cleanOnRerun](/config/#coverage-cleanonrerun)
+- **配置:** [coverage.cleanOnRerun](/config/coverage#coverage-cleanonrerun)
重新运行监视时清理覆盖率报告(默认值:true)
### coverage.reportsDirectory
- **命令行终端:** `--coverage.reportsDirectory `
-- **配置:** [coverage.reportsDirectory](/config/#coverage-reportsdirectory)
+- **配置:** [coverage.reportsDirectory](/config/coverage#coverage-reportsdirectory)
将覆盖率报告写入的目录(默认值: ./coverage)
### coverage.reporter
- **命令行终端:** `--coverage.reporter `
-- **配置:** [coverage.reporter](/config/#coverage-reporter)
+- **配置:** [coverage.reporter](/config/coverage#coverage-reporter)
-使用的报告。更多信息请访问 [`coverage.reporter`](https://vitest.dev/config/#coverage-reporter)。(默认值: `["text", "html", "clover", "json"]`)
+Coverage reporters to use. Visit [`coverage.reporter`](/config/#coverage-reporter) for more information (default: `["text", "html", "clover", "json"]`)
### coverage.reportOnFailure
- **命令行终端:** `--coverage.reportOnFailure`
-- **配置:** [coverage.reportOnFailure](/config/#coverage-reportonfailure)
+- **配置:** [coverage.reportOnFailure](/config/coverage#coverage-reportonfailure)
即使测试失败也能生成覆盖率报告 (默认值: `false`)
### coverage.allowExternal
- **命令行终端:** `--coverage.allowExternal`
-- **配置:** [coverage.allowExternal](/config/#coverage-allowexternal)
+- **配置:** [coverage.allowExternal](/config/coverage#coverage-allowexternal)
收集项目根目录外文件的覆盖范围(默认值:`false`)
### coverage.skipFull
- **命令行终端:** `--coverage.skipFull`
-- **配置:** [coverage.skipFull](/config/#coverage-skipfull)
+- **配置:** [coverage.skipFull](/config/coverage#coverage-skipfull)
不显示语句、分支和函数覆盖率为 100% 的文件(默认值:`false`)
### coverage.thresholds.100
- **命令行终端:** `--coverage.thresholds.100`
-- **配置:** [coverage.thresholds.100](/config/#coverage-thresholds-100)
+- **配置:** [coverage.thresholds.100](/config/coverage#coverage-thresholds-100)
将所有覆盖率阈值设置为 100 的快捷方式(默认值:`false`)
### coverage.thresholds.perFile
- **命令行终端:** `--coverage.thresholds.perFile`
-- **配置:** [coverage.thresholds.perFile](/config/#coverage-thresholds-perfile)
+- **配置:** [coverage.thresholds.perFile](/config/coverage#coverage-thresholds-perfile)
检查每个文件的阈值。 `--coverage.thresholds.lines`, `--coverage.thresholds.functions`, `--coverage.thresholds.branches`, `--coverage.thresholds.statements` 为实际阈值(默认值:`false`)
### coverage.thresholds.autoUpdate
- **命令行终端:** `--coverage.thresholds.autoUpdate `
-- **配置:** [coverage.thresholds.autoUpdate](/config/#coverage-thresholds-autoupdate)
+- **配置:** [coverage.thresholds.autoUpdate](/config/coverage#coverage-thresholds-autoupdate)
更新阈值: 当前覆盖率高于配置的阈值时,将 "lines"、"functions"、"branches"和 "statements"更新到配置文件(默认值:`false`)
@@ -223,23 +222,23 @@
### coverage.ignoreClassMethods
- **命令行终端:** `--coverage.ignoreClassMethods `
-- **配置:** [coverage.ignoreClassMethods](/config/#coverage-ignoreclassmethods)
+- **配置:** [coverage.ignoreClassMethods](/config/coverage#coverage-ignoreclassmethods)
覆盖时要忽略的类方法名称数组。更多信息请访问 [istanbuljs](https://github.com/istanbuljs/nyc#ignoring-methods) 。该选项仅适用于 istanbul providers(默认值:`[]`)
### coverage.processingConcurrency
- **命令行终端:** `--coverage.processingConcurrency `
-- **配置:** [coverage.processingConcurrency](/config/#coverage-processingconcurrency)
+- **配置:** [coverage.processingConcurrency](/config/coverage#coverage-processingconcurrency)
处理覆盖率结果时使用的并发限制。 (默认最小值介于 20 和 CPU 数量之间)
### coverage.customProviderModule
- **命令行终端:** `--coverage.customProviderModule `
-- **配置:** [coverage.customProviderModule](/config/#coverage-customprovidermodule)
+- **配置:** [coverage.customProviderModule](/config/coverage#coverage-customprovidermodule)
-指定自定义覆盖范围提供程序模块的模块名称或路径。 请访问 [自定义 providers 覆盖范围](/guide/coverage#custom-coverage-provider) 了解更多信息。 此选项仅适用于自定义 providers
+Specifies the module name or path for the custom coverage provider module. Visit [Custom Coverage Provider](/guide/coverage#custom-coverage-provider) for more information. This option is only available for custom providers
### coverage.watermarks.statements
@@ -268,21 +267,21 @@
### mode
- **命令行终端:** `--mode `
-- **配置:** [mode](/config/#mode)
+- **配置:** [mode](/config/mode)
覆盖 Vite 模式 (默认值: `test` 或 `benchmark`)
### isolate
- **命令行终端:** `--isolate`
-- **配置:** [isolate](/config/#isolate)
+- **配置:** [isolate](/config/isolate)
隔离运行每个测试文件。要禁用隔离, 使用 `--no-isolate` (默认值: `true`)
### globals
- **命令行终端:** `--globals`
-- **配置:** [globals](/config/#globals)
+- **配置:** [globals](/config/globals)
全局注入
@@ -295,581 +294,471 @@
### browser.enabled
- **命令行终端:** `--browser.enabled`
-- **配置:** [browser.enabled](/guide/browser/config#browser-enabled)
+- **配置:** [browser.enabled](/config/browser/enabled)
在浏览器中运行测试。 相当于 `--browser.enabled` (默认值: `false`)
-
+
### browser.name
- **命令行终端:** `--browser.name `
-- **配置:** [browser.name](/guide/browser/config#browser-name)
-在特定浏览器中运行所有测试。某些浏览器仅适用于特定提供商(请参阅 `--browser.provider` )。访问 [`browser.name`](https://vitest.dev/guide/browser/config/#browser-name) 了解更多信息
+Run all tests in a specific browser. Some browsers are only available for specific providers (see `--browser.provider`).
### browser.headless
- **命令行终端:** `--browser.headless`
-- **配置:** [browser.headless](/guide/browser/config#browser-headless)
+- **配置:** [browser.headless](/config/browser/headless)
在无头模式下运行浏览器(即不打开图形用户界面)。如果在 CI 中运行 Vitest,默认情况下将启用无头模式 (默认值: `process.env.CI`)
### browser.api.port
- **命令行终端:** `--browser.api.port [port]`
-- **配置:** [browser.api.port](/guide/browser/config#browser-api-port)
+- **配置:** [browser.api.port](/config/browser/api#api-port)
指定服务器端口。注意,如果端口已被使用,Vite 会自动尝试下一个可用端口,因此这可能不是服务器最终监听的实际端口。如果为 `true`,将设置为 `63315`
### browser.api.host
- **命令行终端:** `--browser.api.host [host]`
-- **配置:** [browser.api.host](/guide/browser/config#browser-api-host)
+- **配置:** [browser.api.host](/config/browser/api#api-host)
指定服务器应该监听哪些 IP 地址。设为 `0.0.0.0` 或 `true` 则监听所有地址,包括局域网地址和公共地址
### browser.api.strictPort
- **命令行终端:** `--browser.api.strictPort`
-- **配置:** [browser.api.strictPort](/guide/browser/config#browser-api-strictport)
+- **配置:** [browser.api.strictPort](/config/browser/api#api-strictport)
设置为 true 时,如果端口已被使用,则退出,而不是自动尝试下一个可用端口
-### browser.provider
-
-- **命令行终端:** `--browser.provider `
-- **配置:** [browser.provider](/guide/browser/config#browser-provider)
-
-指定执行浏览器测试时所使用的提供程序。部分浏览器仅在特定的提供程序下可用。可选值有 "webdriverio"、"playwright"、"preview",也可以填写自定义提供程序的路径。更多信息请查看 [`browser.provider`](https://vitest.dev/guide/browser/config.html#browser-provider)(默认值为 "preview")
-
### browser.isolate
- **命令行终端:** `--browser.isolate`
-- **配置:** [browser.isolate](/guide/browser/config#browser-isolate)
+- **配置:** [browser.isolate](/config/browser/isolate)
隔离运行每个浏览器测试文件。要禁用隔离请使用 `--browser.isolate=false` (默认值: `true`)
### browser.ui
- **命令行终端:** `--browser.ui`
-- **配置:** [browser.ui](/guide/browser/config#browser-ui)
+- **配置:** [browser.ui](/config/browser/ui)
运行测试时显示 Vitest UI (默认值: `!process.env.CI`)
### browser.fileParallelism
- **命令行终端:** `--browser.fileParallelism`
-- **配置:** [browser.fileParallelism](/guide/browser/config#browser-fileparallelism)
浏览器测试文件是否应并行运行。使用 `--browser.fileParallelism=false` 进行禁用 (默认值: `true`)
### browser.connectTimeout
- **命令行终端:** `--browser.connectTimeout `
-- **配置:** [browser.connectTimeout](/guide/browser/config#browser-connecttimeout)
+- **配置:** [browser.connectTimeout](/config/browser/connecttimeout)
如果连接浏览器时间超时,测试套件将失败 (默认值: `60_000`)
### browser.trackUnhandledErrors
- **命令行终端:** `--browser.trackUnhandledErrors`
-- **配置:** [browser.trackUnhandledErrors](/guide/browser/config#browser-trackunhandlederrors)
+- **配置:** [browser.trackUnhandledErrors](/config/browser/trackunhandlederrors)
控制 Vitest 是否捕获未捕获的异常以便报告(默认:`true`)
### browser.trace
- **命令行终端:** `--browser.trace `
-- **配置:** [browser.trace](/guide/browser/config#browser-trace)
+- **配置:** [browser.trace](/config/browser/trace)
启用追踪视图模式。 可选项: "on", "off", "on-first-retry", "on-all-retries", "retain-on-failure"
### pool
- **命令行终端:** `--pool `
-- **配置:** [pool](/config/#pool)
+- **配置:** [pool](/config/pool)
如果未在浏览器中运行,则指定 pool (默认值: `threads`)
-### poolOptions.threads.isolate
-
-- **命令行终端:** `--poolOptions.threads.isolate`
-- **配置:** [poolOptions.threads.isolate](/config/#pooloptions-threads-isolate)
-
-在线程池中隔离测试 (默认值: `true`)
-
-### poolOptions.threads.singleThread
-
-- **命令行终端:** `--poolOptions.threads.singleThread`
-- **配置:** [poolOptions.threads.singleThread](/config/#pooloptions-threads-singlethread)
-
-在单线程内运行测试 (默认值: `false`)
-
-### poolOptions.threads.maxThreads
-
-- **命令行终端:** `--poolOptions.threads.maxThreads `
-- **配置:** [poolOptions.threads.maxThreads](/config/#pooloptions-threads-maxthreads)
-
-运行测试的最大线程数或百分比
-
-### poolOptions.threads.useAtomics
-
-- **命令行终端:** `--poolOptions.threads.useAtomics`
-- **配置:** [poolOptions.threads.useAtomics](/config/#pooloptions-threads-useatomics)
-
-使用 Atomics 同步线程。这在某些情况下可以提高性能,但在较旧的 Node 版本中可能会导致 segfault。 (默认值: `false`)
-
-### poolOptions.vmThreads.isolate
-
-- **命令行终端:** `--poolOptions.vmThreads.isolate`
-- **配置:** [poolOptions.vmThreads.isolate](/config/#pooloptions-vmthreads-isolate)
-
-在线程池中隔离测试 (默认值: `true`)
-
-### poolOptions.vmThreads.singleThread
-
-- **命令行终端:** `--poolOptions.vmThreads.singleThread`
-- **配置:** [poolOptions.vmThreads.singleThread](/config/#pooloptions-vmthreads-singlethread)
-
-在单线程内运行测试(默认值:`false`)
-
-### poolOptions.vmThreads.maxThreads
-
-- **命令行终端:** `--poolOptions.vmThreads.maxThreads `
-- **配置:** [poolOptions.vmThreads.maxThreads](/config/#pooloptions-vmthreads-maxthreads)
-
-运行测试的最大线程数或百分比
-
-### poolOptions.vmThreads.useAtomics
-
-- **命令行终端:** `--poolOptions.vmThreads.useAtomics`
-- **配置:** [poolOptions.vmThreads.useAtomics](/config/#pooloptions-vmthreads-useatomics)
-
-使用 Atomics 同步线程。这在某些情况下可以提高性能,但在较旧的 Node 版本中可能会导致 segfault。 (默认值: `false`)
+### execArgv
-### poolOptions.vmThreads.memoryLimit
+- **命令行终端:** `--execArgv