Home

Testing using Node and Mocha

Most of this will probably be copied from Codecademy's site until I learn it.

Before writing any tests you’ll need to use Node.js and npm to set up a JavaScript project and install Mocha.

Here is a getting started document from MOCHA which may help too.

(Note...
There is also a technique called Chai but my course only mentioned it and gave no examples - but you can read about it HERE... it's a getting started document from CHAI which may help too.)


Node allows you to run JavaScript in the terminal.
npm is a Node tool that allows you to download packages from the web, and manage them in a JavaScript project.
Mocha is one of those packages and is used to test other JavaScript code.

A JavaScript project is a directory of files.
The following command (in windows Command Prompt) creates a file package.json that can be used to manage packages for the project.
(You will need to change directory (cd) in to your project directory, then...)

$ npm init

After running this command you will be prompted to enter information about your project.
It’s okay to skip some fields if you’re not ready to enter that information.

With your project setup, you can install packages.

$ npm install mocha -D

Here’s what this command means:

npm install tells npm to install a package from the internet and any other packages it depends on.
mocha is the package you want to download.
-D notes that this package is a dependency for your project, which makes it easier for other developers to use.

Once you 'npm install' packages, you can find the packages and all their dependencies in the node_modules folder.
The new directory structure contains the following:

project
|_ node_modules
|___ .bin
|___ mocha
|___ ...
|_ package.json
The ... in the file structure represents other packages that are a dependency for Mocha.

After installing Mocha as a dependency we can run it in two ways.

The first (and more tedious) method is to call it directly from node_modules:
$ ./node_modules/mocha/bin/mocha

The second (and recommended) method is to add a script to the package.json file.
In the scripts object in package.json, set the value of "test" to mocha.
It should look like this:

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


Now you can call Mocha with the following command:
$ npm test

Instead of manually running each test in the test directory, you can use this command to run the full test suite automatically.



DESCRIBE and IT blocks

In Mocha we group tests using the describe function and define tests using the it function.

These two functions can be used to make your test suite complete, maintainable, and expressive in the following ways:

Structure your test suite: you can organize tests into nested groups that reflect the structure of your implementation code.

Provide informative messages: you can define your tests using human-readable strings.

Top

describe and it

In Mocha we group tests using the describe function and define tests using the it function.
These two functions can be used to make your test suite complete, maintainable, and expressive.

If you are testing a Math object with the method .min, you could use the following test code.
(Note...You need one describe command for the object Math and another describe command for the .min method)

You would then use the it command to perform the required test(s).
The text in the it command is displayed in the console log to inform you what is being tested.

describe("Math", () => {
    describe(".min", () => {
        it("returns the argument with the lowest value", () => {
            //...Put your 'assertion code' in here...eg...
            assert.ok(Math.min(30, 40, 50, 20) === 20);
        });
    });
});

When testing this, the above code could be in file index_test.js for example, then in command prompt you would run...
$ npm test
and you would get a message
1 passing
as the Math.min would return 20 and check that it equals 20.


I know all of these examples are not really complete as you need the file names & directories and, maybe, more explanation on NODE but this is just an example of what you could do in index_test.js in order to test it.

assert

To write the tests themselves, we can use the assert.ok method provided by Node.js.

In programming, a test compares an expected outcome to an actual outcome.
For example, we expect the outcome of the following code…

const a = 1 + 2;

…to be: a has a value of 3.
To test the value saved to a with plain JavaScript, you would need to write a conditional statement comparing a to the expected result. Inside the statement, you would construct an error when the actual outcome does not match the expected.

assert.ok() allows you to compare values and throw errors as needed using one function call.

As it's a Node module, assert can be imported at the top of your files with:

const assert = require('assert');

You call assert functions like this:

assert.ok(a === 3);
...or you could say...
assert.ok(a === 3, "This is my message");
(the a === 3 is whatever test you are performing...
...if you include a message then this message will show on the console log as well)


In this case a === 3 evaluates to true, so no error is thrown.
If an argument passed to assert.ok() evaluates to false, an AssertionError is thrown.
The error communicates to Mocha that a test has failed, and Mocha logs the error message to the console.

For instance, you could see some text, which includes...
1) returns the argument with the lowest value
0 passing (7ms)
1 failing

