Testing Vue components in an isolated way using Storybook

Our use case

We develop a Vue application for one of the pages of a Laravel project that runs locally on a vagrant box (Laravel/Homestead). This Vue app will likely grow and we  incorporated Vuex for state management. We would like to develop these components once and be able to test them in isolation and use them in the Laravel app without having duplicate code (components). This may be achieved by using a webpack-devserver. With Storybook (recently released for Vue) we can even improve our workflow as I will show at the end of this post.

By testing I am not talking about unit testing. I am rather testing how the components look and feel based on their state. Since we foresee a large number of components with all kinds of states this is important because we need to know we don’t break things when adding more and more functionality. Of course we need unit tests as well but these are not considered in this post.

Setup webpack-devserver

I assume you have a fresh install of Laravel  with the frontend assets installed using

npm install

Laravel ships with the laravel-mix package that loads all modules required to run a webpack-devserver. We will create a new webpack config file and add a run script to make it work. Follow these three steps:

  1. Add a webpack.config.js file to the root of the project. This file will be used by the script in (1) by default. A good candidate for this is the webpack config from the vue-cli webpack-simple project.
  2. Add a line to the ‘scripts’ part of package.json:
    “devser”: “cross-env NODE_ENV=development webpack-dev-server”,
  3. Create your main.js which is the entry point for webpack. If you put this file alongside the rest of your js code in /resources/assets/js, make sure to change the entry file in webpack.config.js as well, otherwise the compiler will not be able to find the entry file.

Now try running

npm run devser

which will compile  main.js and will output on http://localhost:8080. Note that you get hot module reloading (HMR) for free, try it out by changing a component that is imported in main.js.

So with this setup we can develop our components once and use them directly in the Laravel app. We can import them in main.js and run a local webpack devserver to test the components without the whole Laravel installation around it. If you are using requests to the server, for example to pull some data from the database or update data in the database. This will not work out of the box with this set up.

Start using Storybook

Storybook was originally created for React to quickly work on components in isolation. Recently, a Vue version was released. Before you continue, install storybook for vue globally by running (I have done this on my local machine, not on the vagrant box, I am not sure if it will work if you install it on vagrant alone).

npm i -g @storybook/cli

Now we can use the command getstorybook, to quickly add all stuff we need to get us going with storybook. If an error pops up, you probably need to use the ‘slow start guide’. Otherwise, it is time to run a newly added script (check your package.json scripts block):

npm run storybook

This runs on http://localhost:6006 and is also equipped with HMR. Some example stories are already added in the stories folder. This folder is placed in the root. We would like to have it closer to our components and moved it to the resources/assets/js folder. If you do so, make sure to change the location in .storybook/config.js which you can find in the root as well.

Global stylesheets for Storybook

My components had no styling because I was using a global stylesheet in my Laravel app that is not being used in Storybook out of the box. To get the styling I applied in Storybook, I should either load the css inside the component or find a way for Storybook to load these global stylesheets (e.g., bootstrap) for me. I am not sure what solution is best, but  the latter seems to be quite easy by adding a preview-head.html file in the .storybook/config. In this file, you can put external stylesheets, fonts etc. My preview-head.html looks like this:

<link href=”https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css” rel=”stylesheet”/>

Conclusion

And there you have it, a way to test your components build for a Laravel app in isolation. The webpack devserver is definitely the easiest way because all dependencies are already installed by laravel-mix and we only have to create a config file and add a run script. However, inviting Storybook to the party gives you more options and more fine grained control on your tests!


Mijn Twitter profiel Mijn Facebook profiel
Pim Hooghiemstra Webdeveloper and founder of PLint-sites. Loves to build complex webapplications using Vue and Laravel! Latest post
Build a progressive web app using Vue CLI 3

Leave a Reply

Your email address will not be published. Required fields are marked *