vuejs/core
Testing
Vue uses Vitest for all of its tests. The configuration lives in vitest.config.ts, which defines several Vitest "projects" so different tests can run with different setups in a single command.
Running tests
# everything in watch mode (default vitest behavior)
pnpm test
# run once and exit (CI's mode)
pnpm test run
# all tests under a package
pnpm test runtime-core
# tests by file pattern (matches both filename and path)
pnpm test renderer
pnpm test reactivity/__tests__/effect
# a specific test name within matching files
pnpm test renderer -t "should mount component"
# only the unit project (skip e2e)
pnpm test-unit
# the e2e project (real browser via puppeteer)
pnpm test-e2e
# coverage report (writes to coverage/, mirrored at coverage.vuejs.org)
pnpm test-coverageFor type-level tests:
# build the .d.ts files first, then run dts-test
pnpm test-dts
# re-run only the dts-test project (assumes types are built)
pnpm test-dts-onlyProject layout
Each package's tests live in packages/<pkg>/__tests__/ and are colocated with the source. There are 195 spec/test files across the public packages:
| Package | Test files |
|---|---|
runtime-core |
45 |
compiler-core |
21 |
compiler-sfc |
20 |
vue |
20 |
server-renderer |
18 |
compiler-ssr |
16 |
reactivity |
16 |
runtime-dom |
16 |
compiler-dom |
13 |
vue-compat |
12 |
shared |
6 |
runtime-test |
1 |
packages-private/dts-test/ holds the type-level tests that run against the built .d.ts files.
vitest.config.ts configures three projects:
unit— runs against source code, fastest. The default forpnpm test. Includes setup filescripts/setup-vitest.tswhich installs__DEV__,__TEST__,__BROWSER__, etc., as globals so source files behave consistently.unit-jsdom— same asunitbut runs in a jsdom environment for tests that need awindow/document. Used byruntime-dom,vue, andserver-renderertests that exercise hydration.e2e— boots a real Chromium via puppeteer against the builtvue.global.jsand runs the HTML examples underpackages/vue/examples/__tests__/. Slow; only useful for verifying the global build works end-to-end.
The unit project is the right default. The setup file sets __DEV__ to true and stubs out other build flags so warning behavior is testable.
Writing a test
The contributing guide gives three rules:
- Use the minimal API needed. A test that doesn't need reactivity or a component shouldn't import them. Smaller surface area → fewer false failures when unrelated code changes.
- Use
@vue/runtime-testfor platform-agnostic behavior. ItsnodeOps.tsmints plain JS objects instead of DOM nodes, so renderer/scheduler tests stay isolated from the DOM. - Use platform runtimes only when testing platform behavior. Tests for
v-model, focus events, or hydration mismatches needruntime-dom+ jsdom.
Example skeleton from packages/runtime-test:
import { h, nodeOps, render, serializeInner } from '@vue/runtime-test';
test('mounts a div with text', () => {
const root = nodeOps.createElement('div');
render(h('div', 'hello'), root);
expect(serializeInner(root)).toBe('<div>hello</div>');
});packages/runtime-test/src/serialize.ts produces a stable string form of the node tree, which is the recommended way to assert renderer output.
Type tests
Type-level tests live in packages-private/dts-test/. They are TypeScript files containing expectType<T>(value) and expectError<T>(...) assertions that rely on the actual generated .d.ts files. To run:
pnpm test-dts # builds dts then runs
pnpm test-dts-only # runs against existing dts (faster)The script checks packages-private/dts-test/tsconfig.test.json against the built *.d.ts files. A passing build means the public types still hold up.
What CI runs
.github/workflows/test.yml runs the matrix:
pnpm test run(unit + unit-jsdom + e2e + dts) on Node 20 across Linux/macOS/Windows.pnpm test-coverageon Linux only, with the report uploaded.
.github/workflows/ci.yml separately runs pnpm check, pnpm lint, pnpm format-check. Failing any of these blocks merge.
Common pitfalls
- Forgetting
await nextTick()when mutating state in a test. Vue defers component updates to a microtask flush;expect(...)immediately after a mutation will see the pre-update DOM. - Mixing
runtime-domandruntime-testin the same suite leads to two separate copies of the renderer. Pick one and stick with it. - Tests that only improve coverage, not behavior, are explicitly discouraged. Coverage is a guidance metric, not a goal.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.