Vitest Browser Vue Component Testing
vitest-browser-vue is a library designed for rendering Vue 3 components within Vitest's browser testing environment, adhering to the principles of `@testing-library`. It facilitates writing integration tests by exposing Vitest `locators` and utilities that mimic how users interact with components in a real browser. The current stable version is 2.1.0, with releases occurring regularly, indicating active development and maintenance. A key differentiator from `@testing-library/vue` is its cleanup strategy: it cleans up the component *before* a test starts, rather than after, allowing developers to inspect the rendered UI during debugging. It integrates seamlessly with Vitest's `page.render` and `cleanup` methods and leverages `@vue/test-utils` under the hood for component mounting and interaction. Users must ensure compatibility with `vitest` version `4.0.0` or higher and `vue` version `3.0.0` or higher.
Warnings
- breaking Version 2.0.0 introduced breaking changes to support the new syntax of Vitest v4. Ensure your Vitest configuration and test files are updated to align with Vitest v4 API changes.
- gotcha When using snapshots with a container, a `data-testid` attribute is injected into the DOM. This can cause unexpected differences in snapshots unless Vitest is updated to version 4.0.18 or higher, which handles this injection gracefully.
- gotcha TypeScript types for the injected `page.render` and `cleanup` methods might not be picked up automatically. This can lead to TypeScript errors or missing IntelliSense.
- gotcha By default, `render` from `vitest-browser-vue` cleans up the component *before* each test, which differs from `@testing-library/vue`'s post-test cleanup. This behavior allows for UI inspection. If you require standard post-test cleanup or explicit control, you need to use a different import.
Install
-
npm install vitest-browser-vue -
yarn add vitest-browser-vue -
pnpm add vitest-browser-vue
Imports
- render
const { render } = require('vitest-browser-vue')import { render } from 'vitest-browser-vue' - render
import { render } from 'vitest-browser-vue/pure' - config
import { config } from 'vitest-browser-vue'
Quickstart
import { render } from 'vitest-browser-vue'
import { expect, test } from 'vitest'
// Example Vue component (assuming it's in Component.vue)
// <template><button @click="count++">Increment</button><p>Count is {{ count }}</p></template>
// <script setup> import { ref } from 'vue'; const props = defineProps({ initialCount: Number }); const count = ref(props.initialCount || 0); </script>
const Component = {
template: '<button @click="count++">Increment</button><p>Count is {{ count }}</p>',
props: ['initialCount'],
setup(props) {
const count = ref(props.initialCount || 0);
return { count };
}
}
test('counter button increments the count', async () => {
const screen = await render(Component, {
props: {
initialCount: 1
}
})
await screen.getByRole('button', { name: 'Increment' }).click()
await expect.element(screen.getByText('Count is 2')).toBeVisible()
})