Mocha Unit Testing Tutorial: Getting Started

This Mocha unit testing tutorial will help you get started with performing unit testing with the Mocha framework.

OVERVIEW

Software testing is a way to ensure that the software under test (SUT) conforms with the requirements during or after development. It is an important aspect of software engineering as it reduces bugs and deployment of defective software products.

Over the years, different tools have been created to make software testing easy and more fun. These tools have their similarities as well as their differences. Moreover, Mocha is one such tool, and it's a flexible JavaScript testing framework that makes testing simple and more flexible.

In this Mocha unit testing tutorial, we will explore the Mocha JavaScript testing framework with insights into why use the Mocha framework and the different limitations of using Mocha. Lastly, we will learn how to test a demo Node.js application with the Mocha unit testing framework.

What is Mocha?

Mocha is a JavaScript testing framework that runs both on the server (Node.js) and the client (browser). It's a feature-rich framework that provides on-demand testing tools built-in. Mocha makes asynchronous testing simple and fun while allowing your tests to run serially, allowing for flexible and accurate reporting.

With Mocha, you have many rich features built into the framework, such as browser support, asynchronous and parallel testing, test coverage testing, JavaScript API for running tests, node native ES modules support, etc. These features allow the development team to have one testing framework to support various needs.

According to GitHub, some of the growth statistics of the Mocha library as of the time of writing include more than 22.1k GitHub Stars and about 2m GitHub Usage, making Mocha a very popular testing framework.

You can explore all the features supported by the Mocha unit testing framework right out of the box from the official Mocha documentation.

While Mocha is a great testing framework, some specific reasons and features make Mocha a popular choice for both Test Driven Development (TDD) and Behaviour Driven Development (BDD) development teams.

Note

Note : Run your Mocha tests across 3000+ real browsers. Try LambdaTest Now!

Why use Mocha Framework?

Mocha unit testing framework is widely used for both TDD and BDD teams because of the rich features introduced into Mocha right out of the box. Some reasons why Mocha is a popular choice are listed below:

  • The Mocha unit testing framework has multiple installation methods, which is essential for diverse teams using different approaches in setting up their development teams.
  • Mocha makes browser testing very easy and simple. With multiple browser support, the Mocha unit testing framework makes creating test cases that run seamlessly on all major web browsers easy.
  • Mocha supports both TDD and BDD due to the many rich features built into Mocha right out of the box. It makes it easy for TDD and BDD teams to write high-quality tests with enhanced coverage.
  • With JS assertion libraries in support, you can reduce testing costs and speed up the process by having compatibility with various JavaScript assertion libraries.
  • Mocha unit testing framework provides various ways to offer test reports. This option allows users to have different reporting options, such as the list reporter, the progress reporter, and the JSON reporter.

Mocha, as a testing framework, has more features and benefits included inside the framework that we can mention here. However, it has certain limitations as well.

Limitation of using Mocha

As with every technology, there are always disadvantages and limitations to using a particular technology. In this section of the Mocha unit testing tutorial, we will explore the limitation of using the Mocha unit testing framework.

  • Mocha does not have assertion libraries built-in. It requires you to install and configure your own assertion library, which reduces the flexibility of the library.
  • Mocha does not support snapshot testing right from the box. It requires you to install and configure a separate snapshot library, such as chai-jest-snapshot, for it to work
  • Mocha requires plenty of configurations to get it working in an ideal project. This makes the library less flexible and prone to errors due to wrong configurations from individual developers.
  • Mocha is sometimes considered "bloated" because of the many libraries and features included in-built inside the library. It could be seen as an advantage to some but also a limitation to some teams.
  • Mocha does not support auto-mocking testing right out of the box. It requires the installation of other external libraries.

Above are some of the known limitations of the Mocha unit testing framework. Also, note that some development teams may find these limitations an advantage. So it depends on what your team looks for in a testing framework.