Note
You can have more than 1 assert command within the it command
but each it group counts as 1 passing (or 1 failing) and not each individual assert.
Therefore, 4 'assert' in 2 different 'it' (or is it each 'describe'??) will only be 2 passing's.

Top

It is also worth noting

It is also worth noting that you may need to undo some things that may happen in your test(s), for example...
You may create new test files that need to be deleted when the testing is over.
Or you may write to tables and need to delete the information.
Or maybe you set permissions that need to be removed.
Whatever you need to be undone can be put in your file like this (it is known as a 'teardown')...

describe('example', () => {

    afterEach(() => {
        // teardown goes here
    });

    it('.sample', () => {
        // test goes here
    });

});


This way then it will run the 'teardown' when your testing completes whether or not it fails or passes okay.
(If it fails then the code stops running, but the teardown still happens).

Note...
afterEach() will be executed after each 'it' statement.

Node.js Built-in Modules

Node.js has a set of built-in modules which you can use without any further installation.

See W3Schools page for a list of Node.js Modules like assert(), fail(), equal, etc.

And if you want to take a look at nodejs.org's own site on assertion testing then Click Here

Top

Another small Example

This is another small example that builds a test scenario
and uses assert.deepEqual(array1, array2) to test two objects (in this case arrays).
It also shows the different stages (known as Setup, Exercise & Verify) in the test scenario...

const assert = require('assert');

describe('+', () => {

   it('returns the sum of two values', () => {
      // Setup
      let expected = [3, 4, 7];
      let sum = [3, 4];

      // Exercise
      sum.push(3 + 4);

      // Verify
      assert.deepEqual(sum, expected, "My message goes in here");
   });

});


NOTE...
The assert.deepEqual is used to check objects (eg arrays are objects, variables are not) as assert.equal will fail when checking objects.
If the test fails then "My message goes in here" will be displayed so you know where it failed... useful when performing a test with multiple asserts().

Other files to see

I also have created in:-

D:\
   VisualStudioWeb\
      "Javascript Modules Using Node"\
         "Testing using Node.js - Rooster Call"\

2 files, called:-

index.js
Which exports some methods/functions that the testing file (index_test.js) uses.

index_test.js
This imports from index.js and performs the Node.js testing checks.

This all make up another little Node.js testing program from Codecademy.
So could be worth looking at for further reference.

Top

Below are a copy of 2 forms used for a Codecademy example
index.js & index_test.js

Codecademy example


index.js

const Calculate = {
    //sum (is a function) and will 
    //  become a property of Calculate
    //eg    Calculate.sum([1,2,3]); 
    sum(inputArray) {
    if(inputArray.length === 0){
        return 0
    }
    
    return inputArray.reduce((sum, value) => {
        return sum + value;
    })
    }
}

module.exports = Calculate;

            

Alternative index.js

function myReduceFunction(total, num) {
    return total+num;
}

const Calculate = {
    sum(inputArray) {
    if(inputArray.length === 0){
        return 0
    }
    
    return inputArray.reduce(myReduceFunction)
    }
}

module.exports = Calculate;

            

Codecademy example

index_test.js

const assert = require('assert');
const Calculate =  require('../index.js')

describe('Calculate', () => {
  describe('.sum',() => {
    it('returns the sum of an array of numbers', () => {
      const expectedResult = 6;
      const inputArray = [1,2,3]
      
      const result = Calculate.sum(inputArray)
      
      assert.equal(result, expectedResult);
    });
    
    it('returns the sum of a four item list', ()=>{
      const expectedResult = 22;
      const inputArray = [4,6,5,7];
      
      const result = Calculate.sum(inputArray);
      
      assert.equal(result, expectedResult)
      
    });
    
    it('returns zero when the array is empty', ()=>{
       const expectedResult = 0;
       const inputArray = [];
       const result = Calculate.sum(inputArray);
       assert.equal(result, expectedResult)
    });
  });
});

            
Top