Turn your manual testers into automation experts Request a DemoStart testRigor Free

Vue.js Testing

Vue.js Testing

What is Vue.js

Vue is an open-source JavaScript framework for building single-page web applications and user interfaces. Evan-You, an Angular.js developer at Google, created Vue, and the first stable version hit the market in 2014. Vue is based on Model-View-Viewmodel(MVVM) architecture. From a broader perspective, MVVM is an architectural pattern where the development of the User Interface(view) can be separated from the business logic or backend logic(model). So developers can build UI and backend in a fully independent platform.

Vue is a progressive framework, and the ecosystem is designed to be flexible and incrementally adaptable. Vue provides a declarative and component-based model for developing user interfaces efficiently. Vue is extensively used for creating single-page applications, embedding web components to any page, server-side rendering, status site generation, etc.

For Vue, testing is generally broken down into

Unit testing

Unit testing is referred to as the first pillar in the testing cycle. It's a way of testing the smallest piece of code called a unit that can be logically isolated. Usually done from the developer side, its primary intention is to identify and fix the issues at the earliest stage. Since components are the building blocks of Vue, unit testing is performed on the component level.

Here're the two most popular tools for Vue.js unit testing:
  • Vitest
  • Peeky

A sample project in Vue can be created using the command "create-vue", which forms the pre-configured base with the features we choose and delegates the rest to Vite. Vite is the front-end build tool used in Vue.

Vitest

Vitest is a Jest-compatible unit test framework with faster test execution. Vitest can use the same configurations Vite used and share a standard transformation pipeline during development, build, and test time. Vite is created and maintained by Vue team members. Vitest provides the generic functionality to write unit tests, and Vue Test Utils provides the necessary test utilities.

The Vitest unit test file should have the same name as the component under test, like "<componentName>.spec.js". There should be one unit test file for one component, and this file should be under the sub-folder within the component. A sample Vitest unit test looks like this:
import { describe, it, expect } from 'vitest'
  import { shallowMount } from '@vue/test-utils'
  import WeatherHeader from '../WeatherHeader.vue'

  describe('WeatherHeader.vue Test', () => {
    it('renders message when component is created', () => {
      // render the component
      const wrapper = shallowMount(WeatherHeader, {
        propsData: {
          title: 'Vue Project'
        }
      })

      // check that the title is rendered
      expect(wrapper.text()).toMatch('Vue Project')
    })
  })

Peeky

Peeky is a fast unit test runner that has integration support with Vite. Peeky offers a visual user interface. Peeky uses Vite and integrates with the project without any additional configuration. Also, Peeky supports parallel execution.

A sample Peeky test looks like this:
import { describe, test, expect } from '@peeky/test'
  import Hello from './Hello.vue'
  describe('vue + peeky demo', () => {
    test('mount component', async () => {
      console.log(Hello)
      const wrapper = mount(Hello, {
        props: {
          count: 4,
        },
      })
      expect(wrapper.text()).toContain('4 x 2 = 8')
      expect(wrapper.html()).toMatchSnapshot()
      await wrapper.get('button').trigger('click')
      expect(wrapper.text()).toContain('4 x 3 = 12')
      await wrapper.get('button').trigger('click')
      expect(wrapper.text()).toContain('4 x 4 = 16')
    })
  })

Component testing

Component integration testing, or component testing, checks how the components behave as a combined entity. Component testing aims to capture issues related to the component's props, events, and slots. In component testing, the interactions with child components are not mocked. Here we are testing what the component does, not how it does it.

Tools used for component testing are:
  • Vitest for components
  • Cypress component testing

Vitest for components

One of the key features of Vitest is its ability to mount Vue.js components and test their output and behavior. Here, we are running our tests rendered headlessly. The components are tested using the library - @testing-library/vue.

Here is a sample script:
import {render, fireEvent} from '@testing-library/vue'
  import Component from './Component.vue'

  test('properly handles v-model', async () => {
    const {getByLabelText, getByText} = render(Component)
    // Asserts initial state.
    getByText('Hi, my name is Alice')
    // Get the input DOM node by querying the associated label.
    const usernameInput = getByLabelText(/username/i)
    // Updates the <input> value and triggers an 'input' event.
    // fireEvent.input() would make the test fail.
    await fireEvent.update(usernameInput, 'Bob')
    getByText('Hi, my name is Bob')
  })

Cypress for component testing

Cypress testing provides a testable component workbench. With the support of a workbench, users can quickly build and test any component. The test executions are running on actual browsers. Using Cypress, we can understand how the rendering of components happens, and any issue related to rendering can be captured in competent testing.

