Having worked as a Front End Developer for about five years now, testing code has always been the job of, well, someone else. At each of the previous tech companies I worked for in the past, there was developer that wrote the code and a QA person who reviewed it. However, I did at some point do visual or manual testing, but automated testing was usually handled by the QA Engineer. In my current role, the Developer and the QA Engineer are the same person. I am now responsible for writing and testing the code beyond the typical manual, visual testing.
In this blog, I will compare two popular testing frameworks -- Mocha and Jest -- and help you decide which one to get started with for unit testing in Node.js. Assuming you have previous Node.js knowlegde, I am going to share what I have learned about each testing framework and provide some insight into which one you would likely want to learn first. My goal is to supply the fundamentals of each framework so that someone without prior testing knowledge can understand and create unit tests. Let’s take a look at my definition of a "unit test" and then we will get the boat sailing while looking at both frameworks.
What Are Unit Tests?
Unit tests are essentially functions that test the functionality of your code. You could also say that unit test are functions that test other functions. The word “unit,” in my explanation, means that we are testing one unit of code at a time. In my opinion, unit testing is the easiest because you only have to focus on one single functionality at a time.
Here is a quick example of what I mean. If the function in your code is supposed to return a string, we can simply write a function to check if that function returns a string or not. If our test function concludes that the function returned a string, then the test passes. If our test function concludes that the function did NOT return a string, then the test fails. Here's another example. Let's say a function is supposed to return the number "10." We can write a function to check if that function returned the number "10." Same as the first example, if our test function concludes that the function returned the number "10," then the test passes. If our test function concludes that the function returned the number "6," then the test fails.
The Installation Process
Installing Mocha
$ npm install mocha
// Install with npm globally
$ npm install --global mocha
// Install as a dependency
$ npm install --save-dev mocha
Installing Jest
// Install with npm globally
$ npm install --global jest
// Install as a dependency
$ npm install --save-dev jest
As you can see above, when comparing the installation of the two testing frameworks, there is not much difference when using ‘npm’
to install. As we move on to the package.json file to verify our installation, we perform the same task of modifying our test value in the script to the name of the framework. See below --
"scripts": {
"test": "mocha"
},
"scripts": {
"test": "jest"
},
Similarly, when we run the test in our command line or terminal, we can use “npm test” for both testing frameworks.
$ npm test
When we move on to our project to write our first test, we do not need to import Mocha or Jest. We can start using either framework right away in our code without delay.
So far, everything seems the same. But next we head towards a fork in the road with Mocha and Jest, we need to look at how we actually test within the two frameworks. Now that we are all installed, let’s look at the functions we test with, starting with Mocha.
Mocha Testing Function
Mocha mainly use two functions to test code:
-
“Describe”
Function ( parameter one, parameter two ) -
“IT”
function ( parameter one, parameter two )
Each function has at least two parameters. The first parameter takes a string, while the second takes a function.
The Describe Function
The first parameter of the "Describe"
function is a string, which is the description of the function.
The second parameter of the "Describe"
function is a function.
describe('This is a string that describes the function', () => {
});
The “IT” Function
The first parameter of the “IT”
Function is a string that describes what is being tested.
The second parameter of the “IT”
Function is a function.
The “IT”
Function lives inside the “Describe”
function.
describe('This is a string that describes the function', () => {
it('This is a string that describes whats being tested', () => {
});
});
Are you with me so far? If so, let's begin our first test. Ready... Set... Let’s go!
Let's Begin Our Test!
In Mocha, we run our test inside the “IT”
function using assertions. Node.js does have built-in assertions, or you can use popular assertion libraries such as Should.js, Expect.js, or Chai. So, what exactly are "assertions?" In Layman's terms, I would say it’s simply a specialized function to test one object against another, one string against another, one function against another, one variable against another, or our actual results against our expected results, and so forth. The functions in our code that return something is usually called our actual result, in which we store in a variable called ‘results’
. What we believe the results of our function should return is usually stored in a variable called ‘expected’
.
Chai Assertion Library
I decided to use the Chai assertion library since it is one of the most popular out there. I alos have some experience using it. However, I will not be going into great detail with Chai to maintain this scope of comparing Mocha and Jest.
We install Chai in the command or terminal with “npm install chai”
. We also need to import Chai into our project to use it. We will be able to run multiple functions on our variable we named “assert”
, that is storing our Chai features.
// install
$ npm install chai
// bring in chai
const assert = require('chai').assert;
The first function I am going to run on the assert variable is “assert.equals”
, which takes two parameters.
One parameter with the actual result.
One parameter with the expected result.
// install
// bring in chai
assert.equal("result", "expected");
The “assert.equal”
function compares the first parameter with the second. If they are the same, the test passes. If they are different, the test fails. In the example above, two strings are being tested, “result”
and “expected”
. This test would fail because “result”
and “expected”
are two different strings. Let’s look at this example in more detail using variables for the two parameters.
describe('string that describes the function', () => {
it('string that describes the test', () => {
// Storing our expected results
// and actual results into variables
let result = "example string";
let expected = "example string";
// This assert function test if
// variables are equal
assert.equal(result, expected);
});
});
Here we created variables to hold the expected result and the actual result. We name one variable "expected" and another variable "result."
We use the “assert.equal”
function that takes two parameters or two variables and tests if they are equal. Can you guess if this test will pass or fail?
This test will pass because both strings are equal. This is one of many assertion functions that Chai offers that you can use to test. Let’s move on to Jest and see what it is all about.
Jest Testing Function
Are you still with me? Have I lost you yet? Do you remember Jest? Are you ready to begin comparing? Keep in mind the process needed to do to tests with Mocha.
With Jest, we only use one function. The “Test”
function takes two parameters.
The first parameter of the “Test”
function is a string that describes the test.
The second parameter of the “Test”
function is a function.
test('string that describes the test', () => {
});
Let’s Write Our First Test With Jest!
We run our test inside the “Test”
function. No need to install an assertion library; Jest comes equipped with its own testing tools. Jest allows us to use the “expect”
function, where we place our actual return results from the functions in our code. Then we can use a function called (.toBe)
, among many others, where we place our expected results. The (.toBe)
function is similar to the (assert.equal)
function in Mocha. The code below tests if both variables are equal.
test('string that describes the test', () => {
expect("result").toBe("expected");
});
Below we create variables to hold the expected result and the actual result. We name one variable ‘expected’
and another ‘result’.
Here we use the (expect)
and the (.toBe)
functions that take the two variables and tests if they are equal.
test('string that describes the test', () => {
// Storing our expected results
// and actual results into variables
let result = "example string";
let expected = "example string";
expect(result).toBe(expected);
});
This test should pass because both strings are equal.
Conclusion
Let’s recap by comparing 'apples' to 'apples' with what we learned in this blog. We learned that the process of getting started with both Mocha and Jest is similar. Then, when we began the actual testing process, things started to differ slightly.
The Key Differences Between Mocha and Jest
-
Mocha uses two functions to run test.
-
The “Describe” function
-
The “IT” function
-
-
Jest uses one function to run a test.
- The “Test” function
-
Mocha mainly uses third party libraries for testing functionality.
-
Jest has built-in testing functionality.
I must admit, we barely scratched the surface with unit testing in Mocha and Jest. Hopefully you now have a decent foundation, or at least the concepts of unit testing with both frameworks. Which one would you choose to get started unit testing with? Let me know why!