In the next section of the Mocha unit testing tutorial, we will learn how to run your first Mocha unit test in JavaScript and gain useful knowledge on how to set it up in your JavaScript project.

Understanding Mocha Unit Testing Framework

This section will explore the basic elements of Mocha unit testing, such as suites, specs, and many others listed below.

  • Suites and Specs
  • Hooks
  • Asynchronous code
  • Arrow Functions
  • Pending Tests
  • Exclusive Tests
  • Inclusive Tests
  • Retry Tests
  • Parallel Tests

To begin, create a demo project that will help us to practically learn and understand the different elements used in Mocha unit testing.

After that, create a project folder in your preferred location and execute the following command to initialize a new project's package.json file.


 npm init -y

file and add the following code

Next, create an `helpers.js` file and add the following code:


function fibonacci(num, memo) {
 memo = memo || {};


 if (memo[num]) return memo[num];
 if (num <= 1) return 1;


 return (memo[num] = fibonacci(num - 1, memo) + fibonacci(num - 2, memo));
}


module.exports = {
 fibonacci: Fibonacci,
};

The above code snippet is a simple Fibonacci series computation. We will use this example to understand the different elements of Mocha unit testing.

Suites

A suite refers to a collection of specifications or test cases, which are used to test a set of functionalities or behaviors in JavaScript code. Typically, a suite is encapsulated within an object/class or a function. You can define a suite of test cases with the help of `describe` block.

The `describe` block requires two essential parameters: a string specifying the suite name and a function that implements the actual code of the test suite.

Let's explore an example of our first Mocha test suite:


describe('Test Helpers', function () {
 /**
  * Add all your related test cases here
  *
  */
});

Specs

A spec is a declaration of a specific test that belongs to a test suite. This declaration is made by utilizing the Mocha global function `it()`, which requires two parameters: the title of the spec and a function that implements the actual test case.

It can contain one or more expectations, which are used to determine the correctness of the test. Each expectation is essentially an assertion that can return either true or false. If an expectation returns true, the spec is passed. However, if the expectation returns false, the spec fails.

Here is how to declare a spec in Mocha:


describe('Test Helpers', function () {
 it('should calculate Fibonacci series', function () {
   /*...*/
 });
});

Hooks – Using beforeEach and afterEach

Mocha provides hooks that should be used to set up preconditions and clean up after your tests. They are the before, after, beforeEach, and afterEach functions.

  • The after function is called after each test case in the suite.
  • The before function is called before each test case in the suite.
  • The `beforeEach` function is called once before each spec in the suite.
  • The `afterEach` function is called once before each spec in the suite.

For instance, if you need initial variables to use in each of your test suites, you can simply add the initialization process inside the `beforeEach` function, which will be initialized on every test case. Also, you can reset any variable of your choice using the `afterEach` function.


describe('using hooks', function () {
 before(function () {
   // runs once before the first test in this block
 });


 after(function () {
   // runs once after the last test in this block
 });


 beforeEach(function () {
   // runs before each test in this block
 });


 afterEach(function () {
   // runs after each test in this block
 });


 // test cases
 it('should calculate Fibonacci series', function () {
   const fib = fibonacci(4);
   expect(fib).toEqual(5);
 });
});

Asynchronous Code

Mocha allows asynchronous test suites. It allows the use of callbacks, async/await, and promises. Below we are going to show how to write asynchronous test cases.


describe('Test Helpers', function () {
 it('should calculate Fibonacci series', function (done) {
   var fib = new fibonacci(4);
   fib.calculate(function (err) {
     if (err) done(err);
     else done();
   });
 });
});

Next, let's demonstrate how to use async/await when writing our test cases.


describe('Test Helpers', function () {
 it('should calculate Fibonacci series', async function () {
   const fib = new fibonacci(4);
   const result = await fib.calculate();
   expect(result).toEqual(5);
 });
});

Arrow Functions

Mocha also allows the use of arrow functions in writing test cases, as shown in the code snippet below:


describe('Test Helpers', () => {
 it('should calculate Fibonacci series', () => {
   const fib = new fibonacci(4);
   expect(fib).toEqual(5);
 });
});

Pending Tests

These are test cases that will be written later. Test results will include pending tests and be marked as pending. Tests that are pending are not considered failed tests. These test cases do not have any callbacks or matchers.


describe('Test Helpers', function () {
 // pending test below
 it('should calculate Fibonacci series');
});

Exclusive Tests

Using the exclusivity feature, you can only run a specific suite. You can specify the test you want to run in a test suite by using the only function as shown below:


describe('Test Helpers', function () {
 it.only('should return -1 unless present', function () {
   // ...
 });
 it('should return the index when present', function () {
   // ...
 });
});

Only the test cases with the only function will be executed.

Inclusive Tests

Mocha allows you to ignore a test case by appending the skip function to the test case. Let's demonstrate it as shown below:


describe('Test Helpers', function () {
 it.skip('should return -1 unless present', function () {
   // this test will not be run
 });
 it('should return the index when present', function () {
   // this test will be run
 });
});

Retry Tests

Mocha allows you to retry failed tests up to a certain number of times. This feature is designed to handle end-to-end tests (functional tests/Selenium) where resources cannot be easily mocked/stubbed.

Let's look at examples of how to implement it below:


describe('retries', function () {
 // Retry all tests in this suite up to 4 times
 this.retries(4);
 beforeEach(function () {
   browser.get('https://www.lambdatest.com/');
 });
 it('should succeed on the 3rd try', function () {
   // Specify this test to only retry up to 2 times
   this.retries(2);
   expect($('.foo').isDisplayed()).to.eventually.be.true;
 });
});

In the next section, we will explore how to set up the Mocha unit testing environment and configure Mocha to work with our demo project setup.

Note

Note : Automate Mocha unit testing on the cloud. Try LambdaTest Now!

Running a Mocha Unit Test in JavaScript

Writing a unit test is simpler than you think using Mocha unit testing frameworks. In the example, we will use the Mocha framework to write some basic test cases.

Subscribe to the LambdaTest YouTube Channel to get the latest tutorials around Selenium testing, Cypress testing, and more.

We will write some unit test cases to sum up numbers on the LambdaTest Playground website using Selenium.

Create a Project

First, clone the Mocha testing repository from GitHub, and add the following libraries to our package.json file.


npm install mocha assert

please set the following environment variables

Before the tests are run, please set the following environment variables in your .env file. You can find the LambdaTest username and access key on your LambdaTest Profile page.

For macOS:


LT_USERNAME=
LT_ACCESS_KEY=
GRID_HOST=hub.lambdatest.com/wd/hub

After installing the libraries and setting the environment variables, below is the implementation of the web calculator:


const { Builder, By } = require('selenium-webdriver');
let driver;
const USERNAME = process.env.LT_USERNAME ?? '';
const KEY = process.env.LT_ACCESS_KEY ?? '';
const GRID_HOST = 'hub.lambdatest.com/wd/hub';


// Setting LambdaTest Capabilities
const searchCapabilities = {
 browserName: 'Chrome',
 browserVersion: '107.0',
 'LT:Options': {
   username: USERNAME,
   accessKey: KEY,
   geoLocation: 'US',
   platformName: 'Windows 10',
   build: 'calculate',
   project: 'Calculate',
   w3c: true,
   plugin: 'node_js-node_js',
 },
};
const searchGridUrl = 'https://' + USERNAME + ':' + KEY + '@' + GRID_HOST;


