new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Vitest · Guide · all subjects

debugging

12 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Stale snapshot test failures

When using snapshot tests, if you intentionally change the output of your code, the existing snapshots become outdated and the test fails showing a diff between the old snapshot and new output. Review the diff to confirm the changes are correct, then update snapshots by pressing `u` in watch mode or running `vitest -u`.

Fixing wrong test environment errors

If code accesses browser APIs like `document` or `window` and you see errors like 'document is not defined', the test is running in Node environment (the default). Switch to a browser-like environment using the `environment` config option, or use Browser Mode which runs tests in a real browser.

Auto-restore mocks to prevent leaks between tests

If mocks from one test leak into another (like a `vi.spyOn` that persists its override), enable automatic mock restoration in vitest.config.js with the `restoreMocks: true` option in the test configuration. This calls `mockRestore()` on every mock after each test.

Using console.log for debugging tests

Adding `console.log` to tests is a valid debugging technique. Vitest displays console output inline with test results, so you can see which test produced which log output. This is the fastest way to inspect values and understand what's happening during a test.

Vitest UI for visual test overview

Run `vitest --ui` to open a browser-based dashboard showing all tests, their status, and output. The dashboard includes a module graph showing how files are connected, which helps understand why changes in one file cause failures in another.

Attaching a debugger to Vitest

For complex issues requiring line-by-line code stepping, run Vitest with `vitest --inspect-brk --no-file-parallelism` to enable debugging. The `--no-file-parallelism` flag ensures tests run in the main thread so breakpoints work reliably. Then attach a debugger from VS Code, IntelliJ, or Chrome DevTools at `chrome://inspect`.

Test isolation problems and inter-test failures

If a test passes when run alone but fails when run with others, the problem is test isolation. Check for shared state modifications that aren't cleaned up. If a test fails even when run alone, the issue is in the test itself or the code it's testing.

Understanding test failure output components

When a test fails in Vitest, the error output contains several key pieces of information. The header shows the file path, describe block, and test name that failed (the full path in the test tree). The assertion message indicates what kind of check failed and shows the two values being compared. The diff shows exactly what's different, with lines starting with + showing the actual value and lines starting with - showing the expected value. The code snippet shows the exact line with surrounding context and a caret (^) pointing to the failing assertion.

Running only a single test to isolate failures

To isolate a failing test, run only that test file or use a name pattern. Run with `vitest src/user.test.js` to test only that file, or use `vitest -t "test name"` to run tests matching a pattern. Combine both with `vitest src/user.test.js -t "test name"` for maximum precision. You can also add `.only` to the test itself to run only that test in the file, or use `vitest --bail 1` to stop after the first failure when dealing with many failures.

Shared state between tests problem

A common cause of test failures is shared state between tests. When a test passes when run alone but fails when run with others, it usually means some other test modified shared state (a global variable, module-level cache, or database) without cleaning up. The fix is to reset state before each test using `beforeEach` hook, or better yet, use `test.extend()` to create fresh state for each test automatically.

Using test.extend to create fresh test context

Use `test.extend()` to automatically create fresh state for each test. For example, `const test = baseTest.extend('users', () => [])` creates a fresh array for each test. Each test then receives this state as a parameter, like `test('adds a user', ({ users }) => { ... })`.

Async test failures from missing await

The most common async test mistake is forgetting to await assertions. If you see an unawaited assertion warning at the end of a test, add the missing `await`. For example, `await expect(fetchUser(1)).resolves.toMatchObject({ name: 'Alice' })`. Without await, the test finishes before the promise settles and may pass even when it should fail. If a test hangs and times out, it usually means a promise never resolves.

Give your agent this brain