choosing a javascript testing framework

Choosing a JavaScript testing framework: Jest vs. Jasmine vs. Mocha

Before JS, verifying simple information meant a trip from the client, to a server, and back again. Internet connections at the time were extremely slow, so there was a pressing need for a good client-side scripting language. So, JS was a huge progression for the internet, allowing the client to do some of this validation without having to call a server. 

Since then, JS has continued to grow, blossoming into a full programming language that can handle difficult problems and interactions. It has become a giant in the developer community. 

While most full-featured modern languages can create tests without external dependencies, any language benefits from easy, robust, and simple testing frameworks. To save time or effort, developers often omit a robust testing suite in their codebases. But leaving out a testing suite is a huge mistake for anyone who wants to be able to easily maintain a codebase. Writing tests gives us more confidence that our code works, helps us make more sound code design decisions, and lets us check certain functionalities before we commit to our codebases.

In this article, we’ll compare three frameworks: Jest, Jasmine, and Mocha. All three frameworks are effective, giving developers the capability to create testing suites in their codebases. However, they each have their own ideal use cases, pros and cons, and feature sets. 

Let’s take a closer look at each framework and see how to create tests in each framework, so you can see whether Jest, Jasmine, or Mocha is right for your next project.

Comparing Javascript Testing Frameworks: Jest, Jasmine, and Mocha

Jest’s primary use is strong front-end testing. Its main goal is to be a zero-config framework, which it achieves by being built on top of one of the other frameworks we’re looking at today: Jasmine. The Jasmine-core package has no external dependencies, so any framework built on top of it gets easy access to a low-dependency package. 

Jest also pairs well with React apps. It’s the main in-house framework for JS testing with React at Facebook. 

The second framework, Jasmine, is great for both front-end and back-end testing. Jasmine also aims to be fast and to work right out of the box. However, as we’ll explore later, Jasmine’s front-end suite works better with Angular than it does with React. Jasmine is one of the oldest frameworks in the JavaScript community and has been a stable anchor for JS testing.

Mocha, the third framework we’re discussing, is probably the most flexible of the three. With a focus on simple creation and flexibility, Mocha is suitable for many different projects and fits into a variety of tech stacks. The main problem with Mocha is that it has more dependencies than the other two frameworks. 

Let’s explore each of these frameworks one by one. We’ll look at how each framework pairs with React, create short JS functions, and use each framework to test them, then examine the output of each test to compare all three.

Coding in Jest

Jest is automatically integrated into the famous create-react-app, so anyone building a React app this way can already run tests with Jest. If we happen to have a React project that wasn’t created with create-react-app, then there are a few dependencies to integrate. 

We need to install and configure the babel-jest package and the react babel preset to create a Jest testing environment. Following the Jest documentation, we start by running yarn add --dev jest babel-jest @babel/preset-env @babel/preset-react react-test-renderer.
package.json should look like the following code, with <current-version> being the actual latest version.

  "dependencies": {
	"react": "<current-version>",
	"react-dom": "<current-version>"
  },
  "devDependencies": {
	"@babel/preset-env": "<current-version>",
	"@babel/preset-react": "<current-version>",
	"babel-jest": "<current-version>",
	"jest": "<current-version>",
	"react-test-renderer": "<current-version>"
  },
  "scripts": {
	"test": "jest"
  }

Then, in babel.config.js, add the following:

module.exports = {
  presets: ['@babel/preset-env', '@babel/preset-react'],
};

We’re now ready to use Jest to test any React app, quickly and securely. Before we dive into coding our own testable function, let’s take a look at why Jest pairs best with React and some of the issues you may face when trying to integrate it with other frameworks. 

For example, to get Jest to work with an Angular project we need to: 

  • Add Jest to our project and edit the package.json file
  • Create a file to add Jest imports
  • Change more files to provide mocks for browser-specific APIs 
  • Remove Jasmine from the node_modules and add Jest

Getting Jest to work in an Angular app can be a headache, requiring multiple steps to achieve the results that come instantly when working with React. And, depending on the project, using Jest may not be the best way to create our tests. 

