From 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Fri, 10 Apr 2026 06:11:47 +0200 Subject: [PATCH 1/2] docs: expand test filtering and parallelism docs (#10116) --- guide/filtering.md | 165 +++++++++++++++++++++++-------------------- guide/parallelism.md | 68 +++++++++++++++--- 2 files changed, 146 insertions(+), 87 deletions(-) diff --git a/guide/filtering.md b/guide/filtering.md index 56fa545d..3c7501dc 100644 --- a/guide/filtering.md +++ b/guide/filtering.md @@ -4,17 +4,35 @@ title: Test Filtering | Guide # Test Filtering -Filtering, timeouts, concurrent for suite and tests +As your test suite grows, running every test on every change becomes slow and distracting. If you're fixing a bug in a single module, you don't need to wait for hundreds of unrelated tests to finish. Test filtering lets you narrow down which tests run so you can stay focused on the code you're actively working on. -## CLI +Vitest offers several ways to filter tests: from the command line, inside your test files, and through tags. Each approach is useful in different situations. -You can use CLI to filter test files by name: +::: tip Performance Note +Filters like `-t`, `--tags-filter`, `.only`, and `.skip` are applied *per test file* — Vitest still has to run each test file to discover which tests match. In a large project, this overhead adds up even if only a few tests actually execute. + +To avoid this, always pass a file path alongside your filter so Vitest only loads the files you care about: ```bash -$ vitest basic +vitest utils.test.ts -t "handles empty input" ``` -Will only execute test files that contain `basic`, e.g. +Alternatively, you can use the [`--experimental.preParse`](/config/experimental#experimental-preparse) flag, which parses test files to discover test names without fully executing them: + +```bash +vitest --experimental.preParse -t "handles empty input" +``` +::: + +## Filtering by File Name + +The simplest way to run a subset of tests is to pass a filename pattern as a CLI argument. Vitest will only run test files whose path contains the given string: + +```bash +vitest basic +``` + +This matches any test file with `basic` in its path: ``` basic.test.ts @@ -22,76 +40,52 @@ basic-foo.test.ts basic/foo.test.ts ``` -You can also use the `-t, --testNamePattern ` option to filter tests by full name. This can be helpful when you want to filter by the name defined within a file rather than the filename itself. - -Since Vitest 3, you can also specify the test by filename and line number: +This is useful when you know which file you need to work on and want to skip everything else. -```bash -$ vitest basic/foo.test.ts:10 -``` +## Filtering by Test Name -::: warning -Note that Vitest requires the full filename for this feature to work. It can be relative to the current working directory or an absolute file path. +Sometimes the test you care about is buried in a file with many other tests. The `-t` (or `--testNamePattern`) option filters by the test's name rather than the filename. It accepts a regex pattern and matches against the full test name, which includes any `describe` block names: ```bash -$ vitest basic/foo.js:10 # ✅ -$ vitest ./basic/foo.js:10 # ✅ -$ vitest /users/project/basic/foo.js:10 # ✅ -$ vitest foo:10 # ❌ -$ vitest ./basic/foo:10 # ❌ +vitest -t "handles empty input" ``` -At the moment Vitest also doesn't support ranges: +You can combine this with a file filter to narrow things down further: ```bash -$ vitest basic/foo.test.ts:10, basic/foo.test.ts:25 # ✅ -$ vitest basic/foo.test.ts:10-25 # ❌ +vitest utils -t "handles empty input" ``` -::: -## Specifying a Timeout +This runs only tests whose name matches `"handles empty input"` inside files matching `utils`. -You can optionally pass a timeout in milliseconds as a third argument to tests. The default is [5 seconds](/config/testtimeout). +## Filtering by Line Number -```ts -import { test } from 'vitest' +When you're looking at a specific test in your editor, you often just want to run *that one test*. You can point directly to a line number: -test('name', async () => { /* ... */ }, 1000) +```bash +vitest basic/foo.test.ts:10 ``` -Hooks also can receive a timeout, with the same 5 seconds default. - -```ts -import { beforeAll } from 'vitest' +Vitest will run the test that contains line 10. This requires the full filename (relative or absolute): -beforeAll(async () => { /* ... */ }, 1000) +```bash +vitest basic/foo.test.ts:10 # ✅ +vitest ./basic/foo.test.ts:10 # ✅ +vitest /users/project/basic/foo.test.ts:10 # ✅ +vitest foo:10 # ❌ partial name won't work +vitest ./basic/foo:10 # ❌ missing file extension ``` -## Skipping Suites and Tests - -Use `.skip` to avoid running certain suites or tests - -```ts -import { assert, describe, it } from 'vitest' - -describe.skip('skipped suite', () => { - it('test', () => { - // Suite skipped, no error - assert.equal(Math.sqrt(4), 3) - }) -}) +To run multiple specific tests, separate them with spaces: -describe('suite', () => { - it.skip('skipped test', () => { - // Test skipped, no error - assert.equal(Math.sqrt(4), 3) - }) -}) +```bash +vitest basic/foo.test.ts:10 basic/foo.test.ts:25 # ✅ +vitest basic/foo.test.ts:10-25 # ❌ ranges are not supported ``` -## Filtering Tags +## Filtering by Tags -If your test defines a [tag](/guide/test-tags), you can filter your tests with a `--tags-filter` option: +For larger projects, you may want to categorize tests and run them by category. [Tags](/guide/test-tags) let you label tests and then filter by those labels from the CLI: ```ts test('renders a form', { tags: ['frontend'] }, () => { @@ -103,66 +97,83 @@ test('calls an external API', { tags: ['backend'] }, () => { }) ``` -```shell +```bash vitest --tags-filter=frontend ``` -## Selecting Suites and Tests to Run +This is particularly helpful in CI pipelines where you might want to run frontend and backend tests in separate jobs, or skip slow integration tests during quick checks. + +## Focusing on Specific Tests with `.only` -Use `.only` to only run certain suites or tests +When you're debugging a failing test, you want to run just that test without modifying CLI arguments every time. Adding `.only` to a test or suite tells Vitest to skip everything else in the file: ```ts -import { assert, describe, it } from 'vitest' +import { describe, expect, it } from 'vitest' -// Only this suite (and others marked with only) are run describe.only('suite', () => { it('test', () => { - assert.equal(Math.sqrt(4), 3) + // This runs because the suite is marked with .only + expect(Math.sqrt(4)).toBe(2) }) }) describe('another suite', () => { it('skipped test', () => { - // Test skipped, as tests are running in Only mode - assert.equal(Math.sqrt(4), 3) + // This does not run + expect(Math.sqrt(4)).toBe(2) }) - it.only('test', () => { - // Only this test (and others marked with only) are run - assert.equal(Math.sqrt(4), 2) + it.only('focused test', () => { + // This also runs because it is marked with .only + expect(Math.sqrt(4)).toBe(2) }) }) ``` -Run Vitest with a file filter and a line number: +You can use `.only` on both `describe` blocks and individual tests. When any test or suite in a file is marked with `.only`, all unmarked tests in that file are skipped. -```shell -vitest ./test/example.test.ts:5 -``` +::: warning +Remember to remove `.only` before committing. By default, Vitest will fail the entire test run if it encounters `.only` in CI (when `process.env.CI` is set), preventing you from accidentally skipping tests in your pipeline. This behavior is controlled by the [`allowOnly`](/config/allowonly) option. + +To catch `.only` even earlier, the [`no-focused-tests`](https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md) ESLint rule (also available in [oxlint](https://oxc.rs/docs/guide/usage/linter/rules/jest/no-focused-tests.html)) can flag it in your editor before you commit. +::: -```ts:line-numbers -import { assert, describe, it } from 'vitest' +## Skipping Tests with `.skip` -describe('suite', () => { - // Run only this test +The opposite of `.only` is `.skip`. Use it to temporarily disable a test or suite without deleting it. Skipped tests still show up in the report so you don't forget about them: + +```ts +import { describe, expect, it } from 'vitest' + +describe.skip('skipped suite', () => { it('test', () => { - assert.equal(Math.sqrt(4), 3) + // This entire suite is skipped + expect(Math.sqrt(4)).toBe(2) + }) +}) + +describe('suite', () => { + it.skip('skipped test', () => { + // Just this one test is skipped + expect(Math.sqrt(4)).toBe(2) }) }) ``` -## Unimplemented Suites and Tests +This is useful when a test is flaky or depends on an external service that's temporarily down. It lets you keep the test in place as a reminder while unblocking the rest of the suite. + +## Placeholder Tests with `.todo` -Use `.todo` to stub suites and tests that should be implemented +When planning new features, you might know what tests you'll need before you write the actual implementation. `.todo` marks a test as planned but not yet written. It shows up in the report as a reminder: ```ts import { describe, it } from 'vitest' -// An entry will be shown in the report for this suite describe.todo('unimplemented suite') -// An entry will be shown in the report for this test describe('suite', () => { it.todo('unimplemented test') }) ``` + +Unlike `.skip`, a `.todo` test has no test body. It's purely a placeholder for future work. diff --git a/guide/parallelism.md b/guide/parallelism.md index c2033531..4c694c3b 100644 --- a/guide/parallelism.md +++ b/guide/parallelism.md @@ -5,28 +5,51 @@ outline: deep # Parallelism +Vitest has two levels of parallelism: it can run multiple *test files* at the same time, and within each file it can run multiple *tests* at the same time. Understanding the difference between the two is important because they work differently and have different trade-offs. + ## File Parallelism -By default, Vitest runs _test files_ in parallel. Depending on the specified `pool`, Vitest uses a different mechanism to parallelize test files: +By default, Vitest runs test files in parallel across multiple workers. Each file gets its own isolated environment, so tests in different files can't interfere with each other. + +The mechanism Vitest uses to create workers depends on the configured [`pool`](/config/pool): + +- `forks` (the default) and `vmForks` run each file in a separate [child process](https://nodejs.org/api/child_process.html) +- `threads` and `vmThreads` run each file in a separate [worker thread](https://nodejs.org/api/worker_threads.html) -- `forks` (the default) and `vmForks` run tests in different [child processes](https://nodejs.org/api/child_process.html) -- `threads` and `vmThreads` run tests in different [worker threads](https://nodejs.org/api/worker_threads.html) +You can control how many workers run simultaneously with the [`maxWorkers`](/config/maxworkers) option. More workers means more files run in parallel, but also more memory and CPU usage. The right number depends on your machine and how heavy your tests are. -Both "child processes" and "worker threads" are referred to as "workers". You can configure the number of running workers with [`maxWorkers`](/config/maxworkers) option. +For most projects, file parallelism is the single biggest factor in test suite speed. However, there are cases where you might want to disable it — for example, if your tests share an external resource like a database that can't handle concurrent access. You can set [`fileParallelism`](/config/fileparallelism) to `false` to run files one at a time. -If you have a lot of tests, it is usually faster to run them in parallel, but it also depends on the project, the environment and [isolation](/config/isolate) state. To disable file parallelisation, you can set [`fileParallelism`](/config/fileparallelism) to `false`. To learn more about possible performance improvements, read the [Performance Guide](/guide/improving-performance). +To learn more about tuning performance, see the [Performance Guide](/guide/improving-performance). ## Test Parallelism -Unlike _test files_, Vitest runs _tests_ in sequence. This means that tests inside a single test file will run in the order they are defined. +Within a single file, Vitest runs tests sequentially by default. Tests execute in the order they are defined, one after another. This is the safest default because tests within a file often share setup and state through lifecycle hooks like `beforeEach`. + +If the tests in a file are independent, you can opt into running them concurrently with the [`concurrent`](/api/test#test-concurrent) modifier: + +```ts +import { expect, test } from 'vitest' + +test.concurrent('fetches user profile', async () => { + const user = await fetchUser(1) + expect(user.name).toBe('Alice') +}) -Vitest supports the [`concurrent`](/api/test#test-concurrent) option to run tests together. If this option is set, Vitest will group concurrent tests in the same _file_ (the number of simultaneously running tests depends on the [`maxConcurrency`](/config/maxconcurrency) option) and run them with [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all). +test.concurrent('fetches user posts', async () => { + const posts = await fetchPosts(1) + expect(posts).toHaveLength(3) +}) +``` -The hook execution order within a single group is also controlled by [`sequence.hooks`](/config/sequence#sequence-hooks). With `sequence.hooks: 'parallel'`, the execution is bounded by the same limit of [`maxConcurrency`](/config/maxconcurrency). +When tests are marked as `concurrent`, Vitest groups them together and runs them with [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all). The number of tests running at once is bounded by the [`maxConcurrency`](/config/maxconcurrency) option. -Vitest doesn't perform any smart analysis and doesn't create additional workers to run these tests. This means that the performance of your tests will improve only if you rely heavily on asynchronous operations. For example, these tests will still run one after another even though the `concurrent` option is specified. This is because they are synchronous: +::: tip When does `concurrent` actually help? +Vitest doesn't create extra workers for concurrent tests — they all run in the same worker as the file they belong to. This means `concurrent` only speeds things up when your tests spend time *waiting* (on network requests, timers, file I/O, etc.). Purely synchronous tests won't benefit because they still block the single JavaScript thread: ```ts +// These run one after another despite `concurrent`, +// because there is nothing to await test.concurrent('the first test', () => { expect(1).toBe(1) }) @@ -35,5 +58,30 @@ test.concurrent('the second test', () => { expect(2).toBe(2) }) ``` +::: + +You can also apply `concurrent` to an entire suite: + +```ts +import { describe, expect, test } from 'vitest' + +describe.concurrent('user API', () => { + test('fetches profile', async () => { + const user = await fetchUser(1) + expect(user.name).toBe('Alice') + }) + + test('fetches posts', async () => { + const posts = await fetchPosts(1) + expect(posts).toHaveLength(3) + }) +}) +``` + +If you want *all* tests in your project to run concurrently by default, set [`sequence.concurrent`](/config/sequence#sequence-concurrent) to `true` in your config. + +### Hooks with Concurrent Tests + +When tests run concurrently, lifecycle hooks behave differently. `beforeAll` and `afterAll` still run once for the group, but `beforeEach` and `afterEach` run for each test — potentially at the same time, since the tests themselves overlap. -If you wish to run all tests concurrently, you can set the [`sequence.concurrent`](/config/sequence#sequence-concurrent) option to `true`. +The hook execution order is controlled by [`sequence.hooks`](/config/sequence#sequence-hooks). With `sequence.hooks: 'parallel'`, hooks are also bounded by the [`maxConcurrency`](/config/maxconcurrency) limit. From 2cd65cca7596b69d875662dc1981ef41e2427e90 Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 13 Apr 2026 10:53:41 +0800 Subject: [PATCH 2/2] docs(cn): dissolve the conflict --- guide/filtering.md | 126 +------------------------------------------ guide/parallelism.md | 33 ++---------- 2 files changed, 5 insertions(+), 154 deletions(-) diff --git a/guide/filtering.md b/guide/filtering.md index e3ff3664..f21991b4 100644 --- a/guide/filtering.md +++ b/guide/filtering.md @@ -1,16 +1,9 @@ --- title: 测试筛选 | 指南 --- - + # 测试筛选 {#test-filtering} -<<<<<<< HEAD -筛选、超时和测试套件的并发。 - -## CLI {#cli} - -你可以使用 CLI 按名称筛选测试文件: -======= As your test suite grows, running every test on every change becomes slow and distracting. If you're fixing a bug in a single module, you don't need to wait for hundreds of unrelated tests to finish. Test filtering lets you narrow down which tests run so you can stay focused on the code you're actively working on. Vitest offers several ways to filter tests: from the command line, inside your test files, and through tags. Each approach is useful in different situations. @@ -19,15 +12,11 @@ Vitest offers several ways to filter tests: from the command line, inside your t Filters like `-t`, `--tags-filter`, `.only`, and `.skip` are applied *per test file* — Vitest still has to run each test file to discover which tests match. In a large project, this overhead adds up even if only a few tests actually execute. To avoid this, always pass a file path alongside your filter so Vitest only loads the files you care about: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ```bash vitest utils.test.ts -t "handles empty input" ``` -<<<<<<< HEAD -将只执行包含 `basic` 的测试文件,例如: -======= Alternatively, you can use the [`--experimental.preParse`](/config/experimental#experimental-preparse) flag, which parses test files to discover test names without fully executing them: ```bash @@ -44,7 +33,6 @@ vitest basic ``` This matches any test file with `basic` in its path: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ``` basic.test.ts @@ -52,90 +40,22 @@ basic-foo.test.ts basic/foo.test.ts ``` -<<<<<<< HEAD -你还可以使用 `-t, --testNamePattern ` 选项按全名过滤测试。当你想按文件内定义的名称而不是文件名本身进行过滤时,这将非常有用。 - -自 Vitest 3 起,也可以通过文件名和行号来指定测试: -======= This is useful when you know which file you need to work on and want to skip everything else. ## Filtering by Test Name Sometimes the test you care about is buried in a file with many other tests. The `-t` (or `--testNamePattern`) option filters by the test's name rather than the filename. It accepts a regex pattern and matches against the full test name, which includes any `describe` block names: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ```bash vitest -t "handles empty input" ``` -<<<<<<< HEAD -::: warning -请注意,Vitest 需要完整的文件名才能使此功能正常工作。文件名可以是相对于当前工作目录的路径,也可以是绝对文件路径。 -======= You can combine this with a file filter to narrow things down further: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ```bash vitest utils -t "handles empty input" ``` -<<<<<<< HEAD -目前,Vitest 还不支持范围: - -```bash -$ vitest basic/foo.test.ts:10, basic/foo.test.ts:25 # ✅ -$ vitest basic/foo.test.ts:10-25 # ❌ -``` -::: - -## 指定超时阈值 {#specifying-a-timeout} - -你可以选择将超时阈值(以毫秒为单位)作为第三个参数传递给测试。默认值为 [5 秒](/config/testtimeout)。 - -```ts -import { test } from 'vitest' - -test('name', async () => { - /* ... */ -}, 1000) -``` - -Hooks 也可以接收超时阈值,默认值为 5 秒。 - -```ts -import { beforeAll } from 'vitest' - -beforeAll(async () => { - /* ... */ -}, 1000) -``` - -## 跳过测试套件和测试 {#skipping-suites-and-tests} - -使用 `.skip` 以避免运行某些测试套件或测试 - -```ts -import { assert, describe, it } from 'vitest' - -describe.skip('skipped suite', () => { - it('test', () => { - // 已跳过此测试套件,无错误 - assert.equal(Math.sqrt(4), 3) - }) -}) - -describe('suite', () => { - it.skip('skipped test', () => { - // 已跳过此测试,无错误 - assert.equal(Math.sqrt(4), 3) - }) -}) -``` - -## 标签过滤 {#filtering-tags} - -若测试中定义了 [标签](/guide/test-tags),可通过 `--tags-filter` 选项进行筛选: -======= This runs only tests whose name matches `"handles empty input"` inside files matching `utils`. ## Filtering by Line Number @@ -166,7 +86,6 @@ vitest basic/foo.test.ts:10-25 # ❌ ranges are not supported ## Filtering by Tags For larger projects, you may want to categorize tests and run them by category. [Tags](/guide/test-tags) let you label tests and then filter by those labels from the CLI: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ```ts test('renders a form', { tags: ['frontend'] }, () => { @@ -182,25 +101,15 @@ test('calls an external API', { tags: ['backend'] }, () => { vitest --tags-filter=frontend ``` -<<<<<<< HEAD -## 选择要运行的测试套件和测试 {#selecting-suites-and-tests-to-run} - -使用 `.only` 仅运行某些测试套件或测试 -======= This is particularly helpful in CI pipelines where you might want to run frontend and backend tests in separate jobs, or skip slow integration tests during quick checks. ## Focusing on Specific Tests with `.only` When you're debugging a failing test, you want to run just that test without modifying CLI arguments every time. Adding `.only` to a test or suite tells Vitest to skip everything else in the file: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ```ts import { describe, expect, it } from 'vitest' -<<<<<<< HEAD -// 仅运行此测试套件(以及标记为 Only 的其他测试套件) -======= ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 describe.only('suite', () => { it('test', () => { // This runs because the suite is marked with .only @@ -210,15 +119,6 @@ describe.only('suite', () => { describe('another suite', () => { it('skipped test', () => { -<<<<<<< HEAD - // 已跳过测试,因为测试在 Only 模式下运行 - assert.equal(Math.sqrt(4), 3) - }) - - it.only('test', () => { - // 仅运行此测试(以及标记为 Only 的其他测试) - assert.equal(Math.sqrt(4), 2) -======= // This does not run expect(Math.sqrt(4)).toBe(2) }) @@ -226,16 +126,11 @@ describe('another suite', () => { it.only('focused test', () => { // This also runs because it is marked with .only expect(Math.sqrt(4)).toBe(2) ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 }) }) ``` -<<<<<<< HEAD -运行 Vitest 时指定文件过滤器和行号: -======= You can use `.only` on both `describe` blocks and individual tests. When any test or suite in a file is marked with `.only`, all unmarked tests in that file are skipped. ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ::: warning Remember to remove `.only` before committing. By default, Vitest will fail the entire test run if it encounters `.only` in CI (when `process.env.CI` is set), preventing you from accidentally skipping tests in your pipeline. This behavior is controlled by the [`allowOnly`](/config/allowonly) option. @@ -258,43 +153,24 @@ describe.skip('skipped suite', () => { }) describe('suite', () => { -<<<<<<< HEAD - // 仅运行此测试 - it('test', () => { - assert.equal(Math.sqrt(4), 3) -======= it.skip('skipped test', () => { // Just this one test is skipped expect(Math.sqrt(4)).toBe(2) ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 }) }) ``` -<<<<<<< HEAD -## 未实现的测试套件和测试 {#unimplemented-suites-and-tests} - -使用 `.todo` 留存将要实施的测试套件和测试的待办事项 -======= This is useful when a test is flaky or depends on an external service that's temporarily down. It lets you keep the test in place as a reminder while unblocking the rest of the suite. ## Placeholder Tests with `.todo` When planning new features, you might know what tests you'll need before you write the actual implementation. `.todo` marks a test as planned but not yet written. It shows up in the report as a reminder: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ```ts import { describe, it } from 'vitest' -<<<<<<< HEAD -// 此测试套件的报告中将显示一个条目 -describe.todo('unimplemented suite') - -// 此测试的报告中将显示一个条目 -======= describe.todo('unimplemented suite') ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 describe('suite', () => { it.todo('unimplemented test') }) diff --git a/guide/parallelism.md b/guide/parallelism.md index 3b864850..fd0c745a 100644 --- a/guide/parallelism.md +++ b/guide/parallelism.md @@ -1,25 +1,15 @@ --- -title: 并行性 | Guide +title: 并行性 | 指南 outline: deep --- -# 并行性 {#parallelism} - -<<<<<<< HEAD -## 文件级并行 {#file-parallelism} - -默认情况下,Vitest 会并行运行 _测试文件_。根据指定的 `pool`,Vitest 会采用不同的并行化机制: - -- `forks`(默认)和 `vmForks` 会在不同的 [child processes](https://nodejs.org/api/child_process.html) 中执行测试 -- `threads` 和 `vmThreads` 则会在不同的 [worker threads](https://nodejs.org/api/worker_threads.html) 中运行 + -“子进程(child processes)” 和 “工作线程(worker threads)” 都统称为 “工作者(workers)”。你可以通过 [`maxWorkers`](/config/maxworkers) 选项配置运行的工作者数量。 +# 并行性 {#parallelism} -如果项目包含大量测试文件,通常并行执行会大幅提升速度。但具体效果还要看项目本身、运行环境以及是否启用了 [隔离](/config/isolate)。若需要关闭文件级并行化,可以将 [`fileParallelism`](/config/fileparallelism) 设为 `false` 。更多性能优化技巧,请参考 [性能指南](/guide/improving-performance) 。 -======= Vitest has two levels of parallelism: it can run multiple *test files* at the same time, and within each file it can run multiple *tests* at the same time. Understanding the difference between the two is important because they work differently and have different trade-offs. -## File Parallelism +## 文件级并行 {#file-parallelism} By default, Vitest runs test files in parallel across multiple workers. Each file gets its own isolated environment, so tests in different files can't interfere with each other. @@ -33,23 +23,12 @@ You can control how many workers run simultaneously with the [`maxWorkers`](/con For most projects, file parallelism is the single biggest factor in test suite speed. However, there are cases where you might want to disable it — for example, if your tests share an external resource like a database that can't handle concurrent access. You can set [`fileParallelism`](/config/fileparallelism) to `false` to run files one at a time. To learn more about tuning performance, see the [Performance Guide](/guide/improving-performance). ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ## 测试级并行 {#test-parallelism} -<<<<<<< HEAD -与 _测试文件_ 不同, Vitest 在同一个文件中会顺序执行 _测试用例_ 。也就是说,同一个文件里的测试会按定义顺序一个接一个地执行。 - -Vitest 支持通过 [`concurrent`](/api/test#test-concurrent) 选项并行运行测试。当启用该选项时,Vitest 会将同一 _文件_ 中的并发测试分组(同时运行的测试数量取决于 [`maxConcurrency`](/config/maxconcurrency) 配置),并通过 [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) 一起执行。 - -单个分组内钩子的执行顺序同样受 [`sequence.hooks`](/config/sequence#sequence-hooks) 控制。当设置 `sequence.hooks: 'parallel'` 时,执行受 [`maxConcurrency`](/config/maxconcurrency) 相同限制的约束。 - -Vitest 不会自动分析你的测试是否可以并行,也不会为了并发而额外创建工作者。这意味着,只有在测试中有大量异步操作时,使用并发才能提升性能。例如,以下示例即便指定了 concurrent ,也会顺序执行,因为它们是同步的: -======= Within a single file, Vitest runs tests sequentially by default. Tests execute in the order they are defined, one after another. This is the safest default because tests within a file often share setup and state through lifecycle hooks like `beforeEach`. If the tests in a file are independent, you can opt into running them concurrently with the [`concurrent`](/api/test#test-concurrent) modifier: ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676 ```ts import { expect, test } from 'vitest' @@ -83,9 +62,6 @@ test.concurrent('the second test', () => { ``` ::: -<<<<<<< HEAD -如果希望所有测试用例都并发执行,可以将 [`sequence.concurrent`](/config/sequence#sequence-concurrent) 配置项设为 `true` 。 -======= You can also apply `concurrent` to an entire suite: ```ts @@ -111,4 +87,3 @@ If you want *all* tests in your project to run concurrently by default, set [`se When tests run concurrently, lifecycle hooks behave differently. `beforeAll` and `afterAll` still run once for the group, but `beforeEach` and `afterEach` run for each test — potentially at the same time, since the tests themselves overlap. The hook execution order is controlled by [`sequence.hooks`](/config/sequence#sequence-hooks). With `sequence.hooks: 'parallel'`, hooks are also bounded by the [`maxConcurrency`](/config/maxconcurrency) limit. ->>>>>>> 1df9a43d68d7337e9df5dc24c97c34d47b7b0676