Back to Vuetify

Unit Testing

packages/docs/src/pages/en/getting-started/unit-testing.md

4.0.64.5 KB
Original Source

Unit Testing

Add regression protection by adding unit tests to your Vuetify application

<PageFeatures /> <PromotedEntry />

Usage

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.

Using Vite

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:

js
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
    server: {
      deps: {
        inline: ['vuetify'],
      },
    },
  },
})

Setup Vitest

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

bash
pnpm add @vue/test-utils vitest resize-observer-polyfill --save-dev
bash
yarn add @vue/test-utils vitest resize-observer-polyfill --dev
bash
npm install @vue/test-utils vitest resize-observer-polyfill --save-dev
bash
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:

js
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')
})

Testing Vuetify Components

When testing Vuetify components, we recommend running tests in a real browser environment instead of jsdom.

Rendering with Vuetify

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.

ts
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)
}

Using data-testid

For reliable queries in tests, use data-testid attributes in your components:

html
<v-btn data-testid="submit-btn">Submit</v-btn>
ts
const { getByTestId } = render(MyComponent)
expect(getByTestId('submit-btn')).toBeInTheDocument()

Accessibility Considerations

Tests should respect user accessibility preferences. Configure prefers-reduced-motion when testing animations to avoid flakiness and ensure accessibility compliance.