Now, let’s build a quick testable function in JavaScript and then test it using Jest. The code in this section can also be found in Jest documentation.

First, like any project, we need to make sure we stay organized. Create a project folder and call it JestTest. Next, make two files, sum.js and sum.test.js, so we can properly use and test our function. In your terminal, navigate to our project folder and run the following command:

yarn add --dev jest

or

npm install --save-dev jest

This will install Jest and create the package.json file that we will be adding to. Next, add the following simple code to the sum.js file:

function sum(a, b) {
  return a + b;
}
module.exports = sum;

Then, in sum.js.test, add the following test. It’s a simple Jest test that checks that the function outputs the correct values:

const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

Lastly, add the following to package.json (Jest may do this automatically when it’s initialized):

{
  "scripts": {
	"test": "jest"
  }
}

We can now run our test. In your terminal, enter yarn test or npm run test. Jest will output the following message:

PASS  ./sum.test.js
  ✓ adds 1 + 2 to equal 3 (2 ms)

Test Suites: 1 passed, 1 total
Tests:   	1 passed, 1 total
Snapshots:   0 total
Time:    	0.63 s
Ran all test suites.

We can see here that the test passed, meaning our function will always operate properly. Also, we can see that Jest completed this test in just two-thirds of a second. 

Jest is a great testing framework for any JavaScript codebase, working especially well with React. But if we’re working with another framework, like Angular, it might not be the right choice. So, let’s explore Jasmine, which is built into Angular.

Coding in Jasmine

Jasmine works best with Angular, much like Jest is most compatible with React. Any Angular app can use Jasmine to test its codebase—we simply use the Angular CLI to run ng test, which initiates the Karma test runner and outputs the results. 

Although the CLI app does most of the Jasmine and Karma configuration for us, we can still tweak the config by editing karma.conf.js at the root of our project. 

However, much like Jest, using Jasmine to test a non-Angular app requires lots more setup. For example, to test a React app using Jasmine, we need to install six different packages with the following command:

yarn add --dev @babel/core \
                 @babel/register \
                 babel-preset-react-app \
                 cross-env \
                 jsdom \
                 jasmine

Then, we have to initialize Jasmine within the project, configure it for Babel, create a simulated browser environment, and set up a react testing utility before we can run our first test. If you’re interested in learning more about this lengthy process, check out the detailed instructions

Now let’s create a simple function together and test it with Jasmine.

Jasmine requires a bit more setup than Jest. But, if we stay organized, we can get just as powerful results with ease. 

First, we need to create a project folder called “JasmineTest.” First, navigate to the project folder in the terminal. Once there, we run a series of commands starting with:

npm init

This command initializes the project using npm and creates a package.json file. Next, install Jasmine:

npm i --save-dev jasmine

This installs the necessary Jasmine dependencies to the project. Next, we need to add the following code to our package.json:

"scripts": {
"test": "jasmine"
},

After that, we need to initialize the testing suite:

npm test init

This configures the npm project to use Jasmine for testing. We’re now ready to create our simple function. 

Inside the main project folder, we create a file called helloWorld.js and add the following code. This code returns a hello world string and tells our spec file that the module is named helloWorld.

function helloWorld() {
    return "hello world";
};

module.exports = helloWorld;

Next, navigate to the spec folder and create a file called helloWorld.spec.js with the following code:

const helloWorld = require('../helloWorld.js');
 
describe("helloWorld", () => {
    it("returns hello world", () => {
      expect(helloWorld()).toBe("hello world");
    });
  });

This code is written using the Jasmine test structures. It simply expects the helloWorld file to return “hello world.” 
We’re now ready to run our test. The npm test command should give the following results alongside the random seed:

Started
.

1 spec, 0 failures
Finished in 0.004 seconds

The test (spec) passed with no failures in just a fraction of a second. The test finished much faster than Jest, like because there were no variables to handle and no additions to be made. 

Jasmine is a powerful Javascript testing framework, especially when paired with Angular. Its testing language is a bit more intricate than Jest, which is why it’s also great for backend testing. 

