Diese Seite ist auch auf Deutsch verfügbar. Zur deutschen Seite wechseln

Writing unit tests with Jest

Writing unit tests with Jest

It's important to always write a unit test for any function change. It guarantees that your written code works and that a third party developer does not destroy the functionality with his code in the future. Having good test coverage means we can be confident that we can deploy stable software without requiring additional manual testing. We use Jest as our test framework. It is a solid foundation and is used by many developers. This small tutorial will show you how to write those unit tests for the administration in Shopware 6, on the component test level.

Prerequisites

This tutorial will have a strong focus on how unit tests should be written when it comes to components in the administration. So please make sure that you already know what a unit test is and why we are doing it. Furthermore, you should know what components tests are and what we want to achieve with them.

In addition, you need a running Shopware 6 installation. Your repository used for that should be based on a development template, as we need to use some of the scripts provided by it.

Frameworks we use for frontend unit testing

At shopware, we use Jest to unit test our Javascript code. It is a JavaScript Testing Framework with a focus on simplicity. It works well with a lot of Javascript frameworks, including VueJS.

For making component testing possible, we need to use a second framework: We are using Vue Test Utils in our Administration. Vue Test Utils is the official unit testing utility library for Vue.js, tailored specifically for Vue components.

Getting to know the component to test

First things first: All information about Shopware's Administration components can be found in our component library. The Shopware Administration is built with reusable components that you can use to build your own module. Our component library contains all components we provide in our Administration to try out or just look up all information to work with them

Now, let's look at the component we want to test: It's called sw-alert. The sw-alert component is used to convey important information to the user. It comes in 4 variations, success, info, warning, and error. These variations have default icons assigned which can be changed and represent different actions. Via the default slot, you can provide the message you want.

Writing our component test

Enough theory, let's start writing our first test. As the first step, we want to test if our wrapper and thus our component is a Vue instance.

Folder structure

The test folder structure should match the source folder structure. Therefore, I navigate to the folder where the sw-alert component is located, keep the path in mind and afterward create the folder the way I need to create my `sw-alert` test.

You see: When creating the file, the name should also be the same as the component has with an additional .spec before the ending .js. The .spec suffix is a well-known naming convention of frontend testing files.

Basic test: Rendering of component

Let's fill our test file with life. At first, we need to import the things we need. Typically, we need a wrapper to depict our alert:

Remember, a Wrapper is an object that contains a mounted component or vnode and methods to test. Of course, we need to import our component itself as well. Our test file should look like this:

Let's continue with the test structure itself. We'll use the Mocha syntax you might already know if you wrote frontend tests before. First things first, we need to begin with the describe function. It can be seen as a frame for structuring our tests and is important for the usage of lifecycle hooks. Afterward, we will use the it function representing the test itself.

In our test, we can use the wrapper now to use our component to test. So let's mount our alert component in order to have a wrapper to work with.

Next, we are ready to start writing assertions. A test assertion is a statement that describes the logic of the system under test. So we're checking our component with the use of this assertion. In our test, it looks like this:

Ok, we completed our test now, at least in theory. Let's see how it turns out when running it.

Running tests in CLI

Before you are using the commands for running tests please make sure that you installed all dependencies for your Administration.

In order to run jest unit tests of the administration, you can use psh commands provided by our development template. Beware: This only applies to the Administration! If you use unit tests in Plugin, you might need to write your own scripts for that.

If you wish to run all unit tests and generate complete code coverage, please use ./psh.phar administration:unit

Of course, You can use a command which executes only unit tests on changed files. It automatically restarts if a file gets saved. This should be used during the development of unit tests: ./psh.phar administration:unit-watch

Shopware-sided differences

When running our sw-alert test this way, we see our test threw a warning. Let's take a look.

test-fails-componentTnbPMKCfmYPxv

In the context of Shopware's administration, it's not enough for us to just write the test as usual. We need to consider some important differences. We can't test components that easily like in other Vue projects because we are supporting template inheritance and extendability for third party developers. This causes overhead which we need to bear in mind.

We are using a global object as an interface for the whole administration. Every component gets registered to this object. Therefore we have access to our Component with the `Shopware.Component.build()`method. This creates a native Vue component with a working template. Every override or extension from another components is resolved in the built component.

Next, we need to check if our tests is passing now.

test-fails-icon

Yes, that made our test pass, but theres still a warning concerning an sw-icon component. This is component missing in our test which we need to stub. We need to use shallowMount now, as we need a Wrapper that contains the mounted and rendered Vue component, but with stubbed child components. It will look like this

Ok, let's run our test again and see if it passes:

test-passed

Right, is passing now, without warnings.

A test with more meaning: Testing slots

Yay, we wrote our first component test together, using Jest and Vue Test Utils. However, our tests doesn't do that much yet. Let's thing about a more meaningful test.

Actually, he task of an alert is displaying a message for the user in most cases. So lets write a test for this text located in a slot. Let's take the test from the first example: There we'll add another test case for testing the alert's message:

You can set the content of a slot during component mount.

Afterwards you can make an assertion that the text passed to the slot will be rendered inside the desired element. In this case we search in the wrapper for the element with the selector '.sw-alert__message' and check if the text is there.

Check out the video tutorial on youtube: 

Newsletter

Never miss out - get all the latest news sent straight to your inbox.