Home / Blog / Vue.js Testing with Vue Test Utils and Vitest
Vue.js Testing with Vue Test Utils and Vitest

Vue.js Testing with Vue Test Utils and Vitest

Daniel Kelly
Daniel Kelly
Updated: January 29th 2025

Vue Test Utils is the official test library for Vue.js components. It provides a set of utility functions that make it easier to test Vue components in isolation.

Why Unit Testing Matters in Vue

Unit testing is crucial for maintaining a reliable and robust Vue.js application. It helps developers:

  • Catch bugs early in the development cycle
  • Ensure components behave as expected without regressing
  • Refactor with confidence
  • Document component behavior

Getting Started with Vue Test Utils

Vue Test Utils provides a simple and intuitive API for mounting components, triggering events, and making assertions about the component's output. The library works seamlessly with popular testing frameworks like Jest and Vitest.

Key Features of Vue Test Utils

  • Component Mounting: Easily mount and isolate components for testing
  • DOM Interaction: Simulate user events and interactions
  • Props and Data Management: Test component behavior with different prop values

Simple Vue Test Utils + Vitest Example

In the following example, we’ve got a MessageComponent that takes a title prop and displays it as an h1 . It also binds some local message data to an input and emits and clears that data when a button is clicked.

<!--MessageComponent.vue-->
<script setup>
import { ref } from 'vue'

const props = defineProps({
    title: {
        type: String,
        default: 'Message Form'
    }
})

const emit = defineEmits(['message-sent'])
const message = ref('')

const submit = () => {
    emit('message-sent', message.value)
    message.value = ''
}
</script>

<template>
    <div>
        <h1>{{ title }}</h1>
        <input v-model="message" data-test="message-input" />
        <button @click="submit" data-test="send-button">Send</button>
    </div>
</template>

In order to test that component we can write the following test with Vitest and Vue Test Utils.

// MessageComponent.spec.ts

import { mount } from '@vue/test-utils'
import { describe, it, expect } from 'vitest'
import MessageComponent from '../MessageComponent.vue'

describe('MessageComponent', () => {

  // Test that the component correctly renders the title prop
  // This verifies props are properly passed and displayed
  it('renders props.title when passed', () => {
    const title = 'New Message'
    const wrapper = mount(MessageComponent, { props: { title } })
    expect(wrapper.find('h1').text()).toBe(title)
  })

  // Test the full message sending workflow:
  // 1. Enter text in input
  // 2. Click send button
  // 3. Verify event is emitted with correct data
  // 4. Verify input is cleared afterwards
  it('emits message-sent event when button clicked', async () => {
    // Mount the component
    const wrapper = mount(MessageComponent)

    // Find the input element using data-test attribute
    // More reliable than using element selectors
    const input = wrapper.find('[data-test="message-input"]')

    // Simulate user typing a message
    await input.setValue('Hello World')

    // Simulate clicking the send button
    await wrapper.find('[data-test="send-button"]').trigger('click')

    // Verify the correct event was emitted with the message
    expect(wrapper.emitted('message-sent')[0]).toEqual(['Hello World'])

    // Verify the input was cleared after sending
    expect(input.element.value).toBe('')
  })
})

Notice how we’re testing the interface of the component (what passing a certain prop does and the effect of events). It’s a good habit to focus on testing your component interface as opposed to it’s internal logic. This makes for less brittle tests.

Vue Testing Best Practices

This leads us to some other best practices to consider when writing tests for Vue.js components:

  • Remember to test component outputs rather than implementation details but also:
  • Keep tests focused and isolated
  • Use meaningful test descriptions
  • Follow the Arrange-Act-Assert pattern

By implementing a solid testing strategy with Vue Test Utils, you can ensure your Vue.js applications remain maintainable and reliable as they grow in complexity.

Conclusion and Further Learning

To dive deeper into Vue.js testing and Vue Test Utils, check out these valuable resources:

Good luck using tests to build your rock solid Vue apps!

Related Courses

Start learning Vue.js for free

Daniel Kelly
Daniel Kelly
Daniel is the lead instructor at Vue School and enjoys helping other developers reach their full potential. He has 10+ years of developer experience using technologies including Vue.js, Nuxt.js, and Laravel.

Comments

Latest Vue School Articles

Building Advanced WYSIWYG Editors with Vue and TinyMCE &#8211; A Complete Guide

Building Advanced WYSIWYG Editors with Vue and TinyMCE – A Complete Guide

Learn to integrate and customize TinyMCE in Vue with the course 'Rich Text Editing and Beyond with TinyMCE and Vue.' From basic WYSIWYG setups to advanced CMS and CRM solutions, this hands-on course equips you with the tools to build powerful content editing applications.
Daniel Kelly
Daniel Kelly
Exploring the Vue.js Ecosystem: Tools and Libraries That Make Development Fun

Exploring the Vue.js Ecosystem: Tools and Libraries That Make Development Fun

Explore the fun side of Vue.js development with our guide to its ecosystem. Discover UI libraries like Vuetify, Quasar, and tools enhancing your workflow like Pinia and Vue Router. Perfect for making coding efficient.
Eleftheria Batsou
Eleftheria Batsou

Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.

More than 200.000 users have already joined us. You are welcome too!

Follow us on Social

© All rights reserved. Made with ❤️ by BitterBrains, Inc.