diff --git a/docs/config/index.md b/docs/config/index.md
index 9db22a946cdf..63d7a2e61150 100644
--- a/docs/config/index.md
+++ b/docs/config/index.md
@@ -586,7 +586,7 @@ By providing an object instead of a string you can define individual outputs whe
### pool 1.0.0+ {#pool}
- **Type:** `'threads' | 'forks' | 'vmThreads' | 'vmForks'`
-- **Default:** `'threads'`
+- **Default:** `'forks'` (in v1 `'threads'`)
- **CLI:** `--pool=threads`
Pool used to run tests in.
diff --git a/docs/guide/common-errors.md b/docs/guide/common-errors.md
index 5831dbae0674..b0b5082d7f58 100644
--- a/docs/guide/common-errors.md
+++ b/docs/guide/common-errors.md
@@ -65,9 +65,8 @@ This error can happen when NodeJS's `fetch` is used with default [`pool: 'thread
As work-around you can switch to [`pool: 'forks'`](/config/#forks) or [`pool: 'vmForks'`](/config/#vmforks).
-Specify `pool` in your configuration file:
-
-```ts
+::: code-group
+```ts [vitest.config.js]
import { defineConfig } from 'vitest/config'
export default defineConfig({
@@ -76,12 +75,33 @@ export default defineConfig({
},
})
```
+```bash [CLI]
+vitest --pool=forks
+```
+:::
-Or in your `package.json` scripts:
+## Segfaults and native code errors
-```diff
-scripts: {
-- "test": "vitest"
-+ "test": "vitest --pool=forks"
-}
+Running [native NodeJS modules](https://nodejs.org/api/addons.html) in `pool: 'threads'` can run into cryptic errors coming from the native code.
+
+- `Segmentation fault (core dumped)`
+- `thread '' panicked at 'assertion failed`
+- `Abort trap: 6`
+- `internal error: entered unreachable code`
+
+In these cases the native module is likely not built to be multi-thread safe. As work-around, you can switch to `pool: 'forks'` which runs the test cases in multiple `node:child_process` instead of multiple `node:worker_threads`.
+
+::: code-group
+```ts [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ pool: 'forks',
+ },
+})
+```
+```bash [CLI]
+vitest --pool=forks
```
+:::
diff --git a/docs/guide/improving-performance.md b/docs/guide/improving-performance.md
index 1ef6066ad4f0..71c6a0edba3e 100644
--- a/docs/guide/improving-performance.md
+++ b/docs/guide/improving-performance.md
@@ -1,5 +1,7 @@
# Improving Performance
+## Test isolation
+
By default Vitest runs every test file in an isolated environment based on the [pool](/config/#pool):
- `threads` pool runs every test file in a separate [`Worker`](https://nodejs.org/api/worker_threads.html#class-worker)
@@ -49,3 +51,24 @@ export default defineConfig({
})
```
:::
+
+## Pool
+
+By default Vitest runs tests in `pool: 'forks'`. While `'forks'` pool is better for compatibility issues ([hanging process](/guide/common-errors.html#failed-to-terminate-worker) and [segfaults](/guide/common-errors.html#segfaults-and-native-code-errors)), it may be slightly slower than `pool: 'threads'` in larger projects.
+
+You can try to improve test run time by switching `pool` option in configuration:
+
+::: code-group
+```bash [CLI]
+vitest --pool=threads
+```
+```ts [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ pool: 'threads',
+ },
+})
+```
+:::
diff --git a/packages/vitest/src/defaults.ts b/packages/vitest/src/defaults.ts
index 560e6a977a96..1dee107a6c00 100644
--- a/packages/vitest/src/defaults.ts
+++ b/packages/vitest/src/defaults.ts
@@ -67,7 +67,7 @@ const config = {
watch: !isCI,
globals: false,
environment: 'node' as const,
- pool: 'threads' as const,
+ pool: 'forks' as const,
clearMocks: false,
restoreMocks: false,
mockReset: false,
diff --git a/test/browser/vitest.config.unit.mts b/test/browser/vitest.config.unit.mts
index 0fa549ea6d1d..a2a1707127d2 100644
--- a/test/browser/vitest.config.unit.mts
+++ b/test/browser/vitest.config.unit.mts
@@ -4,8 +4,8 @@ export default defineConfig({
test: {
include: ['specs/**/*.{spec,test}.ts'],
poolOptions: {
- threads: {
- singleThread: true,
+ forks: {
+ singleFork: true,
},
},
hookTimeout: process.env.CI ? 120_000 : 10_000,
diff --git a/test/config/test/chai-config.test.ts b/test/config/test/chai-config.test.ts
index 9d99ba26eb5b..08c4f471d255 100644
--- a/test/config/test/chai-config.test.ts
+++ b/test/config/test/chai-config.test.ts
@@ -18,8 +18,7 @@ describe('truncateThreshold', () => {
ok 6 - test-each-title.test.ts > [ 'one', 'two', 'three', 'four', …(1) ]
ok 7 - test-each-title.test.ts > { one: 1, two: 2, three: 3 }
ok 8 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4 }
- ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }
- "
+ ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }"
`)
expect(result.exitCode).toBe(0)
})
@@ -43,8 +42,7 @@ describe('truncateThreshold', () => {
ok 6 - test-each-title.test.ts > [ 'one', 'two', 'three', 'four', …(1) ]
ok 7 - test-each-title.test.ts > { one: 1, two: 2, three: 3 }
ok 8 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4 }
- ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }
- "
+ ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }"
`)
expect(result.exitCode).toBe(0)
})
@@ -68,8 +66,7 @@ describe('truncateThreshold', () => {
ok 6 - test-each-title.test.ts > [ 'one', 'two', 'three', 'four', 'five' ]
ok 7 - test-each-title.test.ts > { one: 1, two: 2, three: 3 }
ok 8 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4 }
- ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4, five: 5 }
- "
+ ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4, five: 5 }"
`)
expect(result.exitCode).toBe(0)
})
@@ -77,5 +74,5 @@ describe('truncateThreshold', () => {
function cleanOutput(output: string) {
// remove non-deterministic output
- return output.replaceAll(/\s*# time=.*/g, '')
+ return output.replaceAll(/\s*# time=.*/g, '').trim()
}
diff --git a/test/config/test/failures.test.ts b/test/config/test/failures.test.ts
index 85a2973d7f84..4f3ca721d13e 100644
--- a/test/config/test/failures.test.ts
+++ b/test/config/test/failures.test.ts
@@ -144,7 +144,6 @@ test('boolean flag 100 should not crash CLI', async () => {
test('nextTick cannot be mocked inside child_process', async () => {
const { stderr } = await runVitest({
- pool: 'forks',
fakeTimers: { toFake: ['nextTick'] },
include: ['./fake-timers.test.ts'],
})
@@ -154,6 +153,7 @@ test('nextTick cannot be mocked inside child_process', async () => {
test('nextTick can be mocked inside worker_threads', async () => {
const { stderr } = await runVitest({
+ pool: 'threads',
fakeTimers: { toFake: ['nextTick'] },
include: ['./fixtures/test/fake-timers.test.ts'],
})
diff --git a/test/watch/vitest.config.ts b/test/watch/vitest.config.ts
index a4a312f5d826..3eda83706106 100644
--- a/test/watch/vitest.config.ts
+++ b/test/watch/vitest.config.ts
@@ -13,13 +13,10 @@ export default defineConfig({
testTimeout: process.env.CI ? 60_000 : 10_000,
// Test cases may have side effects, e.g. files under fixtures/ are modified on the fly to trigger file watchers
- poolOptions: {
- forks: { singleFork: true },
- threads: { singleThread: true },
- vmThreads: { singleThread: true },
- },
+ fileParallelism: false,
// TODO: Fix flakiness and remove
allowOnly: true,
+ bail: 1,
},
})