packages/docs/src/pages/en/getting-started/unit-testing.md
Add regression protection by adding unit tests to your Vuetify application
<PageFeatures /> <PromotedEntry />Unit tests are an important (and sometimes ignored) part of developing applications. They help us secure our processes and workflows, ensuring that the most critical parts of our projects are protected from accidental mistakes or oversights in our development.
Because of this, Vue has its own testing utility called vue-test-utils. It provides useful features for interacting with Vue components and works with many popular test runners.
Vite is a fast, opinionated frontend build tool that serves your code via native ES Module imports during dev and bundles it with Rollup for production. It provides a great developer experience and is the recommended build tool for Vuetify applications.
First, update your vite.config.js file to inline the vuetify dependency:
import { defineConfig } from 'vite'
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
server: {
deps: {
inline: ['vuetify'],
},
},
},
})
Vitest is a popular test runner that provides a great developer experience. It is fast, easy to use, and provides useful features like snapshot testing. To get started, install the following dependencies:
::: tabs
pnpm add @vue/test-utils vitest resize-observer-polyfill --save-dev
yarn add @vue/test-utils vitest resize-observer-polyfill --dev
npm install @vue/test-utils vitest resize-observer-polyfill --save-dev
bun add @vue/test-utils vitest resize-observer-polyfill --dev
:::
Once installed, create a new folder at the root of your application named tests/spec and add a new file named HelloWorld.spec.js. The following example shows how to setup a basic unit test for a Vuetify component:
import { mount } from '@vue/test-utils'
import { expect, test } from 'vitest'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import HelloWorld from '../../src/components/HelloWorld.vue'
const vuetify = createVuetify({
components,
directives,
})
global.ResizeObserver = require('resize-observer-polyfill')
test('displays message', () => {
const wrapper = mount({
template: '<v-layout><hello-world></hello-world></v-layout>'
}, {
props: {},
global: {
components: {
HelloWorld,
},
plugins: [vuetify],
}
})
// Assert the rendered text of the component
expect(wrapper.text()).toContain('Components')
})
When testing Vuetify components, we recommend running tests in a real browser environment instead of jsdom.
To properly render Vuetify components in tests, create a Vuetify instance and pass it to the test renderer. You don’t need to mock transitions or other internals.
export function render<C> (
component: C,
options?: RenderOptions<C> | null,
vuetifyOptions?: VuetifyOptions
): RenderResult {
const vuetify = createVuetify(mergeDeep({ icons: { aliases } }, vuetifyOptions))
const defaultOptions = {
global: {
stubs: {
transition: false,
'transition-group': false,
},
plugins: [vuetify],
},
}
const mountOptions = mergeDeep(defaultOptions, options!, (a, b) => a.concat(b))
return _render(component, mountOptions)
}
data-testidFor reliable queries in tests, use data-testid attributes in your components:
<v-btn data-testid="submit-btn">Submit</v-btn>
const { getByTestId } = render(MyComponent)
expect(getByTestId('submit-btn')).toBeInTheDocument()
Tests should respect user accessibility preferences. Configure prefers-reduced-motion when testing animations to avoid flakiness and ensure accessibility compliance.