Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Front-End Development Projects with Vue.js

You're reading from  Front-End Development Projects with Vue.js

Product type Book
Published in Nov 2020
Publisher Packt
ISBN-13 9781838984823
Pages 774 pages
Edition 1st Edition
Languages
Authors (5):
Raymond Camden Raymond Camden
Profile icon Raymond Camden
Hugo Di Francesco Hugo Di Francesco
Profile icon Hugo Di Francesco
Clifford Gurney Clifford Gurney
Profile icon Clifford Gurney
Philip Kirkbride Philip Kirkbride
Profile icon Philip Kirkbride
Maya Shavin Maya Shavin
Profile icon Maya Shavin
View More author details

Table of Contents (16) Chapters

Preface
1. Starting Your First Vue Project 2. Working with Data 3. Vue CLI 4. Nesting Components (Modularity) 5. Global Component Composition 6. Routing 7. Animations and Transitions 8. The State of Vue.js State Management 9. Working with Vuex – State, Getters, Actions, and Mutations 10. Working with Vuex – Fetching Remote Data 11. Working with Vuex – Organizing Larger Stores 12. Unit Testing 13. End-to-End Testing 14. Deploying Your Code to the Web Appendix

12. Unit Testing

Overview

In this chapter, we will look at approaches to unit testing Vue.js applications in order to improve our quality and speed of delivery. We will also look at using tests to drive development using Test-Driven Development (TDD).

As we proceed, you will gain an understanding of why code needs to be tested and what kinds of testing can be employed on different parts of a Vue.js application. You will see how to unit test isolated components and their methods using shallow rendering and vue-test-utils, and you will learn how to test asynchronous component code. Throughout the course of the chapter, you will gain familiarity with techniques to write efficient unit tests for mixins and filters. Toward the end of the chapter, you will become familiar with approaches to testing a Vue.js applications that includes routing and Vuex, and you will learn about using snapshot tests to validate your user interface.

Introduction

In this chapter, we will look at the purpose and approaches to testing Vue.js applications effectively.

In previous chapters, we saw how to build reasonably complex Vue.js applications. This chapter is about testing them to maintain code quality and prevent defects.

Unit testing will allow us to write fast and specific tests that we can develop against and ensure that features don't exhibit unwanted behavior. We'll see how to write unit tests for different parts of a Vue.js application, such as components, mixins, filters, and routing. We will use tools supported by the Vue.js core team, such as vue-test-utils, and tools supported by the rest of the open source community, such as the Vue Testing library and the Jest testing framework. These different tools will serve to illustrate different philosophies and approaches to unit testing.

Why We Need to Test Code

Testing is crucial for ensuring that the code does what it's meant to do.

Quality production software is empirically correct. That means that for the enumerated cases that developers and testers have found, the application behaves as expected.

This lies in contrast with software that has proven to be correct, which is a very time-consuming endeavor and is usually part of academic research projects. We are still at the point where correct software (proven) is still being built to show what kinds of systems are possible to build with this constraint of correctness.

Testing prevents the introduction of defects such as bugs and regressions (that is, when a feature stops working as expected). In the next section, we will learn about the various types of testing.

Understanding Different Types of Testing

The testing spectrum spans from end-to-end testing (by manipulating the user interface) to integration tests, and finally to unit tests. End-to-end tests test everything, including the user interface, the underlying HTTP services, and even database interactions; nothing is mocked. For example, if you've got an e-commerce application, an end-to-end test might actually place a real order with a real credit card, or it might place a test order, with a test credit card.

End-to-end tests are costly to run and maintain. They require the use of full-blown browsers controlled through programmatic drivers such as Selenium, WebdriverIO, or Cypress. This type of test platform is costly to run, and small changes in the application code can cause end-to-end tests to start failing.

Integration or system-level tests ensure that a set of systems is working as expected. This will usually involve deciding on a limit as to where the system under test...

Your First Test

To illustrate how quick and easy it is to get started with automated unit tests in a Vue CLI project, we will start by setting up and writing a unit test with Jest, @vue-test-utils. There is an official Vue CLI package that can be used to generate a setup that includes unit testing with Jest and vue-test-utils. The following command should be run in a project that has been set up with Vue CLI:

vue add @vue/unit-jest

Vue CLI adds Jest as the test runner, @vue/test-utils, the official Vue.js testing utilities, and vue-jest, a processor for .vue single-file component files in Jest. It adds a test:unit script.

By default, it creates a tests/unit folder, which we'll remove. Instead, we can create a __tests__ folder and create an App.test.js file as follows.

We will use shallowMount to render the application and test that it displays the correct text. For the purposes of this example, we'll use the text: "The Vue.js Workshop Blog".

shallowMount...

Testing Components

Components are at the core of Vue.js applications. Writing unit tests for them is straightforward with vue-test-utils and Jest. Having tests that exercise the majority of your components gives you confidence that they behave as designed. Ideal unit tests for components run quickly and are simple.

We'll carry on building the blog application example. We have now built the heading, but a blog usually also needs a list of posts to display.

We'll create a PostList component. For now, it will just render a div wrapper and support a posts Array prop:

<template>
  <div class="flex flex-col w-full">
  </div>
</template>
<script>
export default {
  props: {
    posts: {
      type: Array,
      default: () => []
    }
  }
}
</script>

We can add some data in the App...

Testing Methods, Filters and Mixins

Since filters and mixins generate their output based solely on function parameters, they are straightforward to unit test. It is not recommended to test methods unless it's strictly necessary since the user doesn't call methods on the component directly. The users see the rendered UI, and their interactions with the application are manifested as events (for example, click, input change, focus change, and scroll).

For example, a filter that truncates its input to eight characters would be implemented as follows:

<script>
export default {
  filters: {
    truncate(value) {
      return value && value.slice(0, 8)
    }
  }
}
</script>

There are two options to test it. We could test it directly by importing the component and calling truncate on some input, as per the truncate.test.js file:

import PostListItem from ...

Testing Vue Routing

We have currently got an application that renders what is our blog home page or feed view.

Next, we should have post pages. To do this, we will use Vue Router, as covered in previous chapters, and ensure that our routing works as designed with unit tests.

Vue Router is installed using npm, specifically, npm install vue-router, and wiring it up in the main.js file:

// other imports
import router from './router'
// other imports and configuration 
new Vue({
  render: h => h(App),
  router,
}).$mount(‹#app›)

The router.js file registers vue-router with Vue using Vue.use and instantiates a VueRouter instance:

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
export default new VueRouter({})

A router with no routes isn't very useful. We'll define the root path (/) to display the PostList component in the router.js file, as follows:

// other imports...

Testing Vuex

To show how to test a component that relies on Vuex (Vue.js's official global state management solution), we'll implement and test a newsletter subscription banner.

To start with, we should create the banner template. The banner will contain a Subscribe to the newsletter call to action and a close icon:

<template>
  <div class="text-center py-4 md:px-4">
    <div
      class="py-2 px-4 bg-indigo-800 items-center text-indigo-100
      leading-none md:rounded-full flex md:inline-flex"
      role="alert"
    >
      <span
        class="font-semibold ml-2 md:mr-2 text-left flex-auto"
      >
        Subscribe to the newsletter...

Snapshot Testing

Snapshot tests provide a way to write tests for fast-changing pieces of code without keeping the assertion data inline with the test. They store snapshots instead.

Changes to a snapshot reflect changes to the output, which is quite useful for code reviews.

For example, we can add a snapshot test to the PostList.test.js file:

// imports and tests
test('Post List renders correctly', () => {
  const wrapper = mount(PostList, {
    propsData: {
      posts: [
        {
          title: 'Title 1',
          description: 'Description 1',
          tags: ['react', 'vue']
        },
       ...

Summary

Throughout this chapter, we've looked at different approaches to testing different types of Vue.js applications.

Testing in general is useful for empirically showing that the system is working. Unit tests are the cheapest to build and maintain and should be the base of testing functionality. System tests are the next level up in the testing pyramid and allow you to gain confidence that the majority of features are working as expected. End-to-end tests show that the main flows of the full system work.

We've seen how to unit test components, filters, component methods, and mixins, as well as testing through the layers, and testing component output in a black box fashion instead of inspecting component internals to test functionality. Using the Vue.js Testing library, we have tested advanced functionality, such as routing and applications, that leverage Vuex.

Finally, we looked at snapshot testing and saw how it can be an effective way to write tests for template...

lock icon The rest of the chapter is locked
You have been reading a chapter from
Front-End Development Projects with Vue.js
Published in: Nov 2020 Publisher: Packt ISBN-13: 9781838984823
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}