Vue unit testing: Tests must fail
Tags: tutorial, vue, webdev, testing
Published: 2021-05-03 17:14:41

Kicking off from [A guide to better predictable code](https://thegreencodes.com/unit-testing-in-vue), we create our project boilerplate; assuming you have the vue-cli already installed. Right on, our `awesome-todo`

```bash
vue create awesome-todo 
```
We manually select our project setup. Using Vue-2, allowing the `router`, `vuex` as well as `unit testing` along with the defaults selected. We select `jest` when it comes to our unit testing solution as well and store the configuration in our package.json file. Are you ready? Good, let's get on to the next step.


For purposes of this guide, we'll use bootstrap; particularly, bootstrap-vue. Let's shorten those CSS classes.

```bash
npm install bootstrap-vue
```

In your `main.js` file, add the necessary configurations.

```javascript
import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue'

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Vue.use(BootstrapVue)
Vue.use(BootstrapVueIcons)
```

Spot on! 

On the home/ landing page of our application, we want a welcome message displayed. For our case; 

' *Welcome to TheGreenCodes awesome to-do list*.  '

First of all, though, we test. As I said, we think before we implement. We think of the feature we want to implement before actually implementing it. We then write tests for this feature, to avoid the addiction cheat trap where we say we'll write a test after then never actually get to it.

Create a file `home.spec.js` under the **unit** directory in the **tests** folder. 

Notice how we name the file. Our test runner will look for javascript files with the *spec* keyword, through the project, under this directory. Now copy the following code snippet below.


```javascript
import { shallowMount } from '@vue/test-utils'
import Home from '@/views/Home.vue'

// what componet are the tests referring to
describe('Home.vue', () => {

// what feature or spec are we targetting specifically
  it('Displays a welcome message', () => {
    const welcomeMessage = 'Welcome to TheGreenCodes awesome to-do list'
    const wrapper = shallowMount(Home)
    expect(wrapper.text()).toMatch(welcomeMessage)
  })
})

```

To run this as well as consecutive tests:

```bash
npm run test: unit 
```

Our test fails; rather horribly. Reading the shell, you see:

```bash
  expect(received).toMatch(expected)

    Expected substring: "Welcome to TheGreenCodes awesome to-do list"
    Received string:    ""

```

We gave it a variable with the message to expect in the component `Home`. What we know for certain, however, is that we haven't even touched that component.; hence the failure. Head over the Home component under views, remove the HelloWorld import and use and add an `h2` tag with our welcome message. Re-run this test and see the difference.


Before we get any further, we should explain what the elements in our Home test mean.

As we have made use of comments, we shall describe target areas:

```javascript
    const wrapper = shallowMount(Home)
```

We create a variable , `wrapper`, that holds our component. How we do this you ask? We import `shallowMount` from Vue test utils. Just like the default component life-cycle hooks, our component is initialized, only this time, since we specified we wanted a shallow mount, any child component within this parent component is not included. 

We then ask the question:
*'Hey! Is there any mention of our title from within this component?'* To which the suite complies with a yes or no depending on what we have. We expect this component to have text, not only text but that which matches our welcome message.

Behold! We have done the foundation building block of a test; tests must fail, tests must pass and the code must be refactored.

We break this statement down:

**Tests must fail**
Our feature has not been implemented yet, so why on earth would we expect a test to pass?

**Test must pass**

Hey Marv, I wrote down that cool little feature. What next? Simple; the test must pass. The test whose feature we just wrote should pass.

**Code must be refactored**

When the same piece of code is edited later, does the code still pass? Can this component or code be edited and still let the test pass gracefully? 

Do we get the 'It broke everything else!' exclamation?



![photo_2021-05-03_19-27-42.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1620059314543/5E07Q_U-P.jpeg)



> Tests must fail, tests must pass and the code must be refactored.

We could go further with this test and specify what element we wanted to have the title:

```javascript

    const titleFound = wrapper.find('h2')
    expect(titleFound.text()).toMatch(welcomeMessage)
```

You get the same result. Ignore the warning for UI element registration, incase you are already using it within your code, for now, we'll fix this in a while.

Let's not just make our application, but let's make a great UI. Adjust your code to look as below:

*Home component*
```javascript
<template>
  <div class="home">
    <h2>Welcome to TheGreenCodes awesome to-do list</h2>
    <div class="container">
      <b-card class="list-container">

      </b-card>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Home',
  components: {
  }
</script>

<style scoped>
.list-container{
    max-width: 170%;
}
</style>

```

Refactor the routes: (This would mean another component under views with the name `Completed`)
```javascript

 {
    path: '/completed',
    name: 'Completed',
    component: () => import(/* webpackChunkName: "about" */ '../views/Completed.vue')
  }
```

Our application entry component would also have a link to the completed. section, either as a replacement to the about page or an add-on


```javascript
<router-link to="/completed">Completed</router-link>
```
In the end, we should have something similar to this:


![awesome-todo-llanding.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1620058332923/jZSqb0Lkf.png)

We have a basic layout up, and a first taste of what testing involves. To dive or not to dive is the question I pose to you.

Hush for a moment and let it settle. We will proceed with our application in an upcoming article.

Be sure to check the code, if need be, from [TheGreenCodes](https://github.com/TheGreenCodes/awesome-todo/releases/tag/v0.1.0) repo. Specifically, the project tag `awesome-todo v0.1.0`.

Stick around for a while as we delve more into the internals; and yes, we can continue this conversation on tech twitter, where Potato, oh, my bad, [Larry](https://twitter.com/miamilarry78) and I, [Marvin](https://twitter.com/marvinus_j), talk everything between code and smelling flowers over the weekends. 

Peace out.




*A small laugh, in case [Lewis](https://lewiskori.com/), finds himself here again:*

*'Kuingia kimahuru'*