Sample Cypress component test script is below:
// Set up some constants for the selectors
  const counterSelector = '[data-cy=counter]'
  const incrementSelector = '[aria-label=increment]'
  const decrementSelector = '[aria-label=decrement]'
  it('stepper should default to 0', () => {
    cy.mount(Stepper)
    cy.get(counterSelector).should('have.text', '0')
  })
  it('supports an "initial" prop to set the value', () => {
    cy.mount(Stepper, { props: { initial: 100 } })
    cy.get(counterSelector).should('have.text', '100')
  })

We can capture style issues, cookies, etc. Since Cypress is integrated with Vite, test execution is swift. @testing-library/cypress library is used for Cypress component testing.

End-to-end testing

End to End testing involves testing the application user flow from beginning to end. The actual user scenarios are replicated and validated for integration and data integrity. E2E testing often catches issues with top-level components, request handling, and network configurations. For E2E testing, we don't have to import any application code, but the scenario will run on the browser. Tools mainly used for E2E testing include:

Cypress

Cypress, as discussed above, provides support for component testing and E2E testing. It has got built-in assertions and can execute test cases in parallel. Cypress has an excellent graphical interface report for viewing the test execution result. A disadvantage of Cypress is that the support is limited to Chromium-based browsers, WebKit (currently very limited and experimental), and Firefox. So it's not a great choice for Safari or Edge browsers. You can read more about Cypress here.

Playwright

Playwright is an open-source Node.js library for automating web browsers, including Chrome, Firefox, and Safari. It provides a high-level API for interacting with web pages and applications, and supports various testing frameworks such as Jest, Mocha, and Jasmine.

Playwright can be used to automate end-to-end testing scenarios, where the entire application is tested from the user's perspective. This can include testing the functionality of Vue.js components, routing, state management, and interactions with external APIs.

A sample Playwright test script is shown below:
const { chromium } = require('playwright');
  const { expect } = require('chai');
  const baseUrl = 'http://localhost:8080/';
  const adminPassword = 'ADMIN_PASSWORD';
  const adminUserName = 'Admin username';
  const normalUserName = 'User username';
  const normalUserPassword = 'USER_PASSWORD';
  describe('Authenticated Vue App: ', () => {
    let browser;
    let page;  
    before(async () => {
      browser = await chromium.launch();
      page = await browser.newPage();
      await page.goto(baseUrl);
    });
    after(async () => {
      await page.close();
      await browser.close();
    });
    it('Clicking on login should redirect to login', async () => {
      await page.click('a.login');
      expect(page.url()).to.equal('${baseUrl}login');
    });
  });

Nightwatch

Nightwatch is a Node.js-based end-to-end testing framework that uses the Selenium WebDriver API to automate browser interactions. It provides a simple and intuitive syntax for writing tests, and supports a wide range of browsers, including Chrome, Firefox, and Safari.

In terms of testing Vue.js applications, Nightwatch can be used to automate end-to-end testing scenarios, where the entire application is tested from the user's perspective. This can include testing the functionality of Vue.js components, routing, state management, and interactions with external APIs. It's integrated with Allure reports for reporting; and also has integrations with Azure and Jenkins.

testRigor

testRigor is a no-code AI-integrated automation tool that allows the entire team to create cross-browser and cross-platform end-to-end scenarios in plain English. It is the easiest and fastest way to cover your entire application with functional end-to-end tests, and spend less time on maintenance than with most other similar tools.

Here's why testRigor stands out when it comes to Vue.js end-to-end testing:
  • QA team (including manual testers) can comfortably own the entire process from an initial setup, to writing test cases, to maintenance.
  • It's a one-stop solution for mobile, web, desktop, and API testing, including the additional capability of visual testing when needed.
  • Supported integrations with market-leading CI/CD tools, test management, and issue management tools (Jira, Azure, TestRail, etc).
  • Tests are so stable that some companies even use them for monitoring; you can run them as often as needed and get results in under an hour.
Here's what a sample testRigor script looks like:
click "Sign Up"
  enter email into "Email"
  enter password into "Password"
  enter password into "Confirm Password"
  enter homeName into "Billing Address"  
  enter phoneNum as "Phone Number"
  click "Submit"

Some BDD tools allow you to write a similar test in an English-like language, which will later be transferred into code. With testRigor, however, the above test is all you need. Notice also that it doesn't mention any element locators, such as XPaths. This is because testRigor tests emulate how a real user would interact with your application, and are abstract from implementation details.