Automated Javascript Testing with Mocha.js


It is a well-known fact that code is prone to errors, and sometimes even when we know that a particular workflow will work fine for some cases, there's a good chance that we forget about some other cases.

In simple terms, it can be said that when we test a code manually, we might miss something. For example, suppose we have two functions, func1() and func2(), and we know that func1() works for the cases that we have defined in our test, but we found out that func2() doesn't work. Then we fix func2() but later forgot to check whether func1() works for the entire flow after the changes that we have done in func2(). This process might lead to an error, and it's a typical thing which happens a few times.

Now, we know it's not a very ideal option to run tests in manual fashion, hence it is recommended that we run tests that are written separately, in addition to the code that we might have written. This is what is called Automated Testing.

In this tutorial, we will explore how you can do Automated Testing using Mocha in JavaScript.

The first step is to be able to have both Mocha available to us in our code. For that, we can make use of the CDN links that mocha.js provides us with. In this tutorial, we will use Chai.js and Expect.js as well, which works well with Mocha when we want to check the exact behaviour of different functions that we might have written.

Below are all the CDN's that you need to import in your index.html file.

Expect.js

https://cdn.rawgit.com/Automattic/expect.js/0.3.1/index.js

Chai.js

https://cdn.rawgit.com/chaijs/chai/3.5.0/chai.js

Mocha.js

https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js

The next step is to create three files in a simple project directory inside your favourite IDE or code editor.

  • index.html
  • index.js
  • tests.js

You can also use the command shown below.

touch index.html index.js tests.js

Note − It might be so that the touch command may not work in your local machine, in that case, use the vi command instead.

index.html

Now that we created all the files, it's time to write the code. Open the index.html file and paste the following lines.

Example

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8">
   <title>Automated Testing With Mocha</title>
   <link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
   <div id="mocha"></div>
   <script src="https://cdn.rawgit.com/Automattic/expect.js/0.3.1/index.js"></script>
   <script src="https://cdn.rawgit.com/chaijs/chai/3.5.0/chai.js"></script>
   <script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
   <script src="index.js"></script>
   <script>
      const mocha = window.mocha;
      mocha.setup('bdd');
   </script>
   <script src="tests.js"></script>
   <script>
      mocha.checkLeaks();
      mocha.run();
   </script>
</body>
</html>

Explanation

In the above HTML code, I have imported all the dependencies like Mocha, Chai and Expect via CDN.

Then I have imported two different js files namely index.js and tests.js in a synchronous order, which means, first the index.js file run, and then a script in which I am setting the window.mocha() and the bdd.

Consider the code snippet shown below.

const mocha = window.mocha;
mocha.setup('bdd');

After the above code, I am invoking the tests.js file and later calling different methods of Mocha. Consider the code snippet shown below.

mocha.checkLeaks();
mocha.run();

Now it's time that we write some function or functions to test them out with Mocha in an automated fashion. Consider the code of index.js shown below.

function addNumbers(a, b) {
   return a + b;
}

The above function is a very simple function in which we have two parameters and then simply return the sum of these two numbers in the response.

tests.js

Now comes the interesting part where we will test whether the above function works as expected or not with the help of automated testing. Consider the code of tests.js shown below.

const chai = window.chai const expect = chai.expect describe('addNumbers', () => { it('should be able to add two numbers and give proper result', () => { expect(addNumbers(1, 3)).to.deep.equal(4) expect(addNumbers(1, 5)).to.deep.equal(6) expect(addNumbers(-9, -10)).to.deep.equal(-19) }) })

In the above code, I am importing Chai and Expect packages that were made available to us via CDN links that were present in the index.html file.

Also, we are using the describe function in which the first argument that we are passing is a string of our choice. Next, we are creating an anonymous function inside which we are calling the it() function which in turn takes a string as the first argument and an anonymous arrow function as the second argument.

We are using the expect functions, in which we are calling the actual function that we want to test as the argument and then using the deep.equal() method to check for equality.

Output

Once you run the HTML code and open the code in the browser, everything should work as expected. You should see a text printed in your browser, somewhat similar to what is shown below.

>addNumbers
should be able to add two numbers and give proper result

Let's Add a Second Function

In the above example, we tested a simple JavaScript function called addNumbers. Now, let's try to add another function, but this time, we will make use of an arrow function. Consider the code shown below.

index.js

let multiplyNumber = (a, b) => {
   return a * b;
}

tests.js

Now, let's write an automated test for the above function inside the tests.js file. Consider the code snippet shown below.

describe('multiplyNumber', () => { it('should be able to multiply two numbers and give proper result',() => { expect(multiplyNumber(1, 3)).to.deep.equal(3) expect(multiplyNumber(1, 5)).to.deep.equal(5) expect(multiplyNumber(-9, -10)).to.deep.equal(90) }) })

Output

Run the HTML code and this time you will get the names of both the functions in the browser.

addNumbers
should be able to add two numbers and give proper result‣
multiplyNumber
should be able to multiply two numbers and give proper result

What If a Function Doesn't Return the Expected Output?

In both the functions that we wrote the automated tests for, we were actually expecting the correct values. What if we make changes in the core logic of a function to return wrong values?

Consider a function called multiplyNumber that is present in the index.js file. Let's make a change in the function so that it doesn't give us the expected output.

multiplyNumber

let multiplyNumber = (a, b) => {
   return a * b;
}

Output

Now if we run the HTML code in the browser, we will get the following output in the browser.

multiplyNumber
should be able to multiply two numbers and give proper result‣
AssertionError: expected 0.3333333333333333 to deeply equal 3

Automated Testing with Multiple Describe Functions

In both the examples above, we used a single describe function and simple functions. Now let's say that we want to use a function in which we want to calculate the power of a number.

Consider the index.js code shown below

function power(x, n) {
   let res = 1;
   for (let i = 0; i < n; i++) {
      res *= x;
   }
   return res;
} 

In the above function, we are taking two arguments, and then raising the power of a number to n times.

tests.js

Now let's write an automated test for this function.

describe("power", function () {
   describe("raises x to power 2", function () {
      function checkPower(x) {
         let expected = x * x;
         it(`${x} in the power 2 is ${expected}`, function () {
            expect(power(x, 2)).to.deep.equal(expected);
         });
      }
      for (let x = 1; x <= 5; x++) {
         checkPower(x);
      }
   });
});

We can see that in the automated test function, we are using nested describe functions. Here, we are checking that the power() function that we have written in index.js works as expected or not.

Output

power
raises x to power 2
1 in the power 2 is 1‣
2 in the power 2 is 4‣
3 in the power 2 is 9‣
4 in the power 2 is 16‣
5 in the power 2 is 25

Conclusion

In this tutorial, we explained with examples how you can use Mocha.js with Chai.js and Expect.js to perform Automated Testing in JavaScript.

Updated on: 15-Jun-2023

195 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements