diff --git a/.vitepress/config.ts b/.vitepress/config.ts index c00fcac6..c88bb295 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -515,6 +515,10 @@ export default ({ mode }: { mode: string }) => { text: 'retry', link: '/config/retry', }, + { + text: 'repeats', + link: '/config/repeats', + }, { text: 'onConsoleLog', link: '/config/onconsolelog', diff --git a/api/assert.md b/api/assert.md index f7ed29d7..5dad88bd 100644 --- a/api/assert.md +++ b/api/assert.md @@ -1,6 +1,34 @@ # assert Vitest 从 [`chai`](https://www.chaijs.com/api/assert/) 重新导出了 `assert` 方法,用于验证不变量。 + +::: warning In-Source Testing {#in-source-testing} +When using [assertion functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions) such as `assert` from `import.meta.vitest` in [in-source tests](/guide/in-source), TypeScript reports error `TS2775` because they must be called via an explicitly annotated name. Annotate the variable with `Chai.Assert` or call it directly: + +::: code-group +```ts [Annotated variable] +if (import.meta.vitest) { + const { test, assert } = import.meta.vitest // [!code --] + const { test } = import.meta.vitest // [!code ++] + const assert: Chai.Assert = import.meta.vitest.assert // [!code ++] + + test('assert', () => { + assert('foo' !== 'bar', 'foo should not be equal to bar') + }) +} +``` +```ts [Direct call] +if (import.meta.vitest) { + const { test, assert } = import.meta.vitest // [!code --] + const { test } = import.meta.vitest // [!code ++] + + test('assert', () => { + assert('foo' !== 'bar', 'foo should not be equal to bar') // [!code --] + import.meta.vitest!.assert('foo' !== 'bar', 'foo should not be equal to bar') // [!code ++] + }) +} +``` +::: ## assert diff --git a/config/repeats.md b/config/repeats.md new file mode 100644 index 00000000..7f13ebba --- /dev/null +++ b/config/repeats.md @@ -0,0 +1,14 @@ +--- +title: repeats | Config +outline: deep +--- + +# repeats + +- **Type:** `number` +- **Default:** `0` +- **CLI:** `--repeats=` + +Repeat every test a specific number of times regardless of the result. A test that uses the [`repeats`](/api/test#repeats) test option takes precedence over this value. + +This is useful for verifying that tests are stable across multiple runs. If a test fails on any repetition, the whole test is reported as failed. diff --git a/guide/browser/index.md b/guide/browser/index.md index 7de24e3f..40d27ee8 100644 --- a/guide/browser/index.md +++ b/guide/browser/index.md @@ -119,8 +119,6 @@ export default defineConfig({ ::: info Vitest 默认分配端口号 `63315` 以避免与开发服务器冲突,允许我们同时并行运行两者。我们可以通过 [`browser.api`](/config/browser/api) 选项来更改这个端口号。 - -CLI 不会自动打印 Vite 服务器 URL。在观察模式下运行时,你可以按 "b" 键来打印 URL。 ::: 如果之前未使用过 Vite,请确保已安装框架插件并在配置中指定。有些框架可能需要额外配置才能运行,请查看其 Vite 相关文档以确定。 diff --git a/guide/cli-generated.md b/guide/cli-generated.md index c99b18cd..9a0c9c0d 100644 --- a/guide/cli-generated.md +++ b/guide/cli-generated.md @@ -636,6 +636,13 @@ UI 模式和 HTML 报告器中提供的 HTML 覆盖率输出目录。 - **配置:** [retry.condition](/config/retry#retry-condition) 触发重试操作的错误信息匹配正则表达式。仅当错误信息符合该模式时才会执行重试(默认值:所有错误都会触发重试) + +### repeats + +- **CLI:** `--repeats ` +- **Config:** [repeats](/config/repeats) + +Repeat every test a specific number of times regardless of the result (default: `0`) ### diff.aAnnotation diff --git a/guide/in-source.md b/guide/in-source.md index ec956321..0add6597 100644 --- a/guide/in-source.md +++ b/guide/in-source.md @@ -154,6 +154,10 @@ module.exports = { ``` 完整的示例请参考 [`examples/in-source-test`](https://github.com/vitest-dev/vitest/tree/main/examples/in-source-test)。 + +::: warning +There is a limitation when using [assertion functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions) such as `assert` in in-source tests. See [`assert`](/api/assert#in-source-testing) for details and workarounds. +::: ## 说明 {#notes} diff --git a/guide/learn/setup-teardown.md b/guide/learn/setup-teardown.md index cd367286..1823e439 100644 --- a/guide/learn/setup-teardown.md +++ b/guide/learn/setup-teardown.md @@ -33,15 +33,20 @@ test('items starts with 3 fruits', () => { expect(items).toHaveLength(3) }) +test('can remove an item', () => { + items.pop() + expect(items).toHaveLength(2) +}) + test('can add an item', () => { items.push('date') expect(items).toHaveLength(4) - // afterEach 会为下一个测试重置项目, - // 因此此处的修改不会影响到其他测试 + // beforeEach reset the array to 3 items before this test ran, + // proving that mutations from the previous test do not leak. }) ``` - -如果没有这些钩子,第二个测试的 `push` 操作会影响其后的所有测试,这是导致测试不稳定的典型原因。这些钩子确保了每个测试都拥有干净的状态。 + +Without these hooks, mutations like `pop` or `push` from earlier tests would affect subsequent ones, which is a classic source of flaky tests, while the hooks guarantee clean state for every test. ## 一次性初始化 {#one-time-setup} diff --git a/guide/migration.md b/guide/migration.md index 54d8b71f..1758c866 100644 --- a/guide/migration.md +++ b/guide/migration.md @@ -138,6 +138,12 @@ $ cd subdir && vitest --config ../vitest.config.ts # [!code ++] Assignments to properties on `globalThis` or `window` in `jsdom` and `happy-dom` environments are now propagated to the underlying DOM implementation. Mutable properties such as `innerWidth` can affect APIs implemented by the DOM environment, for example `happy-dom`'s `matchMedia`. +### Browser Orchestrator URL Requires a Session + +Vitest no longer serves the browser orchestrator UI from a bare `/__vitest_test__/` URL. Browser runner URLs are now session-bound and must include the `sessionId` generated by Vitest, for example `/__vitest_test__/?sessionId=...`. + +If you manually opened the browser preview by copying the Vite server URL or visiting `/__vitest_test__/` directly, use the URL opened or printed by Vitest instead. + ## 迁移至 Vitest 4.0 {#vitest-4} ::: warning 前提条件