How to start using TDD (test-driven development) with Vue.js 🚀

How to start using TDD (test-driven development) with Vue.js 🚀

Test-driven development (TDD) is a process where you write tests before you write the associated code. You're ready to start using TDD with Vue so you can be confident that your code is working exactly as intended.

Test-driven development (TDD) is a process where you write tests before you write the associated code. You're ready to start using TDD with Vue so you can be confident that your code is working exactly as intended.

You first write a test that describes an expected behavior, and you run it, ensuring it fails. Then, you write the dumbest, most straightforward code you can to make the test pass. Finally, you refactor the code to make it right. And you repeat all the steps for each test until you’re done.

This approach has many advantages. First, it forces you to think before you code. It’s commonplace to rush into writing code before establishing what it should do. This practice leads to wasting time and writing complicated code. With TDD, any new piece of code requires a test first, so you have no choice but take the time to define what this code should do before you write it.

Secondly, it ensures you write unit tests. Starting with the code often leads to writing incomplete tests, or even no tests at all. Such a practice usually happens as a result of not having precise and exhaustive specs, which leads to spending more time coding than you should. Writing tests becomes a costly effort, which is easy to undermine once the production code is ready.

Unit tests are critical to building robust code. Overlooking or rushing them increases chances of your code breaking in production at some point.

Why do TDD for components?

Testing a component can be counter-intuitive. As we saw in Unit Test Your First Vue.js Component, it requires a mental shift to wrap your head around testing components versus testing plain scripts, knowing what to test, and understanding the line between unit tests and end-to-end.

TDD makes all this easier. Instead of writing tests by examining all bits and pieces of a finished project and trying to guess what you should cover, you’re doing the opposite. You’re starting from actual specs, a list of things that the component should do, without caring about how it does it. This way, you’re ensuring that all you test is the public API, but you’re also guaranteeing you don’t forget anything.

In this tutorial, we’ll build a color picker. For every swatch, users can access the matching color code, either in hexadecimal, RGB, or HSL.

Design inspired from Custom Color Picker Exploration by Chris Castillo

Despite its apparent simplicity, there are a bunch of small pieces of logic to test. They require some thinking before jumping into code.

In this article, we’ll deep dive into TDD. We’ll put some specs together before we write a single line of code. Then, we’ll test every public feature in a test-driven fashion. Finally, we’ll reflect on what we did and see what we can learn from it.

Before we start

This **tutorial **assumes you’ve already built something with Vue.js before, and written unit tests for it using Vue Test Utils and Jest (or a similar test runner). It won’t go deeper into the fundamentals, so make sure you get up to speed first. If you’re not there yet, I recommend you go over Build Your First Vue.js Component and Unit Test Your First Vue.js Component.

TL;DR: *this post goes in-depth in the how and why. It’s designed to help you understand every decision behind testing a real-world Vue.js component with ****TDD ***and teach you how to make design decisions for your future projects. If you want to understand the whole thought process, read on. Otherwise, you can go directly to the afterthoughts at the end, or look at the final code on GitHub.

Write down your specs

Before you even write your first test, you should write down an overview of what the component should do. Having specs makes testing much more straightforward since you’re mostly rewriting each spec in the form of tests.

Let’s think about the different parts that compose our component, and what they should do.

First, we have a collection of color swatches. We want to be able to pass a list of custom colors and display as swatches in the component. The first one should be selected by default, and the end user can select a new one by clicking it.

Secondly, we have the color mode toggler. The end user should be able to switch between three modes: hexadecimal (default), RGB and HSL.

Finally, we have the color code output, where the end user can get the code for the currently selected color swatch. This code is a combination of the selected swatch and color mode. Thus, by default, it should display the first swatch as a hexadecimal value. When changing any of these, the code should update accordingly.

As you can see, we don’t go too deep into details; we don’t specify what the color mode labels should be, or what the active state looks like for the color swatches. We can make most of the small decisions on the fly, even when doing TDD. Yet, we’ve come from a simple definition of what the component should be, to a comprehensive set of specs to start from.

Write test-driven code

First, you need to create a new Vue project with Vue CLI. You can check Build Your First Vue.js Component if you need a step by step guide.

During the scaffolding process, manually select features and make sure you check Unit testing. Pick Jest as your testing solution, and proceed until the project is created, dependencies are installed, and you’re ready to go.

We’ll need to use SVG files as components, so you also need to install the right loader for them. Install vue-svg-loader as a dev dependency, and add a rule for it in your vue.config.js file.

// vue.config.js
module.exports = {
  chainWebpack: config => {
    const svgRule = config.module.rule('svg')
    svgRule.uses.clear()
    svgRule.use('vue-svg-loader').loader('vue-svg-loader')
  }
}

This loader doesn’t play well with Jest by default, which causes tests to throw. To fix it, create a svgTransform.js file as documented on the website, and edit your jest.config.js as follows:

// svgTransform.js
const vueJest = require('vue-jest/lib/template-compiler')
module.exports = {
  process(content) {
    const { render } = vueJest({
      content,
      attrs: {
        functional: false
      }
    })
    return `module.exports = { render: ${render} }`
  }
}
// jest.config.js
module.exports = {
  // ...
  transform: {
    // ...
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)
Note that we’ve removed “svg” from the first regular expression (the one that gets transformed with ```jest-transform-stub```). This way, we ensure SVGs get picked up by ```svgTransform.js```.

Additionally, you need to install [color-convert](https://www.npmjs.com/package/color-convert "color-convert") as a dependency. We’ll need it both in our code and in our tests later on.

**Don’t serve the project yet**. We’re going to write tests and rely on them passing or not to move on. We don’t want to control whether what we build works by testing it visually in the browser, nor being distracted by how it looks.

Instead, open your project and create a new ```ColorPicker.vue``` single-file component in the ```src/components/``` directory. In ```tests/unit/```, create its associated spec file.

// ColorPicker.spec.js import { shallowMount } from '@vue/test-utils' import ColorPicker from '@/components/ColorPicker' describe('ColorPicker', () => { // let's do this! })

In your terminal, execute the following command to run tests:

npm run test:unit --watchAll


For now, you should get an error because you don’t yet have tests. Don’t worry though; we’ll fix this shortly 🙂 Note the usage of the ```--watchAll``` flag in the command: Jest is now watching your files. This way, you won’t have to re-run test by hand.

TDD goes in 3 stages:
1. **Red**: you write a test that describes an expected behavior, then you run it, ensuring it fails.
1. **Green**: you write the dumbest, most straightforward code you can to make the test pass.
1. **Refactor**: you refactor the code to make it right.
## 

## Step 1: Red




Time to write our first test! We’ll start with the color swatches. For clarity, we’ll wrap all tests for each distinct element in their own suite, using a ```describe``` block.

First, we want to make sure that the component displays each color that we provide as an individual swatch. We would pass those as props, in the form of an array of hexadecimal strings. In the component, we would display the list as an unordered list, and assign the background color via a ```style``` attribute.

import { shallowMount } from '@vue/test-utils'
import ColorPicker from '@/components/ColorPicker'
import convert from 'color-convert'
let wrapper = null
const propsData = {
swatches: ['e3342f', '3490dc', 'f6993f', '38c172', 'fff']
}
beforeEach(() => (wrapper = shallowMount(ColorPicker, { propsData })))
afterEach(() => wrapper.destroy())
describe('ColorPicker', () => {
describe('Swatches', () => {
test('displays each color as an individual swatch', () => {
const swatches = wrapper.findAll('.swatch')
propsData.swatches.forEach((swatch, index) => {
expect(swatches.at(index).attributes().style).toBe(
background: rgb(${convert.hex.rgb(swatch).join(', ')})
)
})
})
})
})


We mounted our ```ColorPicker``` component and wrote a test that expects to find items with a background color matching the colors passed as props. **This test is bound to fail**: we currently have nothing in ```ColorPicker.vue```. If you look at your terminal, you should have an error saying that no item exists at 0. This is great! **We just passed the first step of TDD with flying colors.**



## Step 2: Green




Our test is failing; we’re on the right track. Now, time to make it pass. We’re not much interested in writing working or smart code at this point, all we want is to make Jest happy. Right now, Vue Test Utils complains about the fact that we don’t event have no item at index 0.

[vue-test-utils]: no item exists at 0


The simplest thing we can do to make that error go away is to add an unordered list with a ```swatch``` class on the list item.


Jest still complains but the error has changed:

Expected value to equal:
"background: rgb(227, 52, 47);"
Received:
undefined


This makes sense; the list item doesn’t have a ```style``` attribute. The simplest thing we can do about it is to hardcode the ```style``` attribute. This isn’t what we want in the end, but, we aren’t concerned about it yet. What we want is **for our test to go green**.

We can therefore hardcode five list items with the expected style attributes:


The test should now pass.



## Step 3: Refactor




At this stage, we want to rearrange our code to make it right, without breaking tests. In our case, we don’t want to keep the list items and their ```style``` attributes hardcoded. Instead, it would be better to receive swatches as a prop, iterate over them to generate the list items, and assign the colors as their background.


When tests re-run, they should still pass 🥳 This means **we’ve successfully refactored the code without affecting the output**. Congratulations, you’ve just completed your first TDD cycle!

Now, before we go to the next test, let’s reflect a bit. You may be wondering:
> “Isn’t this a bit dumb? I knew the test would fail. Am I not wasting time by running it anyway, then hardcoding the right value, see the test pass, then make the code right? Can’t I go to the refactor step directly?”
It’s understandable that you’re feeling confused by the process. Yet, try to look at things from a different angle: the point here isn’t to *prove* that the test doesn’t pass. We know it won’t. What we want to look at is what our test *expects*, make them happy in the simplest possible way, and finally write smarter code without breaking anything.

That’s the whole idea of test-driven development: we don’t write code to make things work, **we write code to make tests pass**. By reversing the relationship, we’re ensuring robust tests with a focus on the outcome.



## What are we testing?




Another question that may come to mind is **how we’re deciding what to test**. In [Unit Test Your First Vue.js Component](https://frontstuff.io/unit-test-your-first-vuejs-component "Unit Test Your First Vue.js Component"), we saw that we should only be testing the public **API **of our component, not the internal implementation. Strictly speaking, this means we should cover **user interactions** and **props changes**.

But is that all? For example, is it okay for the output **HTML **to break? Or for **CSS **class names to change? Are we sure nobody is relying on them? That you aren’t yourself?

**Tests should give you confidence that you aren’t shipping broken software.** What people can do with your program shouldn’t stop working the way they expect it to work. It can mean different things depending on the project and use case.

For example, if you’re building this color panel as an open source component, your users are other developers who use it in their own projects. They’re likely relying on the class names you provide to style the component to their liking. **The class names become a part of your public API because your users rely on them.**

In our case, we may not necessarily be making an open source component, but we have view logic that depends on specific class names. For instance, it’s important for active swatches to have an ```active``` class name, because we’ll rely on it to display a checkmark, in CSS. If someone changes this by accident, we want to know about it.

Testing scenarios for UI components highly depend on the use case and expectations. Whichever the case, what you need to ask yourself is **do I care about this if it changes**?
### Next tests
#### Testing the swatches

Let’s move on to the next test. We expect the first swatch of the list to be the one that’s selected by default. From the outside, **this is something that we want to ensure keeps on working the same way**. Users could, for instance, rely on the active class name to style the component.

test('sets the first swatch as the selected one by default', () => {
const firstSwatch = wrapper.find('.swatch')
expect(firstSwatch.classes()).toContain('active')
})


This test, too, should fail, as list items currently don’t have any classes. We can easily make this pass by adding the class on the first list item.

  • 
    The test now passes; however, we’ve hardcoded the logic into the template. We can refactor that by externalizing the index onto which the class applies. This way, we can change it later.
    
    
  • export default { // ... data() { return { activeSwatch: 0 } } }
    
    This naturally leads us to our third test. We want to change the active swatch whenever the end user clicks it.
    
    

    test('makes the swatch active when clicked', () => {
    const targetSwatch = wrapper.findAll('.swatch').at(2)
    targetSwatch.trigger('click')
    expect(targetSwatch.classes()).toContain('active')
    })

    
    For now, nothing happens when we click a swatch. However, thanks to our previous refactor, we can make this test go green and even skip the refactor step.
    
    
  • 
    This code makes the test pass and doesn’t even need a refactor. **This is a fortunate side-effect of doing TDD**: sometimes, the process leads to either writing new tests that either don’t need refactors, or even that pass right away.
    
    Active swatches should show a checkmark. We’ll add it now **without writing a test**: instead, we’ll control their visibility via CSS later. This is alright since we’ve already tested how the ```active``` class applies.
    
    First, create a ```checkmark.svg``` file in ```src/assets/```.
    
    
    
    Then, import it in the component.
    
    

    import CheckIcon from '@/assets/check.svg'
    export default {
    // ...
    components: { CheckIcon }
    }

    
    Finally, add it inside the list items.
    
    
  • 
    Good! We can now move on to the next element of our component: **the color mode**.
    ## 
    
    ## Testing the color mode
    
    
    
    
    Let’s now implement the color mode toggler. The end user should be able to switch between hexadecimal, RGB and HSL. We’re defining these modes internally, but we want to ensure they render correctly.
    
    Instead of testing button labels, **we’ll rely on class names**. It makes our test more robust, as we can easily define a class name as part of our component’s contract. However, button labels should be able to change.
    
    Now you may be tempted to check for these three specific modes, but that would make the test brittle. What if we change them? What if we add one, or remove one? That would still be the same logic, yet the test would fail, forcing us to go and edit it.
    
    One solution could be to access the component’s data to iterate on the modes dynamically. Vue Test Utils lets us do that through the [vm](https://vue-test-utils.vuejs.org/api/wrapper/#properties "vm") property, but again, this tightly couples our test with the internal implementation of the modes. If tomorrow, we decided to change the way we define modes, the test would break.
    
    Another solution is to keep going with black box testing and only expect the class name to match a given *pattern*. We don’t care that it’s ```color-mode-hex```, ```color-mode-hsl``` or ```color-mode-xyz```, as long as it looks like what we expect from the outside. Jest lets us do that with regular expression matchers.
    
    

    // ...
    describe('Color model', () => {
    test('displays each mode as an individual button', () => {
    const buttons = wrapper.findAll('.color-mode')
    buttons.wrappers.forEach(button => {
    expect(button.classes()).toEqual(
    expect.arrayContaining([expect.stringMatching(/color-mode-\w{1,}/)])
    )
    })
    })
    })

    
    Here, we’re expecting elements with a class that follows the pattern “color-mode-“ + any word character (in ECMAScript, any character within ```[a-zA-Z_0-9]```). We could add or remove any mode we want, and the test would still be valid.
    
    Naturally, right now, the test should fail, as there are no buttons with class ```color-mode``` yet. We can make it pass by hardcoding them in the component.
    
    
    
    We can now refactor this code by adding the modes as private data in our component and iterate over them.
    
    
    {{ mode }}
    export default { // ... data() { return { activeSwatch: 0, colorModes: ['hex', 'rgb', 'hsl'] } } }
    
    Good! Let’s move on.
    
    As with the swatches, we want the first mode to be set as active. We can copy the test we wrote and adapt it to this new use case.
    
    

    test('sets the first mode as the selected one by default', () => {
    const firstButton = wrapper.find('.color-mode')
    expect(firstButton.classes()).toContain('active')
    })

    
    We can make this test pass by manually adding the class on the first list item.
    
    

    <button
    :key="index"
    v-for="(mode, index) in colorModes"
    class="color-mode"
    :class="[{ active: index === 0 }, color-mode-${mode}]"

    {{ mode }}

    
    Finally, we can refactor by externalizing the index onto which the class applies.
    
    
    {{ mode }} export default { // ... data() { return { activeSwatch: 0, activeMode: 0, colorModes: ['hex', 'rgb', 'hsl'] } } }
    
    We need to change the active mode whenever the end user clicks the associated button, as with the swatches.
    
    

    test('sets the color mode button as active when clicked', () => {
    const targetButton = wrapper.findAll('.color-mode').at(2)
    targetButton.trigger('click')
    expect(targetButton.classes()).toContain('active')
    })

    
    We can now add a ```@click``` directive as we did with the swatches, and make the test go green without having to refactor.
    
    

    <button
    :key="index"
    v-for="(mode, index) in colorModes"
    class="color-mode"
    :class="[{ active: index === activeMode }, color-mode-${mode}]"
    @click="activeMode = index"

    {{ mode }}

    ## 
    
    ## Testing the color code
    
    
    
    
    Now that we’re done testing the swatches and color code, we can move on to the third and final element of our color picker: **the color code**. What we display in there is a combination of the other two: the selected swatch defines the color we should display, and the selected mode determines how to display it.
    
    First, we want to make sure we initially display the default swatch in the default mode. We have the information to build this since we’ve implemented the swatches and the color mode.
    
    Let’s start with a (failing) test.
    
    

    describe('Color code', () => {
    test('displays the default swatch in the default mode', () => {
    expect(wrapper.find('.color-code').text()).toEqual('#e3342f')
    })
    })

    
    Now, let’s make this pass by hardcoding the expected result in the component.
    
    
    #e3342f
    
    Good! Time to refactor. We have a raw color in hexadecimal mode, and we’re willing to output it in hexadecimal format. The only difference between our input and output values is that we want to prepend the latter with a hash character. The easiest way of doing so with Vue is via a ```computed``` property.
    
    
    {{ activeCode }}
    export default { // ... computed: { activeCode() { return `#${this.swatches[this.activeSwatch]}` } } }
    
    This should keep the test green. However, there’s an issue with this computed property: it only works for hexadecimal values. It should keep on working when we change the color, but not when we change the mode. We can verify this with another test.
    
    

    test('displays the code in the right mode when changing mode', () => {
    wrapper.find('.color-mode-hsl').trigger('click')
    expect(wrapper.find('.color-code').text()).toEqual('2°, 76%, 54%')
    })

    
    Here, we’ve changed to HSL mode, but we’re still getting the hexadecimal output. We need to refactor our code so that our ```activeCode``` computed property is not only aware of the current color, but also the current color mode. One way we can achieve this is to create computed properties for each mode and proxy them through ```activeCode``` based on the selected mode.
    
    First, we should simplify access to the current color and mode. Right now, we need to do an array lookup, which is repetitive and makes the code hard to read. We can use computed properties to wrap that logic.
    
    

    export default {
    // ...
    computed: {
    // ...
    activeColorValue() {
    return this.swatches[this.activeSwatch]
    },
    activeModeValue() {
    return this.colorModes[this.activeMode]
    }
    }
    }

    
    As you can see, we’re not writing tests for these computed properties, as they aren’t part of our public API. We’ll use them later in our dedicated color mode computed properties, which themselves will be proxied in ```activeCode```, which we’re testing in our “Color code” suite. **All we care about is that the color code renders as expected** so that the user can rely on them. How we get there are implementation details that we need to be able to change if need be.
    
    We can now write our dedicated computed properties for each mode. We’ll map their name onto the ones in ```colorModes```, so we can do an array lookup later in ```activeCode``` to return the right one.
    
    For the hexadecimal output, we can externalize what we currently have in ```activeCode``` and refactor it using ```activeColorValue```.
    
    

    export default {
    // ...
    computed: {
    // ...
    hex() {
    return #${this.activeColorValue}
    }
    }
    }

    
    Now, let’s modify ```activeCode``` so it proxies the right computed property depending on the active mode.
    
    

    export default {
    // ...
    computed: {
    // ...
    activeCode() {
    return this[this.activeModeValue]
    }
    }
    }

    
    This still shouldn’t make our latest test pass, since we haven’t written a computed property for it. However, our test that checks if the default mode renders correctly is still passing, which is a good sign we’re on the right track.
    
    We now want to write a computed property that returns the color output in HSL mode. For this, we’ll use ```color-convert```, an npm package that lets us convert colors in many different modes. We’ve already been using it in our tests, so we don’t have to reinstall it.
    
    

    import convert from 'color-convert'
    export default {
    // ...
    computed: {
    // ...
    hsl() {
    const hslColor = convert.hex.hsl(this.activeColorValue)
    return ${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%
    }
    }
    }

    
    Great, our test passes! We can now finish this up adding the missing RGB mode.
    
    Yet, as you can see, we’re currently not testing the output of our color computed properties in isolation, but through other tests. To make things cleaner, we could decouple that logic from the component, import it as a dependency, and test it separately. This has several benefits:
    * it keeps the component from growing every time we want to add a color mode,
    * it keeps domains separated: the component focuses on its own view logic, and the color modes utility takes care of testing each mode exhaustively.
    
    First, create a new ```color.js``` file in the ```src/utils/``` directory, and a matching spec file in ```tests/unit/```.
    
    

    // color.spec.js
    import { rgb, hex, hsl } from '@/utils/color'
    // color.js
    import convert from 'color-convert'
    export const rgb = () => {}
    export const hex = () => {}
    export const hsl = () => {}

    
    We can use TDD to test those three functions and make sure they always return the expected value. We can extract the logic we had in our Vue component for the last two, and write the RGB function from scratch.
    
    For the sake of brevity, we’ll cover all three tests at once, but the process remains the same.
    
    

    import { rgb, hex, hsl } from '@/utils/color'
    const color = 'e3342f'
    describe('color', () => {
    test('returns the color into RGB notation', () => {
    expect(rgb(color)).toBe('227, 52, 47')
    })
    test('returns the color into hexadecimal notation', () => {
    expect(hex(color)).toBe('#e3342f')
    })
    test('returns the color into HSL notation', () => {
    expect(hsl(color)).toBe('2°, 76%, 54%')
    })
    })

    
    We now have three failing tests. The first thing we can do is to return hardcoded values to go green.
    
    

    export const rgb = () => '227, 52, 47'
    export const hex = () => '#e3342f'
    export const hsl = () => '2°, 76%, 54%'

    
    Now, we can start refactoring by migrating the code from our Vue component.
    
    

    export const hex = () => #${color}
    export const hsl = color => {
    const hslColor = convert.hex.hsl(color)
    return ${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%
    }

    
    Finally, we can implement our ```rgb``` function.
    
    

    export const rgb = color => convert.hex.rgb(color).join(', ')

    
    All tests should stay green!
    
    We can now use the ```color``` utilities in our Vue component and refactor it a bit. We no longer need to import ```color-convert``` in the component, nor do we need dedicated computed properties for each mode, or even for getting the active color and mode values. All we need to keep is ```activeCode```, where we can store all the necessary logic.
    
    This is a good example where doing black box testing helps us: we’ve been focusing on testing the public API; thus **we can refactor the internals of our component without breaking the tests**. Removing properties like ```activeColorValue``` or ```hex``` doesn’t matter, because we were never testing them directly.
    
    

    // ...
    import { rgb, hex, hsl } from '@/utils/color'
    const modes = { rgb, hex, hsl }
    export default {
    // ...
    computed: {
    activeCode() {
    const activeColor = this.swatches[this.activeSwatch]
    const activeMode = this.colorModes[this.activeMode]
    return modesactiveMode
    }
    }
    }

    
    We now have much terser code in our component, and better domain separation, while still respecting the component’s contract.
    
    Finally, we can implement a missing test: the one that ensures the color code changes whenever we click a new swatch. This should already go green, but it’s still essential for us to write it, so we can know about it if it breaks.
    
    

    test('displays the code in the right color when changing color', () => {
    wrapper
    .findAll('.swatch')
    .at(2)
    .trigger('click')
    expect(wrapper.find('.color-code').text()).toEqual('#f6993f')
    })

    
    And we’re done! We just built a fully functional Vue component using TDD, without relying on browser output, **and our tests are ready**.
    
    
    
    ## Visual control
    
    
    
    
    Now that our component is ready, we can see how it looks and play with it in the browser. This allows us to add the CSS and ensure we didn’t miss out on anything.
    
    First, mount the component into the main ```App.vue``` file.
    
    
    
    Then, run the app by executing the following script, and open it in your browser at ```<a href="http://localhost:8080/" target="_blank">http://localhost:8080/</a>```.
    
    

    npm run serve

    
    You should see your color picker! It doesn’t look like much for now, but it works. Try clicking colors and change the color mode; you should see the color code change.
    
    To see the component with proper styling, add the following CSS between the ```style``` tags:
    
    

    .color-picker {
    background-color: #fff;
    border: 1px solid #dae4e9;
    border-radius: 0.125rem;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
    color: #596a73;
    font-family: BlinkMacSystemFont, Helvetica Neue, sans-serif;
    padding: 1rem;
    }
    .swatches {
    color: #fff;
    display: flex;
    flex-wrap: wrap;
    list-style: none;
    margin: -0.25rem -0.25rem 0.75rem;
    padding: 0;
    }
    .swatch {
    border-radius: 0.125rem;
    cursor: pointer;
    height: 2rem;
    margin: 0.25rem;
    position: relative;
    width: 2rem;
    }
    .swatch::after {
    border-radius: 0.125rem;
    bottom: 0;
    box-shadow: inset 0 0 0 1px #dae4e9;
    content: '';
    display: block;
    left: 0;
    mix-blend-mode: multiply;
    position: absolute;
    right: 0;
    top: 0;
    }
    .swatch svg {
    display: none;
    color: #fff;
    fill: currentColor;
    margin: 0.5rem;
    }
    .swatch.active svg {
    display: block;
    }
    .color-modes {
    display: flex;
    font-size: 1rem;
    letter-spacing: 0.05rem;
    margin: 0 -0.25rem 0.75rem;
    }
    .color-mode {
    background: none;
    border: none;
    color: #9babb4;
    cursor: pointer;
    display: block;
    font-weight: 700;
    margin: 0 0.25rem;
    padding: 0;
    text-transform: uppercase;
    }
    .color-mode.active {
    color: #364349;
    }
    .color-code {
    border: 1px solid #dae4e9;
    border-radius: 0.125rem;
    color: #364349;
    text-transform: uppercase;
    padding: 0.75rem;
    }

    
    You should see something like this:
    
    ![](https://cdn-images-1.medium.com/max/640/0*e2w8W0MplRF7UPdc.gif)
    
    And we’re done!
    
    
    
    ## Afterthoughts
    #### How can we improve this?
    
    For now, we have a robust test suite. Even though we don’t have 100% coverage, we can feel confident with our component going out in the wild, and evolving over time. There are still a couple of things we could improve though, depending on the use case.
    
    First, you may notice that when clicking the white swatch, the checkmark doesn’t show up. That’s not a bug, rather a visual issue: the checkmark is there, but we can’t see it because it’s white on white. You could add a bit of logic to fix this: when a color is lighter than a certain threshold (let’s say 90%), you could add a ```light``` class on the swatch. This would then let you apply some specific CSS and make the checkmark dark.
    
    Fortunately, you already have all you need: the ```color-converter``` package can help you determine whether a color is light (with the HSL utilities), and you already have a ```color``` utility module to store that logic and test it in isolation. To see what the finished code could look like, check out the project’s repository on [GitHub](https://github.com/sarahdayan/colorpicker-tdd-tutorial "GitHub").
    
    We could also reinforce the suite by adding a few tests to make sure some expected classes are there. This doesn’t test actual logic, but would still be particularly useful if someone was relying on those class names to style the component from the outside. Again, everything depends on your use case: test what shouldn’t change without you knowing, don’t only add tests for the sake of it.
    
    
    
    ## What did we learn?
    
    
    
    
    There are several lessons to learn from this TDD experiment. It brings a lot to the table but also highlights a few challenges that we should be aware of.
    
    First, TDD is a **fantastic way to write robust tests**, not too many and not too few. Have you ever finished a component, moved on to tests and thought *“where do I even start?”*? Looking at finished code and figuring out what to test is hard. It’s tempting to get it done quickly, overlook some critical parts and end up with an incomplete test suite. Or you can adopt a defensive approach and test everything, risking to focus on implementation details and writing brittle tests.
    
    Adopting TDD for developing UI components helps us focus on exactly what to test by **defining, before writing any line of code, if this is part of the contract or not**.
    
    Secondly, **TDD encourages refactors, leading to better software design**. When you’re writing tests after coding, you’re usually no longer in a refactoring dynamic. You can fix your code if you find issues while testing, but at this stage, you’re most likely done with the implementation. **This separation between writing code and writing test is where lies the issue.**
    
    With TDD, **you’re creating a deeper connection between code and tests, with a strong focus on making the public API reliable**. Implementation comes right after you’ve guaranteed the outcome. This is why the *green* step is critical: you first need your test to pass, then ensure it never breaks. Instead of implementing your way to a working solution, you’re reversing the relationship, focusing on the contract first, and allowing the implementation to remain disposable. Because refactoring comes last, and you’ve established the contract, you now have mental space to make things right, clean some code, adopt a better design, or focus on performance.
    
    It’s worth noting that **TDD is much easier to follow with specs**. When you already have a clear overview of everything the component should do, you can translate those specifications into tests. Some teams use frameworks like [ATDD](https://en.wikipedia.org/wiki/Acceptance_test%E2%80%93driven_development "ATDD") (acceptance test–driven development), where the involved parties develop specifications from a business perspective. The final specs, or acceptance tests, are a perfect base to write tests following TDD.
    
    On the other hand, going with TDD to test UI components can be difficult at first, and require some prior knowledge before diving into it. For starters, **you need to have good knowledge of your testing libraries** so that you can write reliable assertions. Look at the test we wrote with a regular expression: the syntax is not the most straightforward. If you don’t know the library well, it’s easy to write a test that fails for the wrong reasons, which would end up hindering the whole TDD process.
    
    Similarly, you need to be aware of some details regarding the values you expect; otherwise, you could end up battling with your tests and doing some annoying back-and-forths. On that matter, UI components are more challenging than renderless libraries, because of the various ways the DOM specifications can be implemented.
    
    Take the first test of our suite for example: we’re testing background colors. However, even though we’re passing hexadecimal colors, we’re expecting RGB return values. That’s because Jest uses [jsdom](https://github.com/jsdom/jsdom "jsdom"), a Node.js implementation of the DOM and HTML standards. If we were running our tests in a specific browser, we might have a different return value. This can be tricky when you’re testing different engines. You may have to seek some more advanced conversion utilities or use environment variables to handle the various implementations.
    ## Is it worth it?
    
    
    
    
    If you made it this far, you’ve probably realized that **TDD demands time**. This article itself is over 6,000 words! This can be a bit scary if you’re used to faster development cycles, and probably looks impossible if you’re often working under pressure. However, it’s important to bust the myth that TDD would somehow double development time for little return on investment, because this is entirely false.
    
    TDD requires some practice, and you’ll get faster over time. What feels clumsy today can become a second nature tomorrow, if you do it regularly. I encourage you not to discard something because it’s new and feels awkward: give it some time to assess it fairly, then take a decision.
    
    Secondly, **time spent on writing test-driven code is time you won’t spend fixing bugs**.
    
    Fixing bugs is far more costly than preventing them. If you’ve ever had to fix critical production bugs, you know this feels close to holding an open wound on a surgical patient with one hand, while trying to operate with the other one. In the desert. At night. With a Swiss Army knife. It’s messy, stressful, suboptimal, and bears high chances of screwing up something else in the process. If you want to preserve your sanity and the trust your end users have in your software, **you want to avoid those situations at all costs**.
    
    
    
    
    ![](https://cdn-images-1.medium.com/max/640/0*-ypCMc0eow3xfIdm.gif)
    
    Tests help you catch bugs before they make it to production, and TDD helps you write better tests. **If you think you should test your software, then you should care about making these tests useful in the first place.** Otherwise, the whole thing is only a waste of time.
    
    As with anything, I encourage you to try TDD before discarding the idea. If you’re consistently encountering production issues, or you think you could improve your development process, then it’s worth giving it a shot. **Try it for a limited amount of time, measure the impact, and compare the results.** You may discover a method that helps you ship better software, and feel more confident about hitting the “Deploy” button.
    
    **Thanks for reading** ❤
    
    If you liked this post, share it with all of your programming buddies!
    
    Follow us on [**Facebook**](https://www.facebook.com/vuejstutorial "**Facebook**") | [**Twitter**](https://twitter.com/moriohdotcom "**Twitter**")
    ### Learn More
    
    ☞ [Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)](http://learnstartup.net/p/BJBa7-l-g "Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)")
    
    ☞ [Nuxt.js - Vue.js on Steroids](http://learnstartup.net/p/ryWiRu5qz "Nuxt.js - Vue.js on Steroids")
    
    ☞ [Build Web Apps with Vue JS 2 & Firebase](http://learnstartup.net/p/r1IF4NTpM "Build Web Apps with Vue JS 2 & Firebase")
    
    ☞ [Front-end Developer Handbook 2019](http://on.geeklearn.net/38b3800bb9 "Front-end Developer Handbook 2019")
    
    ☞ [ES Module Browser Build in Vue](http://tech.learn4startup.com/eae8ea9ece "ES Module Browser Build in Vue")
    
    ☞ [Implementing Authentication in a Nuxt.js App](http://tech.learn4startup.com/4082d07f9f "Implementing Authentication in a Nuxt.js App")
    
    ☞ [Getting Started with Vuex: Managing State in Vue.js](http://tech.edupioneer.net/6e329fcdee "Getting Started with Vuex: Managing State in Vue.js")
    
    ☞ [Build a Server-Side Rendered Vue App with Nuxt.js](http://on.geeklearn.net/af342a0d69 "Build a Server-Side Rendered Vue App with Nuxt.js")
    
    ☞ [React vs. Vue vs. Angular](http://tech.edupioneer.net/51a9b27b79 "React vs. Vue vs. Angular")
    
    ☞ [Getting up and Running with the Vue.js 2.0 Framework](http://on.edupioneer.net/4e3020cd5b "Getting up and Running with the Vue.js 2.0 Framework")
    
    ☞ [Hands-on Vue.js for Beginners](http://tech.edupioneer.net/5c942093ff "Hands-on Vue.js for Beginners")
    
    ☞ [Vue CLI 3 Full-Stack App Structure](http://on.geeklearn.net/f877e930ab "Vue CLI 3 Full-Stack App Structure")
    
    *Originally published on *[*https://medium.freecodecamp.org*](https://medium.freecodecamp.org/an-introduction-to-tdd-with-vue-js-66544710b50c "*https://medium.freecodecamp.org*")
    : 'jest-transform-stub',
        '^.+\\.svg
    Note that we’ve removed “svg” from the first regular expression (the one that gets transformed with ```jest-transform-stub```). This way, we ensure SVGs get picked up by ```svgTransform.js```.
    
    Additionally, you need to install [color-convert](https://www.npmjs.com/package/color-convert "color-convert") as a dependency. We’ll need it both in our code and in our tests later on.
    
    **Don’t serve the project yet**. We’re going to write tests and rely on them passing or not to move on. We don’t want to control whether what we build works by testing it visually in the browser, nor being distracted by how it looks.
    
    Instead, open your project and create a new ```ColorPicker.vue``` single-file component in the ```src/components/``` directory. In ```tests/unit/```, create its associated spec file.
    
    
    // ColorPicker.spec.js import { shallowMount } from '@vue/test-utils' import ColorPicker from '@/components/ColorPicker' describe('ColorPicker', () => { // let's do this! })
    
    In your terminal, execute the following command to run tests:
    
    

    npm run test:unit --watchAll

    
    For now, you should get an error because you don’t yet have tests. Don’t worry though; we’ll fix this shortly 🙂 Note the usage of the ```--watchAll``` flag in the command: Jest is now watching your files. This way, you won’t have to re-run test by hand.
    
    TDD goes in 3 stages:
    1. **Red**: you write a test that describes an expected behavior, then you run it, ensuring it fails.
    1. **Green**: you write the dumbest, most straightforward code you can to make the test pass.
    1. **Refactor**: you refactor the code to make it right.
    ## 
    
    ## Step 1: Red
    
    
    
    
    Time to write our first test! We’ll start with the color swatches. For clarity, we’ll wrap all tests for each distinct element in their own suite, using a ```describe``` block.
    
    First, we want to make sure that the component displays each color that we provide as an individual swatch. We would pass those as props, in the form of an array of hexadecimal strings. In the component, we would display the list as an unordered list, and assign the background color via a ```style``` attribute.
    
    

    import { shallowMount } from '@vue/test-utils'
    import ColorPicker from '@/components/ColorPicker'
    import convert from 'color-convert'
    let wrapper = null
    const propsData = {
    swatches: ['e3342f', '3490dc', 'f6993f', '38c172', 'fff']
    }
    beforeEach(() => (wrapper = shallowMount(ColorPicker, { propsData })))
    afterEach(() => wrapper.destroy())
    describe('ColorPicker', () => {
    describe('Swatches', () => {
    test('displays each color as an individual swatch', () => {
    const swatches = wrapper.findAll('.swatch')
    propsData.swatches.forEach((swatch, index) => {
    expect(swatches.at(index).attributes().style).toBe(
    background: rgb(${convert.hex.rgb(swatch).join(', ')})
    )
    })
    })
    })
    })

    
    We mounted our ```ColorPicker``` component and wrote a test that expects to find items with a background color matching the colors passed as props. **This test is bound to fail**: we currently have nothing in ```ColorPicker.vue```. If you look at your terminal, you should have an error saying that no item exists at 0. This is great! **We just passed the first step of TDD with flying colors.**
    
    
    
    ## Step 2: Green
    
    
    
    
    Our test is failing; we’re on the right track. Now, time to make it pass. We’re not much interested in writing working or smart code at this point, all we want is to make Jest happy. Right now, Vue Test Utils complains about the fact that we don’t event have no item at index 0.
    
    

    [vue-test-utils]: no item exists at 0

    
    The simplest thing we can do to make that error go away is to add an unordered list with a ```swatch``` class on the list item.
    
    
    
    Jest still complains but the error has changed:
    
    

    Expected value to equal:
    "background: rgb(227, 52, 47);"
    Received:
    undefined

    
    This makes sense; the list item doesn’t have a ```style``` attribute. The simplest thing we can do about it is to hardcode the ```style``` attribute. This isn’t what we want in the end, but, we aren’t concerned about it yet. What we want is **for our test to go green**.
    
    We can therefore hardcode five list items with the expected style attributes:
    
    
    
    The test should now pass.
    
    
    
    ## Step 3: Refactor
    
    
    
    
    At this stage, we want to rearrange our code to make it right, without breaking tests. In our case, we don’t want to keep the list items and their ```style``` attributes hardcoded. Instead, it would be better to receive swatches as a prop, iterate over them to generate the list items, and assign the colors as their background.
    
    
    
    When tests re-run, they should still pass 🥳 This means **we’ve successfully refactored the code without affecting the output**. Congratulations, you’ve just completed your first TDD cycle!
    
    Now, before we go to the next test, let’s reflect a bit. You may be wondering:
    > “Isn’t this a bit dumb? I knew the test would fail. Am I not wasting time by running it anyway, then hardcoding the right value, see the test pass, then make the code right? Can’t I go to the refactor step directly?”
    It’s understandable that you’re feeling confused by the process. Yet, try to look at things from a different angle: the point here isn’t to *prove* that the test doesn’t pass. We know it won’t. What we want to look at is what our test *expects*, make them happy in the simplest possible way, and finally write smarter code without breaking anything.
    
    That’s the whole idea of test-driven development: we don’t write code to make things work, **we write code to make tests pass**. By reversing the relationship, we’re ensuring robust tests with a focus on the outcome.
    
    
    
    ## What are we testing?
    
    
    
    
    Another question that may come to mind is **how we’re deciding what to test**. In [Unit Test Your First Vue.js Component](https://frontstuff.io/unit-test-your-first-vuejs-component "Unit Test Your First Vue.js Component"), we saw that we should only be testing the public **API **of our component, not the internal implementation. Strictly speaking, this means we should cover **user interactions** and **props changes**.
    
    But is that all? For example, is it okay for the output **HTML **to break? Or for **CSS **class names to change? Are we sure nobody is relying on them? That you aren’t yourself?
    
    **Tests should give you confidence that you aren’t shipping broken software.** What people can do with your program shouldn’t stop working the way they expect it to work. It can mean different things depending on the project and use case.
    
    For example, if you’re building this color panel as an open source component, your users are other developers who use it in their own projects. They’re likely relying on the class names you provide to style the component to their liking. **The class names become a part of your public API because your users rely on them.**
    
    In our case, we may not necessarily be making an open source component, but we have view logic that depends on specific class names. For instance, it’s important for active swatches to have an ```active``` class name, because we’ll rely on it to display a checkmark, in CSS. If someone changes this by accident, we want to know about it.
    
    Testing scenarios for UI components highly depend on the use case and expectations. Whichever the case, what you need to ask yourself is **do I care about this if it changes**?
    ### Next tests
    #### Testing the swatches
    
    Let’s move on to the next test. We expect the first swatch of the list to be the one that’s selected by default. From the outside, **this is something that we want to ensure keeps on working the same way**. Users could, for instance, rely on the active class name to style the component.
    
    

    test('sets the first swatch as the selected one by default', () => {
    const firstSwatch = wrapper.find('.swatch')
    expect(firstSwatch.classes()).toContain('active')
    })

    
    This test, too, should fail, as list items currently don’t have any classes. We can easily make this pass by adding the class on the first list item.
    
    
  • 
    The test now passes; however, we’ve hardcoded the logic into the template. We can refactor that by externalizing the index onto which the class applies. This way, we can change it later.
    
    
  • export default { // ... data() { return { activeSwatch: 0 } } }
    
    This naturally leads us to our third test. We want to change the active swatch whenever the end user clicks it.
    
    

    test('makes the swatch active when clicked', () => {
    const targetSwatch = wrapper.findAll('.swatch').at(2)
    targetSwatch.trigger('click')
    expect(targetSwatch.classes()).toContain('active')
    })

    
    For now, nothing happens when we click a swatch. However, thanks to our previous refactor, we can make this test go green and even skip the refactor step.
    
    
  • 
    This code makes the test pass and doesn’t even need a refactor. **This is a fortunate side-effect of doing TDD**: sometimes, the process leads to either writing new tests that either don’t need refactors, or even that pass right away.
    
    Active swatches should show a checkmark. We’ll add it now **without writing a test**: instead, we’ll control their visibility via CSS later. This is alright since we’ve already tested how the ```active``` class applies.
    
    First, create a ```checkmark.svg``` file in ```src/assets/```.
    
    
    
    Then, import it in the component.
    
    

    import CheckIcon from '@/assets/check.svg'
    export default {
    // ...
    components: { CheckIcon }
    }

    
    Finally, add it inside the list items.
    
    
  • 
    Good! We can now move on to the next element of our component: **the color mode**.
    ## 
    
    ## Testing the color mode
    
    
    
    
    Let’s now implement the color mode toggler. The end user should be able to switch between hexadecimal, RGB and HSL. We’re defining these modes internally, but we want to ensure they render correctly.
    
    Instead of testing button labels, **we’ll rely on class names**. It makes our test more robust, as we can easily define a class name as part of our component’s contract. However, button labels should be able to change.
    
    Now you may be tempted to check for these three specific modes, but that would make the test brittle. What if we change them? What if we add one, or remove one? That would still be the same logic, yet the test would fail, forcing us to go and edit it.
    
    One solution could be to access the component’s data to iterate on the modes dynamically. Vue Test Utils lets us do that through the [vm](https://vue-test-utils.vuejs.org/api/wrapper/#properties "vm") property, but again, this tightly couples our test with the internal implementation of the modes. If tomorrow, we decided to change the way we define modes, the test would break.
    
    Another solution is to keep going with black box testing and only expect the class name to match a given *pattern*. We don’t care that it’s ```color-mode-hex```, ```color-mode-hsl``` or ```color-mode-xyz```, as long as it looks like what we expect from the outside. Jest lets us do that with regular expression matchers.
    
    

    // ...
    describe('Color model', () => {
    test('displays each mode as an individual button', () => {
    const buttons = wrapper.findAll('.color-mode')
    buttons.wrappers.forEach(button => {
    expect(button.classes()).toEqual(
    expect.arrayContaining([expect.stringMatching(/color-mode-\w{1,}/)])
    )
    })
    })
    })

    
    Here, we’re expecting elements with a class that follows the pattern “color-mode-“ + any word character (in ECMAScript, any character within ```[a-zA-Z_0-9]```). We could add or remove any mode we want, and the test would still be valid.
    
    Naturally, right now, the test should fail, as there are no buttons with class ```color-mode``` yet. We can make it pass by hardcoding them in the component.
    
    
    
    We can now refactor this code by adding the modes as private data in our component and iterate over them.
    
    
    {{ mode }}
    export default { // ... data() { return { activeSwatch: 0, colorModes: ['hex', 'rgb', 'hsl'] } } }
    
    Good! Let’s move on.
    
    As with the swatches, we want the first mode to be set as active. We can copy the test we wrote and adapt it to this new use case.
    
    

    test('sets the first mode as the selected one by default', () => {
    const firstButton = wrapper.find('.color-mode')
    expect(firstButton.classes()).toContain('active')
    })

    
    We can make this test pass by manually adding the class on the first list item.
    
    

    <button
    :key="index"
    v-for="(mode, index) in colorModes"
    class="color-mode"
    :class="[{ active: index === 0 }, color-mode-${mode}]"

    {{ mode }}

    
    Finally, we can refactor by externalizing the index onto which the class applies.
    
    
    {{ mode }} export default { // ... data() { return { activeSwatch: 0, activeMode: 0, colorModes: ['hex', 'rgb', 'hsl'] } } }
    
    We need to change the active mode whenever the end user clicks the associated button, as with the swatches.
    
    

    test('sets the color mode button as active when clicked', () => {
    const targetButton = wrapper.findAll('.color-mode').at(2)
    targetButton.trigger('click')
    expect(targetButton.classes()).toContain('active')
    })

    
    We can now add a ```@click``` directive as we did with the swatches, and make the test go green without having to refactor.
    
    

    <button
    :key="index"
    v-for="(mode, index) in colorModes"
    class="color-mode"
    :class="[{ active: index === activeMode }, color-mode-${mode}]"
    @click="activeMode = index"

    {{ mode }}

    ## 
    
    ## Testing the color code
    
    
    
    
    Now that we’re done testing the swatches and color code, we can move on to the third and final element of our color picker: **the color code**. What we display in there is a combination of the other two: the selected swatch defines the color we should display, and the selected mode determines how to display it.
    
    First, we want to make sure we initially display the default swatch in the default mode. We have the information to build this since we’ve implemented the swatches and the color mode.
    
    Let’s start with a (failing) test.
    
    

    describe('Color code', () => {
    test('displays the default swatch in the default mode', () => {
    expect(wrapper.find('.color-code').text()).toEqual('#e3342f')
    })
    })

    
    Now, let’s make this pass by hardcoding the expected result in the component.
    
    
    #e3342f
    
    Good! Time to refactor. We have a raw color in hexadecimal mode, and we’re willing to output it in hexadecimal format. The only difference between our input and output values is that we want to prepend the latter with a hash character. The easiest way of doing so with Vue is via a ```computed``` property.
    
    
    {{ activeCode }}
    export default { // ... computed: { activeCode() { return `#${this.swatches[this.activeSwatch]}` } } }
    
    This should keep the test green. However, there’s an issue with this computed property: it only works for hexadecimal values. It should keep on working when we change the color, but not when we change the mode. We can verify this with another test.
    
    

    test('displays the code in the right mode when changing mode', () => {
    wrapper.find('.color-mode-hsl').trigger('click')
    expect(wrapper.find('.color-code').text()).toEqual('2°, 76%, 54%')
    })

    
    Here, we’ve changed to HSL mode, but we’re still getting the hexadecimal output. We need to refactor our code so that our ```activeCode``` computed property is not only aware of the current color, but also the current color mode. One way we can achieve this is to create computed properties for each mode and proxy them through ```activeCode``` based on the selected mode.
    
    First, we should simplify access to the current color and mode. Right now, we need to do an array lookup, which is repetitive and makes the code hard to read. We can use computed properties to wrap that logic.
    
    

    export default {
    // ...
    computed: {
    // ...
    activeColorValue() {
    return this.swatches[this.activeSwatch]
    },
    activeModeValue() {
    return this.colorModes[this.activeMode]
    }
    }
    }

    
    As you can see, we’re not writing tests for these computed properties, as they aren’t part of our public API. We’ll use them later in our dedicated color mode computed properties, which themselves will be proxied in ```activeCode```, which we’re testing in our “Color code” suite. **All we care about is that the color code renders as expected** so that the user can rely on them. How we get there are implementation details that we need to be able to change if need be.
    
    We can now write our dedicated computed properties for each mode. We’ll map their name onto the ones in ```colorModes```, so we can do an array lookup later in ```activeCode``` to return the right one.
    
    For the hexadecimal output, we can externalize what we currently have in ```activeCode``` and refactor it using ```activeColorValue```.
    
    

    export default {
    // ...
    computed: {
    // ...
    hex() {
    return #${this.activeColorValue}
    }
    }
    }

    
    Now, let’s modify ```activeCode``` so it proxies the right computed property depending on the active mode.
    
    

    export default {
    // ...
    computed: {
    // ...
    activeCode() {
    return this[this.activeModeValue]
    }
    }
    }

    
    This still shouldn’t make our latest test pass, since we haven’t written a computed property for it. However, our test that checks if the default mode renders correctly is still passing, which is a good sign we’re on the right track.
    
    We now want to write a computed property that returns the color output in HSL mode. For this, we’ll use ```color-convert```, an npm package that lets us convert colors in many different modes. We’ve already been using it in our tests, so we don’t have to reinstall it.
    
    

    import convert from 'color-convert'
    export default {
    // ...
    computed: {
    // ...
    hsl() {
    const hslColor = convert.hex.hsl(this.activeColorValue)
    return ${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%
    }
    }
    }

    
    Great, our test passes! We can now finish this up adding the missing RGB mode.
    
    Yet, as you can see, we’re currently not testing the output of our color computed properties in isolation, but through other tests. To make things cleaner, we could decouple that logic from the component, import it as a dependency, and test it separately. This has several benefits:
    * it keeps the component from growing every time we want to add a color mode,
    * it keeps domains separated: the component focuses on its own view logic, and the color modes utility takes care of testing each mode exhaustively.
    
    First, create a new ```color.js``` file in the ```src/utils/``` directory, and a matching spec file in ```tests/unit/```.
    
    

    // color.spec.js
    import { rgb, hex, hsl } from '@/utils/color'
    // color.js
    import convert from 'color-convert'
    export const rgb = () => {}
    export const hex = () => {}
    export const hsl = () => {}

    
    We can use TDD to test those three functions and make sure they always return the expected value. We can extract the logic we had in our Vue component for the last two, and write the RGB function from scratch.
    
    For the sake of brevity, we’ll cover all three tests at once, but the process remains the same.
    
    

    import { rgb, hex, hsl } from '@/utils/color'
    const color = 'e3342f'
    describe('color', () => {
    test('returns the color into RGB notation', () => {
    expect(rgb(color)).toBe('227, 52, 47')
    })
    test('returns the color into hexadecimal notation', () => {
    expect(hex(color)).toBe('#e3342f')
    })
    test('returns the color into HSL notation', () => {
    expect(hsl(color)).toBe('2°, 76%, 54%')
    })
    })

    
    We now have three failing tests. The first thing we can do is to return hardcoded values to go green.
    
    

    export const rgb = () => '227, 52, 47'
    export const hex = () => '#e3342f'
    export const hsl = () => '2°, 76%, 54%'

    
    Now, we can start refactoring by migrating the code from our Vue component.
    
    

    export const hex = () => #${color}
    export const hsl = color => {
    const hslColor = convert.hex.hsl(color)
    return ${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%
    }

    
    Finally, we can implement our ```rgb``` function.
    
    

    export const rgb = color => convert.hex.rgb(color).join(', ')

    
    All tests should stay green!
    
    We can now use the ```color``` utilities in our Vue component and refactor it a bit. We no longer need to import ```color-convert``` in the component, nor do we need dedicated computed properties for each mode, or even for getting the active color and mode values. All we need to keep is ```activeCode```, where we can store all the necessary logic.
    
    This is a good example where doing black box testing helps us: we’ve been focusing on testing the public API; thus **we can refactor the internals of our component without breaking the tests**. Removing properties like ```activeColorValue``` or ```hex``` doesn’t matter, because we were never testing them directly.
    
    

    // ...
    import { rgb, hex, hsl } from '@/utils/color'
    const modes = { rgb, hex, hsl }
    export default {
    // ...
    computed: {
    activeCode() {
    const activeColor = this.swatches[this.activeSwatch]
    const activeMode = this.colorModes[this.activeMode]
    return modesactiveMode
    }
    }
    }

    
    We now have much terser code in our component, and better domain separation, while still respecting the component’s contract.
    
    Finally, we can implement a missing test: the one that ensures the color code changes whenever we click a new swatch. This should already go green, but it’s still essential for us to write it, so we can know about it if it breaks.
    
    

    test('displays the code in the right color when changing color', () => {
    wrapper
    .findAll('.swatch')
    .at(2)
    .trigger('click')
    expect(wrapper.find('.color-code').text()).toEqual('#f6993f')
    })

    
    And we’re done! We just built a fully functional Vue component using TDD, without relying on browser output, **and our tests are ready**.
    
    
    
    ## Visual control
    
    
    
    
    Now that our component is ready, we can see how it looks and play with it in the browser. This allows us to add the CSS and ensure we didn’t miss out on anything.
    
    First, mount the component into the main ```App.vue``` file.
    
    
    
    Then, run the app by executing the following script, and open it in your browser at ```<a href="http://localhost:8080/" target="_blank">http://localhost:8080/</a>```.
    
    

    npm run serve

    
    You should see your color picker! It doesn’t look like much for now, but it works. Try clicking colors and change the color mode; you should see the color code change.
    
    To see the component with proper styling, add the following CSS between the ```style``` tags:
    
    

    .color-picker {
    background-color: #fff;
    border: 1px solid #dae4e9;
    border-radius: 0.125rem;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
    color: #596a73;
    font-family: BlinkMacSystemFont, Helvetica Neue, sans-serif;
    padding: 1rem;
    }
    .swatches {
    color: #fff;
    display: flex;
    flex-wrap: wrap;
    list-style: none;
    margin: -0.25rem -0.25rem 0.75rem;
    padding: 0;
    }
    .swatch {
    border-radius: 0.125rem;
    cursor: pointer;
    height: 2rem;
    margin: 0.25rem;
    position: relative;
    width: 2rem;
    }
    .swatch::after {
    border-radius: 0.125rem;
    bottom: 0;
    box-shadow: inset 0 0 0 1px #dae4e9;
    content: '';
    display: block;
    left: 0;
    mix-blend-mode: multiply;
    position: absolute;
    right: 0;
    top: 0;
    }
    .swatch svg {
    display: none;
    color: #fff;
    fill: currentColor;
    margin: 0.5rem;
    }
    .swatch.active svg {
    display: block;
    }
    .color-modes {
    display: flex;
    font-size: 1rem;
    letter-spacing: 0.05rem;
    margin: 0 -0.25rem 0.75rem;
    }
    .color-mode {
    background: none;
    border: none;
    color: #9babb4;
    cursor: pointer;
    display: block;
    font-weight: 700;
    margin: 0 0.25rem;
    padding: 0;
    text-transform: uppercase;
    }
    .color-mode.active {
    color: #364349;
    }
    .color-code {
    border: 1px solid #dae4e9;
    border-radius: 0.125rem;
    color: #364349;
    text-transform: uppercase;
    padding: 0.75rem;
    }

    
    You should see something like this:
    
    ![](https://cdn-images-1.medium.com/max/640/0*e2w8W0MplRF7UPdc.gif)
    
    And we’re done!
    
    
    
    ## Afterthoughts
    #### How can we improve this?
    
    For now, we have a robust test suite. Even though we don’t have 100% coverage, we can feel confident with our component going out in the wild, and evolving over time. There are still a couple of things we could improve though, depending on the use case.
    
    First, you may notice that when clicking the white swatch, the checkmark doesn’t show up. That’s not a bug, rather a visual issue: the checkmark is there, but we can’t see it because it’s white on white. You could add a bit of logic to fix this: when a color is lighter than a certain threshold (let’s say 90%), you could add a ```light``` class on the swatch. This would then let you apply some specific CSS and make the checkmark dark.
    
    Fortunately, you already have all you need: the ```color-converter``` package can help you determine whether a color is light (with the HSL utilities), and you already have a ```color``` utility module to store that logic and test it in isolation. To see what the finished code could look like, check out the project’s repository on [GitHub](https://github.com/sarahdayan/colorpicker-tdd-tutorial "GitHub").
    
    We could also reinforce the suite by adding a few tests to make sure some expected classes are there. This doesn’t test actual logic, but would still be particularly useful if someone was relying on those class names to style the component from the outside. Again, everything depends on your use case: test what shouldn’t change without you knowing, don’t only add tests for the sake of it.
    
    
    
    ## What did we learn?
    
    
    
    
    There are several lessons to learn from this TDD experiment. It brings a lot to the table but also highlights a few challenges that we should be aware of.
    
    First, TDD is a **fantastic way to write robust tests**, not too many and not too few. Have you ever finished a component, moved on to tests and thought *“where do I even start?”*? Looking at finished code and figuring out what to test is hard. It’s tempting to get it done quickly, overlook some critical parts and end up with an incomplete test suite. Or you can adopt a defensive approach and test everything, risking to focus on implementation details and writing brittle tests.
    
    Adopting TDD for developing UI components helps us focus on exactly what to test by **defining, before writing any line of code, if this is part of the contract or not**.
    
    Secondly, **TDD encourages refactors, leading to better software design**. When you’re writing tests after coding, you’re usually no longer in a refactoring dynamic. You can fix your code if you find issues while testing, but at this stage, you’re most likely done with the implementation. **This separation between writing code and writing test is where lies the issue.**
    
    With TDD, **you’re creating a deeper connection between code and tests, with a strong focus on making the public API reliable**. Implementation comes right after you’ve guaranteed the outcome. This is why the *green* step is critical: you first need your test to pass, then ensure it never breaks. Instead of implementing your way to a working solution, you’re reversing the relationship, focusing on the contract first, and allowing the implementation to remain disposable. Because refactoring comes last, and you’ve established the contract, you now have mental space to make things right, clean some code, adopt a better design, or focus on performance.
    
    It’s worth noting that **TDD is much easier to follow with specs**. When you already have a clear overview of everything the component should do, you can translate those specifications into tests. Some teams use frameworks like [ATDD](https://en.wikipedia.org/wiki/Acceptance_test%E2%80%93driven_development "ATDD") (acceptance test–driven development), where the involved parties develop specifications from a business perspective. The final specs, or acceptance tests, are a perfect base to write tests following TDD.
    
    On the other hand, going with TDD to test UI components can be difficult at first, and require some prior knowledge before diving into it. For starters, **you need to have good knowledge of your testing libraries** so that you can write reliable assertions. Look at the test we wrote with a regular expression: the syntax is not the most straightforward. If you don’t know the library well, it’s easy to write a test that fails for the wrong reasons, which would end up hindering the whole TDD process.
    
    Similarly, you need to be aware of some details regarding the values you expect; otherwise, you could end up battling with your tests and doing some annoying back-and-forths. On that matter, UI components are more challenging than renderless libraries, because of the various ways the DOM specifications can be implemented.
    
    Take the first test of our suite for example: we’re testing background colors. However, even though we’re passing hexadecimal colors, we’re expecting RGB return values. That’s because Jest uses [jsdom](https://github.com/jsdom/jsdom "jsdom"), a Node.js implementation of the DOM and HTML standards. If we were running our tests in a specific browser, we might have a different return value. This can be tricky when you’re testing different engines. You may have to seek some more advanced conversion utilities or use environment variables to handle the various implementations.
    ## Is it worth it?
    
    
    
    
    If you made it this far, you’ve probably realized that **TDD demands time**. This article itself is over 6,000 words! This can be a bit scary if you’re used to faster development cycles, and probably looks impossible if you’re often working under pressure. However, it’s important to bust the myth that TDD would somehow double development time for little return on investment, because this is entirely false.
    
    TDD requires some practice, and you’ll get faster over time. What feels clumsy today can become a second nature tomorrow, if you do it regularly. I encourage you not to discard something because it’s new and feels awkward: give it some time to assess it fairly, then take a decision.
    
    Secondly, **time spent on writing test-driven code is time you won’t spend fixing bugs**.
    
    Fixing bugs is far more costly than preventing them. If you’ve ever had to fix critical production bugs, you know this feels close to holding an open wound on a surgical patient with one hand, while trying to operate with the other one. In the desert. At night. With a Swiss Army knife. It’s messy, stressful, suboptimal, and bears high chances of screwing up something else in the process. If you want to preserve your sanity and the trust your end users have in your software, **you want to avoid those situations at all costs**.
    
    
    
    
    ![](https://cdn-images-1.medium.com/max/640/0*-ypCMc0eow3xfIdm.gif)
    
    Tests help you catch bugs before they make it to production, and TDD helps you write better tests. **If you think you should test your software, then you should care about making these tests useful in the first place.** Otherwise, the whole thing is only a waste of time.
    
    As with anything, I encourage you to try TDD before discarding the idea. If you’re consistently encountering production issues, or you think you could improve your development process, then it’s worth giving it a shot. **Try it for a limited amount of time, measure the impact, and compare the results.** You may discover a method that helps you ship better software, and feel more confident about hitting the “Deploy” button.
    
    **Thanks for reading** ❤
    
    If you liked this post, share it with all of your programming buddies!
    
    Follow us on [**Facebook**](https://www.facebook.com/vuejstutorial "**Facebook**") | [**Twitter**](https://twitter.com/moriohdotcom "**Twitter**")
    ### Learn More
    
    ☞ [Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)](http://learnstartup.net/p/BJBa7-l-g "Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)")
    
    ☞ [Nuxt.js - Vue.js on Steroids](http://learnstartup.net/p/ryWiRu5qz "Nuxt.js - Vue.js on Steroids")
    
    ☞ [Build Web Apps with Vue JS 2 & Firebase](http://learnstartup.net/p/r1IF4NTpM "Build Web Apps with Vue JS 2 & Firebase")
    
    ☞ [Front-end Developer Handbook 2019](http://on.geeklearn.net/38b3800bb9 "Front-end Developer Handbook 2019")
    
    ☞ [ES Module Browser Build in Vue](http://tech.learn4startup.com/eae8ea9ece "ES Module Browser Build in Vue")
    
    ☞ [Implementing Authentication in a Nuxt.js App](http://tech.learn4startup.com/4082d07f9f "Implementing Authentication in a Nuxt.js App")
    
    ☞ [Getting Started with Vuex: Managing State in Vue.js](http://tech.edupioneer.net/6e329fcdee "Getting Started with Vuex: Managing State in Vue.js")
    
    ☞ [Build a Server-Side Rendered Vue App with Nuxt.js](http://on.geeklearn.net/af342a0d69 "Build a Server-Side Rendered Vue App with Nuxt.js")
    
    ☞ [React vs. Vue vs. Angular](http://tech.edupioneer.net/51a9b27b79 "React vs. Vue vs. Angular")
    
    ☞ [Getting up and Running with the Vue.js 2.0 Framework](http://on.edupioneer.net/4e3020cd5b "Getting up and Running with the Vue.js 2.0 Framework")
    
    ☞ [Hands-on Vue.js for Beginners](http://tech.edupioneer.net/5c942093ff "Hands-on Vue.js for Beginners")
    
    ☞ [Vue CLI 3 Full-Stack App Structure](http://on.geeklearn.net/f877e930ab "Vue CLI 3 Full-Stack App Structure")
    
    *Originally published on *[*https://medium.freecodecamp.org*](https://medium.freecodecamp.org/an-introduction-to-tdd-with-vue-js-66544710b50c "*https://medium.freecodecamp.org*")
    : '<rootDir>/svgTransform.js'
      },
      // ...
    }
    
    

    Note that we’ve removed “svg” from the first regular expression (the one that gets transformed with jest-transform-stub). This way, we ensure SVGs get picked up by svgTransform.js.

    Additionally, you need to install color-convert as a dependency. We’ll need it both in our code and in our tests later on.

    Don’t serve the project yet. We’re going to write tests and rely on them passing or not to move on. We don’t want to control whether what we build works by testing it visually in the browser, nor being distracted by how it looks.

    Instead, open your project and create a new ColorPicker.vue single-file component in the src/components/ directory. In tests/unit/, create its associated spec file.

    <!-- ColorPicker.vue -->
    <template>
      <div></div>
    </template>
    <script>
    export default {}
    </script>
    <style>
    </style>
    // ColorPicker.spec.js
    import { shallowMount } from '@vue/test-utils'
    import ColorPicker from '@/components/ColorPicker'
    describe('ColorPicker', () => {
      // let's do this!
    })
    
    

    In your terminal, execute the following command to run tests:

    npm run test:unit --watchAll
    
    

    For now, you should get an error because you don’t yet have tests. Don’t worry though; we’ll fix this shortly 🙂 Note the usage of the --watchAll flag in the command: Jest is now watching your files. This way, you won’t have to re-run test by hand.

    TDD goes in 3 stages:

    1. Red: you write a test that describes an expected behavior, then you run it, ensuring it fails.
    2. Green: you write the dumbest, most straightforward code you can to make the test pass.
    3. Refactor: you refactor the code to make it right.
    Step 1: Red

    Time to write our first test! We’ll start with the color swatches. For clarity, we’ll wrap all tests for each distinct element in their own suite, using a describe block.

    First, we want to make sure that the component displays each color that we provide as an individual swatch. We would pass those as props, in the form of an array of hexadecimal strings. In the component, we would display the list as an unordered list, and assign the background color via a style attribute.

    import { shallowMount } from '@vue/test-utils'
    import ColorPicker from '@/components/ColorPicker'
    import convert from 'color-convert'
    let wrapper = null
    const propsData = {
      swatches: ['e3342f', '3490dc', 'f6993f', '38c172', 'fff']
    }
    beforeEach(() => (wrapper = shallowMount(ColorPicker, { propsData })))
    afterEach(() => wrapper.destroy())
    describe('ColorPicker', () => {
      describe('Swatches', () => {
        test('displays each color as an individual swatch', () => {
          const swatches = wrapper.findAll('.swatch')
          propsData.swatches.forEach((swatch, index) => {
            expect(swatches.at(index).attributes().style).toBe(
              `background: rgb(${convert.hex.rgb(swatch).join(', ')})`
            )
          })
        })
      })
    })
    
    

    We mounted our ColorPicker component and wrote a test that expects to find items with a background color matching the colors passed as props. This test is bound to fail: we currently have nothing in ColorPicker.vue. If you look at your terminal, you should have an error saying that no item exists at 0. This is great! We just passed the first step of TDD with flying colors.

    Step 2: Green

    Our test is failing; we’re on the right track. Now, time to make it pass. We’re not much interested in writing working or smart code at this point, all we want is to make Jest happy. Right now, Vue Test Utils complains about the fact that we don’t event have no item at index 0.

    [vue-test-utils]: no item exists at 0
    
    

    The simplest thing we can do to make that error go away is to add an unordered list with a swatch class on the list item.

    <template>
      <div class="color-picker">
        <ul class="swatches">
          <li class="swatch"></li>
        </ul>
      </div>
    </template>
    
    

    Jest still complains but the error has changed:

    Expected value to equal:
      "background: rgb(227, 52, 47);"
    Received:
      undefined
    
    

    This makes sense; the list item doesn’t have a style attribute. The simplest thing we can do about it is to hardcode the style attribute. This isn’t what we want in the end, but, we aren’t concerned about it yet. What we want is for our test to go green.

    We can therefore hardcode five list items with the expected style attributes:

    <ul class="swatches">
      <li class="swatch" style="background: rgb(227, 52, 47);"></li>
      <li class="swatch" style="background: rgb(52, 144, 220);"></li>
      <li class="swatch" style="background: rgb(246, 153, 63);"></li>
      <li class="swatch" style="background: rgb(56, 193, 114);"></li>
      <li class="swatch" style="background: rgb(255, 255, 255);"></li>
    </ul>
    
    

    The test should now pass.

    Step 3: Refactor

    At this stage, we want to rearrange our code to make it right, without breaking tests. In our case, we don’t want to keep the list items and their style attributes hardcoded. Instead, it would be better to receive swatches as a prop, iterate over them to generate the list items, and assign the colors as their background.

    <template>
      <div class="color-picker">
        <ul class="swatches">
          <li
            :key="index"
            v-for="(swatch, index) in swatches"
            :style="{ background: `#${swatch}` }"
            class="swatch"
          ></li>
        </ul>
      </div>
    </template>
    <script>
    export default {
      props: {
        swatches: {
          type: Array,
          default() {
            return []
          }
        }
      }
    }
    </script>
    
    

    When tests re-run, they should still pass 🥳 This means we’ve successfully refactored the code without affecting the output. Congratulations, you’ve just completed your first TDD cycle!

    Now, before we go to the next test, let’s reflect a bit. You may be wondering:

    “Isn’t this a bit dumb? I knew the test would fail. Am I not wasting time by running it anyway, then hardcoding the right value, see the test pass, then make the code right? Can’t I go to the refactor step directly?”
    It’s understandable that you’re feeling confused by the process. Yet, try to look at things from a different angle: the point here isn’t to prove that the test doesn’t pass. We know it won’t. What we want to look at is what our test expects, make them happy in the simplest possible way, and finally write smarter code without breaking anything.

    That’s the whole idea of test-driven development: we don’t write code to make things work, we write code to make tests pass. By reversing the relationship, we’re ensuring robust tests with a focus on the outcome.

    What are we testing?

    Another question that may come to mind is how we’re deciding what to test. In Unit Test Your First Vue.js Component, we saw that we should only be testing the public **API **of our component, not the internal implementation. Strictly speaking, this means we should cover user interactions and props changes.

    But is that all? For example, is it okay for the output **HTML **to break? Or for **CSS **class names to change? Are we sure nobody is relying on them? That you aren’t yourself?

    Tests should give you confidence that you aren’t shipping broken software. What people can do with your program shouldn’t stop working the way they expect it to work. It can mean different things depending on the project and use case.

    For example, if you’re building this color panel as an open source component, your users are other developers who use it in their own projects. They’re likely relying on the class names you provide to style the component to their liking. The class names become a part of your public API because your users rely on them.

    In our case, we may not necessarily be making an open source component, but we have view logic that depends on specific class names. For instance, it’s important for active swatches to have an active class name, because we’ll rely on it to display a checkmark, in CSS. If someone changes this by accident, we want to know about it.

    Testing scenarios for UI components highly depend on the use case and expectations. Whichever the case, what you need to ask yourself is do I care about this if it changes?

    Next tests

    Testing the swatches

    Let’s move on to the next test. We expect the first swatch of the list to be the one that’s selected by default. From the outside, this is something that we want to ensure keeps on working the same way. Users could, for instance, rely on the active class name to style the component.

    test('sets the first swatch as the selected one by default', () => {
      const firstSwatch = wrapper.find('.swatch')
      expect(firstSwatch.classes()).toContain('active')
    })
    
    

    This test, too, should fail, as list items currently don’t have any classes. We can easily make this pass by adding the class on the first list item.

    <li
      :key="index"
      v-for="(swatch, index) in swatches"
      :style="{ background: `#${swatch}` }"
      class="swatch"
      :class="{ 'active': index === 0 }"
    ></li>
    
    

    The test now passes; however, we’ve hardcoded the logic into the template. We can refactor that by externalizing the index onto which the class applies. This way, we can change it later.

    <template>
      <!-- ... -->
      <li
        :key="index"
        v-for="(swatch, index) in swatches"
        :style="{ background: `#${swatch}` }"
        class="swatch"
        :class="{ active: index === activeSwatch }"
      ></li>
      <!-- ... -->
    </template>
    export default {
      // ...
      data() {
        return {
          activeSwatch: 0
        }
      }
    }
    
    

    This naturally leads us to our third test. We want to change the active swatch whenever the end user clicks it.

    test('makes the swatch active when clicked', () => {
      const targetSwatch = wrapper.findAll('.swatch').at(2)
      targetSwatch.trigger('click')
      expect(targetSwatch.classes()).toContain('active')
    })
    
    

    For now, nothing happens when we click a swatch. However, thanks to our previous refactor, we can make this test go green and even skip the refactor step.

    <li
      :key="index"
      v-for="(swatch, index) in swatches"
      :style="{ background: `#${swatch}` }"
      class="swatch"
      :class="{ active: index === activeSwatch }"
      @click="activeSwatch = index"
    ></li>
    
    

    This code makes the test pass and doesn’t even need a refactor. This is a fortunate side-effect of doing TDD: sometimes, the process leads to either writing new tests that either don’t need refactors, or even that pass right away.

    Active swatches should show a checkmark. We’ll add it now without writing a test: instead, we’ll control their visibility via CSS later. This is alright since we’ve already tested how the active class applies.

    First, create a checkmark.svg file in src/assets/.

    <svg viewBox="0 0 448.8 448.8">
      <polygon points="142.8 323.9 35.7 216.8 0 252.5 142.8 395.3 448.8 89.3 413.1 53.6"/>
    </svg>
    
    

    Then, import it in the component.

    import CheckIcon from '@/assets/check.svg'
    export default {
      // ...
      components: { CheckIcon }
    }
    
    

    Finally, add it inside the list items.

    <li ... >
      <check-icon />
    </li>
    
    

    Good! We can now move on to the next element of our component: the color mode.

    Testing the color mode

    Let’s now implement the color mode toggler. The end user should be able to switch between hexadecimal, RGB and HSL. We’re defining these modes internally, but we want to ensure they render correctly.

    Instead of testing button labels, we’ll rely on class names. It makes our test more robust, as we can easily define a class name as part of our component’s contract. However, button labels should be able to change.

    Now you may be tempted to check for these three specific modes, but that would make the test brittle. What if we change them? What if we add one, or remove one? That would still be the same logic, yet the test would fail, forcing us to go and edit it.

    One solution could be to access the component’s data to iterate on the modes dynamically. Vue Test Utils lets us do that through the vm property, but again, this tightly couples our test with the internal implementation of the modes. If tomorrow, we decided to change the way we define modes, the test would break.

    Another solution is to keep going with black box testing and only expect the class name to match a given pattern. We don’t care that it’s color-mode-hex, color-mode-hsl or color-mode-xyz, as long as it looks like what we expect from the outside. Jest lets us do that with regular expression matchers.

    // ...
    describe('Color model', () => {
      test('displays each mode as an individual button', () => {
        const buttons = wrapper.findAll('.color-mode')
        buttons.wrappers.forEach(button => {
          expect(button.classes()).toEqual(
            expect.arrayContaining([expect.stringMatching(/color-mode-\w{1,}/)])
          )
        })
      })
    })
    
    

    Here, we’re expecting elements with a class that follows the pattern “color-mode-“ + any word character (in ECMAScript, any character within [a-zA-Z_0-9]). We could add or remove any mode we want, and the test would still be valid.

    Naturally, right now, the test should fail, as there are no buttons with class color-mode yet. We can make it pass by hardcoding them in the component.

    <div class="color-modes">
      <button class="color-mode color-mode-hex"></button>
      <button class="color-mode color-mode-rgb"></button>
      <button class="color-mode color-mode-hsl"></button>
    </div>
    
    

    We can now refactor this code by adding the modes as private data in our component and iterate over them.

    <template>
      <!-- ... -->
      <div class="color-modes">
        <button
          :key="index"
          v-for="(mode, index) in colorModes"
          class="color-mode"
          :class="`color-mode-${mode}`"
        >{{ mode }}</button>
      </div>
      <!-- ... -->
    </template>
    export default {
      // ...
      data() {
        return {
          activeSwatch: 0,
          colorModes: ['hex', 'rgb', 'hsl']
        }
      }
    }
    
    

    Good! Let’s move on.

    As with the swatches, we want the first mode to be set as active. We can copy the test we wrote and adapt it to this new use case.

    test('sets the first mode as the selected one by default', () => {
      const firstButton = wrapper.find('.color-mode')
      expect(firstButton.classes()).toContain('active')
    })
    
    

    We can make this test pass by manually adding the class on the first list item.

    <button
      :key="index"
      v-for="(mode, index) in colorModes"
      class="color-mode"
      :class="[{ active: index === 0 }, `color-mode-${mode}`]"
    >{{ mode }}</button>
    
    

    Finally, we can refactor by externalizing the index onto which the class applies.

    <template>
      <!-- ... -->
      <button
        :key="index"
        v-for="(mode, index) in colorModes"
        class="color-mode"
        :class="[{ active: index === activeMode }, `color-mode-${mode}`]"
      >{{ mode }}</button>
      <!-- ... -->
    </template>
    export default {
      // ...
      data() {
        return {
          activeSwatch: 0,
          activeMode: 0,
          colorModes: ['hex', 'rgb', 'hsl']
        }
      }
    }
    
    

    We need to change the active mode whenever the end user clicks the associated button, as with the swatches.

    test('sets the color mode button as active when clicked', () => {
      const targetButton = wrapper.findAll('.color-mode').at(2)
      targetButton.trigger('click')
      expect(targetButton.classes()).toContain('active')
    })
    
    

    We can now add a @click directive as we did with the swatches, and make the test go green without having to refactor.

    <button
      :key="index"
      v-for="(mode, index) in colorModes"
      class="color-mode"
      :class="[{ active: index === activeMode }, `color-mode-${mode}`]"
      @click="activeMode = index"
    >{{ mode }}</button>
    
    
    Testing the color code

    Now that we’re done testing the swatches and color code, we can move on to the third and final element of our color picker: the color code. What we display in there is a combination of the other two: the selected swatch defines the color we should display, and the selected mode determines how to display it.

    First, we want to make sure we initially display the default swatch in the default mode. We have the information to build this since we’ve implemented the swatches and the color mode.

    Let’s start with a (failing) test.

    describe('Color code', () => {
      test('displays the default swatch in the default mode', () => {
        expect(wrapper.find('.color-code').text()).toEqual('#e3342f')
      })
    })
    
    

    Now, let’s make this pass by hardcoding the expected result in the component.

    <div class="color-code">#e3342f</div>
    
    

    Good! Time to refactor. We have a raw color in hexadecimal mode, and we’re willing to output it in hexadecimal format. The only difference between our input and output values is that we want to prepend the latter with a hash character. The easiest way of doing so with Vue is via a computed property.

    <template>
      <!-- ... -->
      <div class="color-code">{{ activeCode }}</div>
      <!-- ... -->
    </template>
    export default {
      // ...
      computed: {
        activeCode() {
          return `#${this.swatches[this.activeSwatch]}`
        }
      }
    }
    
    

    This should keep the test green. However, there’s an issue with this computed property: it only works for hexadecimal values. It should keep on working when we change the color, but not when we change the mode. We can verify this with another test.

    test('displays the code in the right mode when changing mode', () => {
      wrapper.find('.color-mode-hsl').trigger('click')
      expect(wrapper.find('.color-code').text()).toEqual('2°, 76%, 54%')
    })
    
    

    Here, we’ve changed to HSL mode, but we’re still getting the hexadecimal output. We need to refactor our code so that our activeCode computed property is not only aware of the current color, but also the current color mode. One way we can achieve this is to create computed properties for each mode and proxy them through activeCode based on the selected mode.

    First, we should simplify access to the current color and mode. Right now, we need to do an array lookup, which is repetitive and makes the code hard to read. We can use computed properties to wrap that logic.

    export default {
      // ...
      computed: {
        // ...
        activeColorValue() {
          return this.swatches[this.activeSwatch]
        },
        activeModeValue() {
          return this.colorModes[this.activeMode]
        }
      }
    }
    
    

    As you can see, we’re not writing tests for these computed properties, as they aren’t part of our public API. We’ll use them later in our dedicated color mode computed properties, which themselves will be proxied in activeCode, which we’re testing in our “Color code” suite. All we care about is that the color code renders as expected so that the user can rely on them. How we get there are implementation details that we need to be able to change if need be.

    We can now write our dedicated computed properties for each mode. We’ll map their name onto the ones in colorModes, so we can do an array lookup later in activeCode to return the right one.

    For the hexadecimal output, we can externalize what we currently have in activeCode and refactor it using activeColorValue.

    export default {
      // ...
      computed: {
        // ...
        hex() {
          return `#${this.activeColorValue}`
        }
      }
    }
    
    

    Now, let’s modify activeCode so it proxies the right computed property depending on the active mode.

    export default {
      // ...
      computed: {
        // ...
        activeCode() {
          return this[this.activeModeValue]
        }
      }
    }
    
    

    This still shouldn’t make our latest test pass, since we haven’t written a computed property for it. However, our test that checks if the default mode renders correctly is still passing, which is a good sign we’re on the right track.

    We now want to write a computed property that returns the color output in HSL mode. For this, we’ll use color-convert, an npm package that lets us convert colors in many different modes. We’ve already been using it in our tests, so we don’t have to reinstall it.

    import convert from 'color-convert'
    export default {
      // ...
      computed: {
        // ...
        hsl() {
          const hslColor = convert.hex.hsl(this.activeColorValue)
          return `${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%`
        }
      }
    }
    
    

    Great, our test passes! We can now finish this up adding the missing RGB mode.

    Yet, as you can see, we’re currently not testing the output of our color computed properties in isolation, but through other tests. To make things cleaner, we could decouple that logic from the component, import it as a dependency, and test it separately. This has several benefits:

    • it keeps the component from growing every time we want to add a color mode,
    • it keeps domains separated: the component focuses on its own view logic, and the color modes utility takes care of testing each mode exhaustively.

    First, create a new color.js file in the src/utils/ directory, and a matching spec file in tests/unit/.

    // color.spec.js
    import { rgb, hex, hsl } from '@/utils/color'
    // color.js
    import convert from 'color-convert'
    export const rgb = () => {}
    export const hex = () => {}
    export const hsl = () => {}
    
    

    We can use TDD to test those three functions and make sure they always return the expected value. We can extract the logic we had in our Vue component for the last two, and write the RGB function from scratch.

    For the sake of brevity, we’ll cover all three tests at once, but the process remains the same.

    import { rgb, hex, hsl } from '@/utils/color'
    const color = 'e3342f'
    describe('color', () => {
      test('returns the color into RGB notation', () => {
        expect(rgb(color)).toBe('227, 52, 47')
      })
      test('returns the color into hexadecimal notation', () => {
        expect(hex(color)).toBe('#e3342f')
      })
      test('returns the color into HSL notation', () => {
        expect(hsl(color)).toBe('2°, 76%, 54%')
      })
    })
    
    

    We now have three failing tests. The first thing we can do is to return hardcoded values to go green.

    export const rgb = () => '227, 52, 47'
    export const hex = () => '#e3342f'
    export const hsl = () => '2°, 76%, 54%'
    
    

    Now, we can start refactoring by migrating the code from our Vue component.

    export const hex = () => `#${color}`
    export const hsl = color => {
      const hslColor = convert.hex.hsl(color)
      return `${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%`
    }
    
    

    Finally, we can implement our rgb function.

    export const rgb = color => convert.hex.rgb(color).join(', ')
    
    

    All tests should stay green!

    We can now use the color utilities in our Vue component and refactor it a bit. We no longer need to import color-convert in the component, nor do we need dedicated computed properties for each mode, or even for getting the active color and mode values. All we need to keep is activeCode, where we can store all the necessary logic.

    This is a good example where doing black box testing helps us: we’ve been focusing on testing the public API; thus we can refactor the internals of our component without breaking the tests. Removing properties like activeColorValue or hex doesn’t matter, because we were never testing them directly.

    // ...
    import { rgb, hex, hsl } from '@/utils/color'
    const modes = { rgb, hex, hsl }
    export default {
      // ...
      computed: {
        activeCode() {
          const activeColor = this.swatches[this.activeSwatch]
          const activeMode = this.colorModes[this.activeMode]
          return modes[activeMode](activeColor)
        }
      }
    }
    
    

    We now have much terser code in our component, and better domain separation, while still respecting the component’s contract.

    Finally, we can implement a missing test: the one that ensures the color code changes whenever we click a new swatch. This should already go green, but it’s still essential for us to write it, so we can know about it if it breaks.

    test('displays the code in the right color when changing color', () => {
      wrapper
        .findAll('.swatch')
        .at(2)
        .trigger('click')
      expect(wrapper.find('.color-code').text()).toEqual('#f6993f')
    })
    
    

    And we’re done! We just built a fully functional Vue component using TDD, without relying on browser output, and our tests are ready.

    Visual control

    Now that our component is ready, we can see how it looks and play with it in the browser. This allows us to add the CSS and ensure we didn’t miss out on anything.

    First, mount the component into the main App.vue file.

    <!-- App.vue -->
    <template>
      <div id="app">
        <color-picker :swatches="['e3342f', '3490dc', 'f6993f', '38c172', 'fff']"/>
      </div>
    </template>
    <script>
    import ColorPicker from '@/components/ColorPicker'
    export default {
      name: 'app',
      components: {
        ColorPicker
      }
    }
    </script>
    
    

    Then, run the app by executing the following script, and open it in your browser at <a href="http://localhost:8080/" target="_blank">http://localhost:8080/</a>.

    npm run serve
    
    

    You should see your color picker! It doesn’t look like much for now, but it works. Try clicking colors and change the color mode; you should see the color code change.

    To see the component with proper styling, add the following CSS between the style tags:

    .color-picker {
      background-color: #fff;
      border: 1px solid #dae4e9;
      border-radius: 0.125rem;
      box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
      color: #596a73;
      font-family: BlinkMacSystemFont, Helvetica Neue, sans-serif;
      padding: 1rem;
    }
    .swatches {
      color: #fff;
      display: flex;
      flex-wrap: wrap;
      list-style: none;
      margin: -0.25rem -0.25rem 0.75rem;
      padding: 0;
    }
    .swatch {
      border-radius: 0.125rem;
      cursor: pointer;
      height: 2rem;
      margin: 0.25rem;
      position: relative;
      width: 2rem;
    }
    .swatch::after {
      border-radius: 0.125rem;
      bottom: 0;
      box-shadow: inset 0 0 0 1px #dae4e9;
      content: '';
      display: block;
      left: 0;
      mix-blend-mode: multiply;
      position: absolute;
      right: 0;
      top: 0;
    }
    .swatch svg {
      display: none;
      color: #fff;
      fill: currentColor;
      margin: 0.5rem;
    }
    .swatch.active svg {
      display: block;
    }
    .color-modes {
      display: flex;
      font-size: 1rem;
      letter-spacing: 0.05rem;
      margin: 0 -0.25rem 0.75rem;
    }
    .color-mode {
      background: none;
      border: none;
      color: #9babb4;
      cursor: pointer;
      display: block;
      font-weight: 700;
      margin: 0 0.25rem;
      padding: 0;
      text-transform: uppercase;
    }
    .color-mode.active {
      color: #364349;
    }
    .color-code {
      border: 1px solid #dae4e9;
      border-radius: 0.125rem;
      color: #364349;
      text-transform: uppercase;
      padding: 0.75rem;
    }
    
    

    You should see something like this:

    And we’re done!

    Afterthoughts

    How can we improve this?

    For now, we have a robust test suite. Even though we don’t have 100% coverage, we can feel confident with our component going out in the wild, and evolving over time. There are still a couple of things we could improve though, depending on the use case.

    First, you may notice that when clicking the white swatch, the checkmark doesn’t show up. That’s not a bug, rather a visual issue: the checkmark is there, but we can’t see it because it’s white on white. You could add a bit of logic to fix this: when a color is lighter than a certain threshold (let’s say 90%), you could add a light class on the swatch. This would then let you apply some specific CSS and make the checkmark dark.

    Fortunately, you already have all you need: the color-converter package can help you determine whether a color is light (with the HSL utilities), and you already have a color utility module to store that logic and test it in isolation. To see what the finished code could look like, check out the project’s repository on GitHub.

    We could also reinforce the suite by adding a few tests to make sure some expected classes are there. This doesn’t test actual logic, but would still be particularly useful if someone was relying on those class names to style the component from the outside. Again, everything depends on your use case: test what shouldn’t change without you knowing, don’t only add tests for the sake of it.

    What did we learn?

    There are several lessons to learn from this TDD experiment. It brings a lot to the table but also highlights a few challenges that we should be aware of.

    First, TDD is a fantastic way to write robust tests, not too many and not too few. Have you ever finished a component, moved on to tests and thought “where do I even start?”? Looking at finished code and figuring out what to test is hard. It’s tempting to get it done quickly, overlook some critical parts and end up with an incomplete test suite. Or you can adopt a defensive approach and test everything, risking to focus on implementation details and writing brittle tests.

    Adopting TDD for developing UI components helps us focus on exactly what to test by defining, before writing any line of code, if this is part of the contract or not.

    Secondly, TDD encourages refactors, leading to better software design. When you’re writing tests after coding, you’re usually no longer in a refactoring dynamic. You can fix your code if you find issues while testing, but at this stage, you’re most likely done with the implementation. This separation between writing code and writing test is where lies the issue.

    With TDD, you’re creating a deeper connection between code and tests, with a strong focus on making the public API reliable. Implementation comes right after you’ve guaranteed the outcome. This is why the green step is critical: you first need your test to pass, then ensure it never breaks. Instead of implementing your way to a working solution, you’re reversing the relationship, focusing on the contract first, and allowing the implementation to remain disposable. Because refactoring comes last, and you’ve established the contract, you now have mental space to make things right, clean some code, adopt a better design, or focus on performance.

    It’s worth noting that TDD is much easier to follow with specs. When you already have a clear overview of everything the component should do, you can translate those specifications into tests. Some teams use frameworks like ATDD (acceptance test–driven development), where the involved parties develop specifications from a business perspective. The final specs, or acceptance tests, are a perfect base to write tests following TDD.

    On the other hand, going with TDD to test UI components can be difficult at first, and require some prior knowledge before diving into it. For starters, you need to have good knowledge of your testing libraries so that you can write reliable assertions. Look at the test we wrote with a regular expression: the syntax is not the most straightforward. If you don’t know the library well, it’s easy to write a test that fails for the wrong reasons, which would end up hindering the whole TDD process.

    Similarly, you need to be aware of some details regarding the values you expect; otherwise, you could end up battling with your tests and doing some annoying back-and-forths. On that matter, UI components are more challenging than renderless libraries, because of the various ways the DOM specifications can be implemented.

    Take the first test of our suite for example: we’re testing background colors. However, even though we’re passing hexadecimal colors, we’re expecting RGB return values. That’s because Jest uses jsdom, a Node.js implementation of the DOM and HTML standards. If we were running our tests in a specific browser, we might have a different return value. This can be tricky when you’re testing different engines. You may have to seek some more advanced conversion utilities or use environment variables to handle the various implementations.

    Is it worth it?

    If you made it this far, you’ve probably realized that TDD demands time. This article itself is over 6,000 words! This can be a bit scary if you’re used to faster development cycles, and probably looks impossible if you’re often working under pressure. However, it’s important to bust the myth that TDD would somehow double development time for little return on investment, because this is entirely false.

    TDD requires some practice, and you’ll get faster over time. What feels clumsy today can become a second nature tomorrow, if you do it regularly. I encourage you not to discard something because it’s new and feels awkward: give it some time to assess it fairly, then take a decision.

    Secondly, time spent on writing test-driven code is time you won’t spend fixing bugs.

    Fixing bugs is far more costly than preventing them. If you’ve ever had to fix critical production bugs, you know this feels close to holding an open wound on a surgical patient with one hand, while trying to operate with the other one. In the desert. At night. With a Swiss Army knife. It’s messy, stressful, suboptimal, and bears high chances of screwing up something else in the process. If you want to preserve your sanity and the trust your end users have in your software, you want to avoid those situations at all costs.

    Tests help you catch bugs before they make it to production, and TDD helps you write better tests. If you think you should test your software, then you should care about making these tests useful in the first place. Otherwise, the whole thing is only a waste of time.

    As with anything, I encourage you to try TDD before discarding the idea. If you’re consistently encountering production issues, or you think you could improve your development process, then it’s worth giving it a shot. Try it for a limited amount of time, measure the impact, and compare the results. You may discover a method that helps you ship better software, and feel more confident about hitting the “Deploy” button.

    What are the differences between the various JavaScript frameworks? E.g. Vue.js, Angular.js, React.js

    What are the differences? Do they each have specific use contexts?

    What are the differences? Do they each have specific use contexts?

    Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

    Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

    In this article we will discuss full details and comparison of both Ember.js and Vue.js

    JavaScript was initially created to work for web applications. But today they have become the favorite of mobile app developers. Most of the developers prefer to work with frameworks based on JavaScript. It simplifies coding. You can use JavaScript with almost any framework.

    The use of a particular framework will decide how easy and fast it is to create the app. So, you must choose the best one suited for the app that you are planning to build. You must make a wise choice so that you benefit in the end. Among the crowded market, two of the frameworks stand out. We will make a comparison between Ember.js and Vue.js.

    Why Do You Select A Particular Framework?

    Before we start comparing the two frameworks, we should understand the factors that lead to the choice of a framework. Each developer chooses a framework before he or she goes to work on an app. Let us see the reasons for the selection.

    ● The codes must be easy to understand and transparent.

    ● The framework should give the maximum power with the least amount of coding.

    ● The framework should provide a well laid out structure to work on.

    ● Does the framework support an in-built router or an external plug-in router?

    ● The framework should be able to transfer more data on a full page-load so that it becomes a single-page app. A single-page app is more beneficial for the application.

    ● In single page architectures if there is a need for users to share links to sub-screens within the interface, then the framework should have the capacity to route based on the URL.

    ● A tighter template option can help in enabling two-way binding.

    ● The framework should not conflict any third-party library.

    ● Testing the codes inside the framework should be easy.

    ● The framework should provide the HTTP client service for AJAX calls

    ● The documentation is essential. It should be complete and up-to-date.

    ● The framework should be compatible with the latest version of the browser.

    ● The framework has to fulfill the above conditions for easy construction of the app. You must ensure that the framework you choose meets the conditions.

    Vue.js Explained

    Developers are always looking at new frameworks to build their apps. The main requirements are speed and low cost. The framework should be easy to use by even new developers. You should be able to use it at low cost. Other considerations are about simple coding, proper documentation, etc.

    Vue.js combines a lot of good when it comes to software language for web app development. The architecture of Vue.js is easy to put in use. The apps developed using Vue.js are easy to integrate with new apps.

    Vue.js is a very lightweight framework. It makes it fast to download. It is also much faster than other frameworks. The single-file component nature of the framework is also beneficial. The size has made it very popular.

    You can further decrease weight. With Vue.js you can separate the template-to-virtual DOM and compiler. You can only deploy the minified and zipped interpreter which is only 12 KB. You can compile the templates in your machine.

    Another significant advantage of Vue.js is that it can integrate easily with existing applications created with JavaScript. It will make it easy for using this framework to make changes to applications already present.

    Vue.js also integrates easily with other front-end libraries. You can plug in another library and make up for any deficiency in this framework. This feature makes this tool a versatile one.

    Vue.js uses the method of rendering on the streaming-side server. You can render your component and get a readable stream. You can then send this to the HTTP server. It makes the server highly responsive. Your users will get the rendered content very quickly.

    Vue.js is very SEO friendly. As the framework supports server-side rendering, the views are rendered directly on the server. The search engines list these.

    But the most important thing for you is the ease with which you can learn Vue.js. The structure is elementary. Even new developers will find it easy to use it to build their apps. This framework helps in developing both small and large templates. It helps to save a lot of time.

    You can go back and check your errors very easily. You can travel back and inspect all the states apart from testing your components. It is another important feature as far as any developer is concerned.

    Vue.js also has very detailed documentation. It helps in writing your applications very quickly. You can build a web page or app with the basic knowledge of HTML or JavaScript.

    ● Vue.js has pure architecture. It helps in integration with other apps

    ● Vue.js is lightweight and fast. It can be made lighter by deploying only the interpreter

    ● You can separate the compiler and the template-to-virtual DOM.

    ● Due to smooth integration, you can use this to make changes to existing apps

    ● To make up for any shortfall, you can plug-in any library and makeup.

    ● As Vue.js uses streaming-side server rendering, your users can get quick responses.

    ● The server-side rendering also helps in being ranked higher by search engines.

    ● It has a simple structure. Easy to use for any new developer

    ● You can go back and check and correct your errors.

    ● You can check all the existing states.

    ● Detail documentation also helps build the web page or application very quickly.

    Ember.js Decoded

    Ember.js is an MVVM model framework. It is open-source software. This platform is mostly used for creating complex multi-page applications. It maintains up-to-date features without discarding any of the old features.

    With this framework, you have to follow the architecture of the framework strictly. The JS framework is very tightly organized. It reduces the flexibility that other frameworks might offer.

    There is a very refined and developed control system for its platforms and tools. You can integrate it with the new version with the tools provided. There is strict guidance about avoiding outdated APIs.

    You can understand Ember’s APIs easily. They are also easy to work. You can make use of highly complex functionalities simply and straightforwardly.

    The performance is better as similar jobs are processed together. It creates batches of similar bindings and DOM updates to improve the performance. It means that the browser needs to process them in one go. It will avoid recomputing for each task, wasting a lot of time.

    You can write the codes in a simple manner and modules. You can use any of Ember’s APIs. It is possible due to the presence of Promises everywhere.

    Ember comes with a well-written guide. The API is recorded in a useful manner. It is a front-end framework that is loaded. Ember has a router, pipeline, services, etc. of its own.

    The basis for views, controllers, models, and framework is the Ember Object Model. All components come from the same objects. The framework is firm and steady. The reason is that all elements have similar jobs and characteristics.

    Ember has made the general application, organization, and structure clear so that you don’t make any mistakes. You will have no chance to complicate the application unnecessarily. If you have to go out of the defined limits, you will have to force your way out.

    The language used for templating in Embers is Handlebars. This language helps Embers to keep its logic out of view. The clean syntax of Handlebars makes it easy for you to read and understand the templates. Handlebar templates are faster to load.

    Another advantage you gain from Handlebar is that you don’t have to update your template every time you add or remove data from the page. It will be done automatically by the language itself.

    A community that is continually improving the framework supports Ember. They are updating the framework with the latest technology. They also make sure that backward compatibility is possible.

    ● Ember.js is an open-source MVVM model framework suitable for complex multiple-page applications.

    ● It offers both the latest and old features.

    ● It has a very tightly structured framework which doesn’t offer much flexibility

    ● A very refined control system helps you to integrate with new versions without any problem.

    ● There is strict guidance about avoiding outdated API versions.

    ● Ember’s APIs help you to use complex functionalities in a simple manner

    ● There is no recomputing for each task as the framework allows the browser to do similar functions together.

    ● Promises allow you to write modular and straightforward code using any API of Ember.js.

    ● Ember.js is a fully loaded, front-end framework.

    ● The framework is stable because all components have the same functionalities and properties.

    ● It has well-defined limitations which will prevent your complicating your application

    ● Handlebars, the language used by Ember.js allows you to read and understand templates easily. It also helps to load the templates faster.

    ● Handlebars will ensure to update the template every time you add or remove data.

    ● Ember.js has an active community that updates the framework regularly and facilitates backward compatibility.

    A Comparison Between Ember.js And Vue.js

    This article intends to compare the features of both frameworks. Let us see how the characteristics of these frameworks compare. It will help you to make use of the right framework for your web application.

    When you need a modern engine for an old application, it is Vue.js which will help you. It combines the best properties of other frameworks. Vue.js is a developing framework. A ready-to-use library of interface elements does not exist. However, many third-party libraries can help you.

    Ember.js offers you a well-organized and trustworthy framework. When the development team is big, this is the framework that suits best. It allows everyone to understand the written code and contribute to a common project. The technology will be up-to-date, and the platform will be stable.

    Vue.js can help you use the syntax of different kinds. It helps in writing the codes with ease. It is also an SEO friendly framework. Ember is a fully loaded front-end framework and can help you develop the applications very fast. But it is not suitable for developing small projects.

    It is not easy to say this is better than that. It will depend on what kind of project you have undertaken. Both have their pluses and minuses. The below table will help in a better comparison.

    Final Thoughts

    It is not easy to conclude as to which is better. It all depends on the application that you want to develop. Both frameworks are developing. Both are getting updates. Both the communities are working on the frameworks.

    While Vue.js is more comfortable for writing codes, Ember is a full-stack framework allowing the development of apps very fast. It is suitable for big projects. It is too complicated to be used for smaller projects.

    We hope you had a great time reading this article. If you’ve any questions or suggestions related to this blog, then feel free to ask them in the comment section. Thank You.!