November 20, 2016 - VitoMd and the Evil Machine

Testing Javascript code with Mocha and Chai

Introduction

Testing in Javascript has become more and more important. There are some robust test frameworks to choose like: Mocha.js, Jasmine, QUnit or Tape.

Mocha (http://mochajs.org) is a feature-rich JavaScript test framework running on Node.js and in the browser. Chai (http://chaijs.com) is an assertion library that can be paired with any javascript testing framework. In this short tutorial we will show how to work with Mocha and Chai to test a simple Stack structure written in plain Javascript.

code

Step by Step guide

1) We are going use Plunker to write the code. Go to http://plnkr.co/edit/. Add the Mocha and Chai libraries: click on the index.html page and then go to the right toolbar and click Find and external libraries. Search for mocha-chai and click the add button. You will see 3 new external resources, mocha.js, chai.js and mocha.css.

2) We are going to create a Stack structure using Test Driven Development (TDD). This means that first we will write a test, run the test and see that is failing, write code so the test pass, refactor de code if needed. Double click in the script.js file so you can change the name to stack.js, also in the index.html change the script reference from script.js to stack.js. Then click in new file and create a new file called stack-spec.js.

3) In this step we will configure the test libraries. The describe keyword group tests based on the same subject. The it keyword references a test with a description. The description should make sense when reading, like It creates a Stack, and not It Stack Creation.

Chai gives 2 different assertion styles: TDD and BDD (Behavior-driven development). For TDD it uses the assert style, and for BDD has 2 flavours: expect and should. I prefer the BDD style and expect flavour because they are more descriptive.

We will need to add this to stack-spec.js to use the expect assertion style:

var  expect = chai.expect

We need to run and show the test result, so in the index.html delete the “Hello Plunker!” line and write this instead:

<div id="mocha"></div>
<script>mocha.setup('bdd')</script>
<script src="stack-spec.js"></script>
<script>mocha.run()</script>

The div will show our tests results, mocha.setup(‘bdd’) is to select the bdd style, src=stack-specjs” is to load our test and mocha.run() it will run our tests. Click the run button in plunker. Each time you change the code it will run automatically.

4) Writing the first test: The api reference for Chai can be found here http://chaijs.com/api/bdd/. Add this to the stack-spec.js file

describe('Stack', function() {
  it('creates a Stack', function() {
     expect(new Stack()).to.exist 
  });
});

As you can see the code is easy to understand, we expect the new Stack() to exist. In this case exist means Asserts that the target is neither null nor undefined. that is exactly what we want.

The test should fail with ReferenceError: Stack is not defined

5) We are going to write the Stack structure to make the test pass. Add this code to stack.js

function Stack(){
}

The code will automatically run (if not, click run button) and the test should pass.

6) We know that the Stack needs to have an array to hold the data, we will call it data. We will use the exist method, and also the an method to assert the array type. In general is not good practice to assert two things in the same test, but in this case we are testing the same behaviour. Add this new test in the stack-spec.js file, inside the Stack describe.

  it('has a data array', function() {
    var stack = new Stack();
    expect(stack.data).to.exist;
    expect(stack.data).to.be.an('array');
  });  

The test will fail so we are going to write the code to make it pass. Add it to the stack.js file

function Stack(){
  this.data = [];
}

7) We need 2 methods, one to push elements and other to remove elements from the top of the stack. We will call them push and pop.

8) Now I´m going to test and implement the push method.

  //stack-spec.js
  it('push an element to the stack', function() {
    var stack = new Stack()
    stack.push(1);
    expect(stack.data).to.have.lengthOf(1);
  });  

I’m using the lengthOf method from Chai to test if the data is added. The test should fail and then we need to implement the push method in stack.js.

  //stack.js
  function Stack(){
    this.data = [];
    this.push = function(element) {
      this.data.push(element);
    }
  } 

9) Finally the pop method that will remove and return the top element.

  //stack-spec.js
  it('pop an element from the stack', function() {
    var stack = new Stack();
    stack.push(1);
    var element = stack.pop();
    expect(element).to.be.equal(1);
    expect(stack.data).to.have.lengthOf(0);
  });  

We know that the push method works, so we are pushing and popping an element and comparing it with the equal method from Chai

    //stack.js
    this.pop = function() {
      var index = this.data.length-1
      var top = this.data[index];
      this.data.splice(index, 1);
      return top;
    }

Summary:

We learnt how to setup mocha+chai and how to use some test methods like: exist, an, lengthOf and equal.

Full code on Plunker

Share this post on Twitter

Comments