// Create a calculate function with LamdaTest
async function calculateWithLambdaTest(num1 = 5, num2 = 5) {
 try {
   driver = await new Builder()
     .usingServer(searchGridUrl)
     .withCapabilities(searchCapabilities)
     .build();
   await driver.get(
     'https://www.lambdatest.com/selenium-playground/simple-form-demo'
   );


   const inputSum1 = await driver.findElement(By.id('sum1'));
   const inputSum2 = await driver.findElement(By.id('sum2'));
   const button = await driver.findElement(
     By.xpath(
       '//button[.='Get values']'
     )
   );
   inputSum1.sendKeys(num1);
   inputSum2.sendKeys(num2);
   button.click();
   const result = await driver.findElement(By.id('addmessage'));
   return await result.getText();
 } catch (error) {
   throw new Error(error);
 } finally {
   await driver.quit();
 }
}
module.exports = {
 calculate: calculateWithLambdaTest,
};

GitHub

Code Walkthrough

Let’s walk through the code together and understand the nitty-gritty of it.

Step 1: Add required packages and create Selenium capabilities.

First, we need the selenium-webdriver packages. Before running the operation, please set the following environment variables in your .env file. You can find the username and access key on your LambdaTest Profile page.

Next, generate your Selenium configuration using the LambdaTest Capabilities Generator. LambdaTest Capabilities Generator . Set your necessary configuration and copy the JavaScript object to your code, as shown below.


generate your Selenium configuration using

Next, we created a driver using the configuration and capacity before performing the calculation with the LambdaTest grid using the 'calculateWithLambdaTest()' function.

Step 2: Performing the Operation.

First, we create an instance of the driver using the configurations above. Next, we open the webpage where the calculator is located using the 'driver.get()' function. Lastly, we find elements on the page using Selenium `findElement` function.


Step 2: Performing the Operation

Furthermore, still inside the ''calculateWithLambdaTest”' function, we used the 'sendKeys()' function to pass number input to the input element we retrieved using the `findElement` function as shown below:


we used the 'click()' function to submit

Lastly, we used the 'click()' function to submit the form and perform the calculation. To get the result of the calculation, we use the 'findElement(By.id('addmessage'))' to retrieve the result and the 'getText()' function to retrieve the text value of the result element.

...

Create Express Server

We create a simple Express server to test out the implementation manually before running the test using the Mocha unit testing framework.

First, install ExpressJS using the command below:


npm install express

Here is the output of the command:


Here is the output of the command

Lastly, we created a server.js file in the root directory and added the following code snippet to create a simple Express server.


const express = require('express');
const Calculator = require('./calculate');
const app = express();
const port = 3002;
app.use(express.json());
app.use(express.urlencoded({ extended: false }));


app.get('/calculate', async (request, response) => {
 try {
   const num1 = request.query?.num1 ?? 4;
   const num2 = request.query?.num2 ?? 6;
   const data = await Calculator.calculate(num1, num2);
   console.log(num1, num2, data);
   response.status(200).json(data);
 } catch (error) {
   response.status(500).json({
     message: 'Server error occurred',
   });
 }
});
app.listen(port, () => {
 console.log( 'Example app listening at http://localhost:${port}');
}); 

In the next section, we're going to explore how to test the Node.js applications using Mocha and ExpressJS.

...

Unit Testing with Mocha and ExpressJS

Lastly, open the tests/calculate.test.js file inside the repository to explore how to write real-world unit tests with the Mocha and Assert JavaScript framework.

Here is the code snippet:


const assert = require('assert');
const request = require('request');
let url;
beforeEach(async () => {
 url = 'http://localhost:3002/calculate';
});
describe('Search', () => {
 it('calculate the sum of two values', async () => {
   request(url, function (error, response, body) {
     assert.equal(response.statusCode, 200);
     assert.equal(body[0], 9);
     done();
   });
 });
 it('calculate the wrong sum of two values', async () => {
   request(url + '?num1=5&num2=6', function (error, response, body) {
     assert.equal(response.statusCode, 200);
     assert.not.equal(body[0], 9);
     done();
   });
 });
});

Lastly, we included all the other test cases inside the Describe block, each test case tests a particular behavior or implementation of a feature.

Running the Test

To run your test, type the following command into your root terminal.


npm start
npm run test 

After successfully performing running the test, you should be greeted with green passes for your test, like the screenshot below:


After successfully performing running the test

Until now, we have manually run the test with the command above to ensure that the test is passing before we go ahead with deployment.

We can also automate this process by leveraging the LambdaTest cloud grid, enabling the implementation of a test strategy during deployment.

LambdaTest is a digital experience testing platform that lets you perform manual and automation testing for web and mobile apps across 3000+ real browsers, devices, and operating system combinations.

With LambdaTest, you can run Mocha unit tests in parallel on a cloud-based grid, thereby accelerating your test execution cycles by multiple times. If you are looking to get started with automation testing using Mocha on LambdaTest, check our support documentation on Mocha testing with Selenium.

Summary

Software testing is a way to ensure that the software under test (SUT) conforms with the requirements during or after development. It is a very important aspect of software engineering as it reduces bugs and deployment of defective software products.

Mocha is one such tool, and it's a flexible JavaScript testing framework that makes testing simple and more flexible.

In this Mocha JavaScript tutorial, we learned why to use the Mocha framework and the different limitations of using Mocha. Lastly, we examined how to test a demo Node.js application with the Mocha unit testing framework.

Delve into our top Unit Testing Interview Questions guide, designed to help you excel in unit testing interviews. It covers a wide range of topics, from syntax to advanced techniques, with detailed solutions.

Frequently asked questions

  • General ...
What is Mocha testing?
Mocha testing refers to writing and executing test cases using the Mocha unit testing framework. Mocha is a popular JavaScript testing framework used primarily for Node.js applications, although it can also be used for browser-based testing. Mocha provides a flexible and feature-rich environment for testing JavaScript code, allowing developers to perform unit testing, integration testing, and functional testing.
Is Mocha used for unit testing?
Yes, Mocha is commonly used for unit testing in JavaScript. Unit testing involves testing individual units or components of code in isolation to ensure their correctness and functionality. Mocha provides a robust framework for organizing and executing unit tests, allowing developers to define test suites and test cases and perform assertions to validate the behavior of their code.
Which is better, Jest or Mocha?
The choice between Jest and Mocha depends on various factors and the specific requirements of your project. Both Jest and Mocha are popular JavaScript testing frameworks with their strengths and characteristics.
What is automated testing with Mocha?
Automated testing with Mocha refers to using the Mocha unit testing framework to automate the execution of tests and validate the behavior and functionality of JavaScript code. Mocha provides a flexible and feature-rich environment for writing and running automated tests, enabling developers to automate the testing process and improve software quality. In automated testing with Mocha, developers write test scripts using the Mocha framework to define test suites, test cases, and assertions. These test scripts can be executed automatically without manual intervention, allowing for efficient and repeatable testing.
What is the difference between Mocha.js and Selenium?
Mocha.js and Selenium are popular tools in software testing, but they serve different purposes and operate at different levels of the testing stack. Mocha.js is a testing framework primarily used for JavaScript unit testing. It provides a flexible environment for writing and executing tests, organizing test suites, and performing assertions to validate the behavior of JavaScript code. Selenium is a test automation framework used for the functional testing of websites and web applications. It provides a suite of tools and libraries for automating browser interactions, simulating user actions, and validating the functionality of web pages.

Author's Profile

...

Solomon Eseme

Solomon Eseme is an Software Engineer and Content Creator who is geared toward building high-performing and innovative products following best practices and industry standards. I also love writing about it at Masteringbackend.

Hubs: 06

  • Linkedin

Reviewer's Profile

...

Himanshu Sheth

Himanshu Sheth is a seasoned technologist and blogger with more than 15+ years of diverse working experience. He currently works as the 'Lead Developer Evangelist' and 'Senior Manager [Technical Content Marketing]' at LambdaTest. He is very active with the startup community in Bengaluru (and down South) and loves interacting with passionate founders on his personal blog (which he has been maintaining since last 15+ years).

  • Twitter
  • Linkedin

Did you find this page helpful?

Helpful

NotHelpful

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud