Reader small image

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

Product typeBook
Published inNov 2020
Reading LevelIntermediate
PublisherPackt
ISBN-139781838984823
Edition1st Edition
Languages
Tools
Right arrow
Authors (5):
Raymond Camden
Raymond Camden
author image
Raymond Camden

Raymond Camden is a developer advocate for IBM. His work focuses on the MobileFirst platform, Bluemix, hybrid mobile development, Node.js, HTML5, and web standards in general. He is a published author and presents at conferences and user groups on a variety of topics. Raymond can be reached at his blog, on Twitter, or via email. He is the author of many development books, including Apache Cordova in Action and Client-Side Data Storage.
Read more about Raymond Camden

Hugo Di Francesco
Hugo Di Francesco
author image
Hugo Di Francesco

Hugo Di Francesco is a software engineer who has worked extensively with JavaScript. He holds a MEng degree in mathematical computation from University College London (UCL). He has used JavaScript across the stack to create scalable and performant platforms at companies such as Canon and Elsevier and in industries such as print on demand and mindfulness. He is currently tackling problems in the travel industry at Eurostar with Node.js, TypeScript, React, and Kubernetes while running the eponymous Code with Hugo website. Outside of work, he is an international fencer, in the pursuit of which he trains and competes across the globe.
Read more about Hugo Di Francesco

Clifford Gurney
Clifford Gurney
author image
Clifford Gurney

Clifford Gurney is a solution-focused and results-oriented technical lead at a series-A funded startup. A background in communication design and broad exposure to leading digital transformation initiatives enriches his delivery of conceptually designed front-end solutions using Vue JS. Cliff has presented at the Vue JS Melbourne meetups and collaborates with other like-minded individuals to deliver best in class digital experience platforms.
Read more about Clifford Gurney

Philip Kirkbride
Philip Kirkbride
author image
Philip Kirkbride

Philip Kirkbride has over 5 years of experience with JavaScript and is based in Montreal. He graduated from a technical college in 2011 and since then he has been working with web technologies in various roles.
Read more about Philip Kirkbride

Maya Shavin
Maya Shavin
author image
Maya Shavin

Maya is Senior Software Engineer in Microsoft, working extensively with JavaScript and frontend frameworks and based in Israel. She holds a B.Sc in Computer Sciences, B.A in Business Management, and an International MBA from University of Bar-Ilan, Israel. She has worked with JavaScript and latest frontend frameworks such as React, Vue.js, etc to create scalable and performant front-end solutions at companies such as Cooladata and Cloudinary, and currently Microsoft. She founded and is currently the organizer of the VueJS Israel Meetup Community, helping to create a strong playground for Vue.js lovers and like-minded developers. Maya is also a published author, international speaker and an open-source library maintainer of frontend and web projects.
Read more about Maya Shavin

View More author details
Right arrow

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 2020Publisher: PacktISBN-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.
undefined
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

Authors (5)

author image
Raymond Camden

Raymond Camden is a developer advocate for IBM. His work focuses on the MobileFirst platform, Bluemix, hybrid mobile development, Node.js, HTML5, and web standards in general. He is a published author and presents at conferences and user groups on a variety of topics. Raymond can be reached at his blog, on Twitter, or via email. He is the author of many development books, including Apache Cordova in Action and Client-Side Data Storage.
Read more about Raymond Camden

author image
Hugo Di Francesco

Hugo Di Francesco is a software engineer who has worked extensively with JavaScript. He holds a MEng degree in mathematical computation from University College London (UCL). He has used JavaScript across the stack to create scalable and performant platforms at companies such as Canon and Elsevier and in industries such as print on demand and mindfulness. He is currently tackling problems in the travel industry at Eurostar with Node.js, TypeScript, React, and Kubernetes while running the eponymous Code with Hugo website. Outside of work, he is an international fencer, in the pursuit of which he trains and competes across the globe.
Read more about Hugo Di Francesco

author image
Clifford Gurney

Clifford Gurney is a solution-focused and results-oriented technical lead at a series-A funded startup. A background in communication design and broad exposure to leading digital transformation initiatives enriches his delivery of conceptually designed front-end solutions using Vue JS. Cliff has presented at the Vue JS Melbourne meetups and collaborates with other like-minded individuals to deliver best in class digital experience platforms.
Read more about Clifford Gurney

author image
Philip Kirkbride

Philip Kirkbride has over 5 years of experience with JavaScript and is based in Montreal. He graduated from a technical college in 2011 and since then he has been working with web technologies in various roles.
Read more about Philip Kirkbride

author image
Maya Shavin

Maya is Senior Software Engineer in Microsoft, working extensively with JavaScript and frontend frameworks and based in Israel. She holds a B.Sc in Computer Sciences, B.A in Business Management, and an International MBA from University of Bar-Ilan, Israel. She has worked with JavaScript and latest frontend frameworks such as React, Vue.js, etc to create scalable and performant front-end solutions at companies such as Cooladata and Cloudinary, and currently Microsoft. She founded and is currently the organizer of the VueJS Israel Meetup Community, helping to create a strong playground for Vue.js lovers and like-minded developers. Maya is also a published author, international speaker and an open-source library maintainer of frontend and web projects.
Read more about Maya Shavin