Danywalls

Testing javascript from 0 to Mocha.

May 26, 2019

I’m trying to learn #testing in javascript, today we have few ways to test our code write plain test code or using #mocha, #jest or #cypress.

But what is a Test? the test is a piece of code that ensures our software works as we expect, it can be done without frameworks.

Feel free to read the code in Github or continue reading.

This example we will test a function for calculating IVA Tax of 21% from a single amount. the first step is create a file iva.js and write the ivaCalculate function and export it.

function ivaCalculate(amount, percentage) {
    return amount * percentage / 100
}
module.exports = ivaCalculate

I will use nodemon package to run my js code quick and hot reload.

npm install -g nodemon

The Test

Our second step is to create a spec file for our testing, the iva.spec.js file, import Iva.js using require and call the duction passing the parameters 1250 and 21, it will return the calculation from the function defined into the iva.js.

Validate the result === expect using a ternary and show a message is equal or not.

const irpfCal = require('./iva');
const result = irpfCal(1250,21);
const expect  = 262.5;
result === expect ? console.log("ok") : console.log("fail")

From our terminal run to see the result of our “handy and dirty test”.

danys-imac:iva danyparedes$ nodemon iva.spec
[nodemon] 1.19.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node iva.spec.js`
ok
[nodemon] clean exit - waiting for changes before restart

Using the Assert Module

We are using a dump ternary function to validate our code, but nodejs bring with a module to handle these situations.

In our code, import assert module and it will provide a list of assert methods, I use equal, it does the same behavior as our preview code.

The equal function evaluates if two values are not equal and if fails it throws an error and an optional message parameter for specifies the error.

const assert = require('assert');
const irpfCal = require('./iva');
const result = irpfCal(1250,21)
const expect  = 262.5
assert.equal(result, expect, 'irpf calculation fails') 

Our code will be reloaded by nodemon and it will not show any error but if we modify irpfCal function it will show irpf calculation fails.

Move to Mocha

Our test works, but it is not easy to manage or provide an elegant way to see the results, for this case Mocha come to help us.

Mocha is a test runner, it will help to manage our test easier and it provides an elegant way to write, check and functions to evaluate our test.

First, install mocha test runner for our terminal in the same path.

npm install mocha --save-dev

When complete, edit the package.json and into the script area set tests to mocha.

...
  "scripts": {
    "test": "mocha"
  }
 ..

By convention mocha search into test directory into our application, that means we need to create a test directory and move iva.spec.js file into it.

Mocha provides few global functions as describe it is used for the title of our group of tests, that means we can group few tests into a describe block and it for setting the title for a specific test.

const assert = require('assert');
const irpfCal = require('../iva');
const actual = irpfCal(1250,21)
const expect  = 262.5

describe('IVA tax calculation processs', () => {
    it('calculate 15% of 1250', () => {
        assert.equal(actual,expect)
    })
})

See the test results in the terminal running the command npm test

npm test
danys-imac:iva danyparedes$ npm test

> iva@1.0.0 test /Users/danyparedes/Desktop/testing/iva
> mocha
  IVA tax calculation processs
    ✓ calculate 15% of 1250
  1 passing (3ms)

Extending the test

Create another function for the test, it will call amountWithIVA , add the function into iva.js and include it into the exports.

function ivaCalculate(amount, percentage) {
    return amount * percentage / 100
}

function amountWithIVA(ivaAmount, amount) {
    return ivaAmount + amount;
}

module.exports = { ivaCalculate, amountWithIVA }

I will group my set of test related to the iva into the describe IVA tax calculation and like the preview test it will call the function exposed by iva.js

const assert = require('assert');
const {ivaCalculate, amountWithIVA} = require('../iva');

describe('IVA tax calculation processs', () => {
    it('calculate 15% of 1250', () => {
        const actual = ivaCalculate(1250,21)
        const expect  = 262.5
        assert.equal(actual,expect)
    })
    it('calculate total amount of 1250,21 with 15% IVA', () => {
        const actual = amountWithIVA(1250,262.5)
        const expect  = 1512.50
        assert.equal(actual,expect)
    })
})

Run the test from the terminal with npm test and see the results.

danys-imac:iva danyparedes$ npm test
> iva@1.0.0 test /Users/danyparedes/Desktop/testing/iva
> mocha
  IVA tax calculation processs
    ✓ calculate 15% of 1250
    ✓ calculate total amount of 1250,21 with 15% IVA
  2 passing (5ms)

Testing objects

My last example is a function to get a banner configuration for each IVA type, it returns an object with some settings, I will create a new file ads.js with the function getIVABanner it will return a json object.

function getIVABanner(amount) {
    switch (amount) {
        case 15:
            return {
                img: '/bar.jpg',
                size: '15%',
                border: 3,
                color: 'green'
            }
            break;
        case 20:
                return {
                    img: '/bar.jpg',
                    size: '20%',
                    border: 5,
                    color: 'yellow'
                }
                break;
       case 30:
            return {
                img: '/bar.jpg',
                size: '20%',
                border: 5,
                color: 'red'
            }   
     default:
            break;
    }
}

module.exports  = { getIVABanner }

Next into the test directory create ads.spec.js , similar to iva.spec import assert from assert and gitIVABanner function from ads, using describe and to group all test related to ads for taxes.

Create the actual object calling getIVABanner function and pass 15 Tax type and define the expected object.

But in for the object, we will use assert.deepEqual to validate the actual match fully with the expected.

const assert = require('assert');
const {getIVABanner} = require('../ads');

describe('Ads for taxes', () => {
    it('Get green banner for 15% IVA', () => {
        const actual = getIVABanner(15);
        const expect =   {
            img: '/bar.jpg',
            size: '15%',
            border: 3,
            color: 'green'
        }
        assert.deepEqual(actual,expect)
    })
})

Run the npm test command to see the results.

danys-imac:iva danyparedes$ npm test
> iva@1.0.0 test /Users/danyparedes/Desktop/testing/iva
> mocha
  Ads for taxes
    ✓ Get green banner for 15% IVA
  IVA tax calculation processs
    ✓ calculate 15% of 1250
    ✓ calculate the total amount of 1250,21 with 15% IVA
  3 passing (7ms)

That’s it!

Hopefully, that will give you a bit of a head-start on testing and Mocha, and help you avoid some of the more common mistakes,If you enjoyed this post, share it.

Thanks for reading!


Dany Paredes

Hi, I'm Dany Paredes, few years ago I was working with .NET, but in my last years I have been focusing in Javascript using Vue , Angular or React. You can read more in Twitter or Github.