You might be looking for more flexibility than what Jest and Jasmine offer, though. This is where Mocha comes in. Let’s take a look at Mocha and how to use it.

Coding in Mocha

Unlike Jest and Jasmine, Mocha isn’t built on top of other core frameworks, nor is it natively built into any specific systems. This means that Mocha projects often require more packages than the other examples. However, although it requires more dependencies, Mocha is more flexible than the other frameworks we have looked at today. It’s also a very lightweight library.

Mocha is often used in combination with Chai, a BDD/TDD assertion library that we can use for performing JavaScript testing. Chai is a plug-and-play solution for Mocha, giving us a way to compare the output of our tests with their expected value. Additionally, Chai provides us with a clean syntax that’s intuitive and straightforward to read.

Let’s explore what’s possible when testing with Mocha, focusing on the relationship between Mocha and Node.js. We’re using Node.s because it provides a simple example and properly shows the simplicity that’s possible when using Mocha. 

Let’s create a simple Node.js server and test it with Mocha. 

To create our test with Node.js, we first have to install dependencies and start writing some code. Most of the code for this project can be found here, with slight alterations to fit our needs.

First, open your terminal and create a project folder:

mkdir mochaTest && cd mochaTest

Now, initialize package.json using npm:

npm init

When asked about a test command, enter ./node_modules/.bin/mocha. This ensures that our file knows to use Mocha as its testing suite. All other values can stay the same.
Next, we install the Express Node.js framework as the main dependency for the project. To do this, use the following command:

npm install express

Now we’re ready to create the web app that we’re going to test. Use the following basic express code to serve a Hello World body on localhost in index.js:

const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.send('Hello World')
})

app.listen(8080, function () {
  console.log('App listening on port 8080!')
})

You can now use the node index.js command to launch the app. Navigate to localhost:8080 in your browser to verify that it’s working. 

Next, add Mocha and Chai to our dependencies with the following command:

npm install mocha chai --save-dev

We’re ready to create the test.

First, create a test folder and a file to store the test with the following commands:

mkdir test && touch test/test-pages.js

Since we’re dealing with a website, we need to ensure the request package is installed.

npm install request --save-dev

Then, insert the following code into the test-pages file:

const expect  = require('chai').expect;
const request = require('request');

it('Main page content', function(done) {
    request('http://localhost:8080' , function(error, response, body) {
        expect(body).to.equal('Hello World');
        done();
    });
});

We can now run the website and, in another terminal tab, run npm test to receive the following results:

  ✔ Main page content

  1 passing (22ms)

This basic template can be used to expand your testing suite in many ways. 

Mocha is an extremely flexible Javascript testing framework that gives users the ability to test things like Node.js frameworks without emulating a browser, or test websites using Node.js.

Final Thoughts: Selecting Your Javascript Testing Framework

As developers, we need to select the best possible tech stacks and systems for every project we work on. In this article, we looked at the benefits and challenges of working with Jest, Jasmone, and Mocha. Here’s a quick overview of key takeaways:

  • Jest, optimally paired with React, is best for front-end development, but it isn’t ideal when paired with convoluted backend systems that require lots of dependencies.
  • Jasmine is optimally paired with Angular. It’s best used on complex backend systems that require a stable testing suite but might not be suitable for tough front-end frameworks that require lots of UI testing. 
  • Mocha, the most flexible of the three, is best when paired with simple projects and simple tests, but isn’t as strong in more technically complex projects where Jest or Jasmine would be a better fit. 

With this knowledge of Jest, Jasmine, and Mocha in your arsenal, you’re ready to determine which Javascript testing framework should be the go-to for your next project.

This blog post was created as part of the Mattermost Community Writing Program and is published under the CC BY-NC-SA 4.0 license. To learn more about the Mattermost Community Writing Program, check this out.

Read more about:

Jasmine javascript Jest Mocha.js QA Testing

Jarrett Azar is a computer scientist and a recent graduate of Muhlenberg College in Allentown, Pennsylvania. He double-majored in Computer Science and Studio Arts (with a focus on photography). Jarrett has a keen interest in a variety of topics, including computers, politics, and sports.