Testing with Node.js: Understand and Choose the Right Tools
Tags: javascript, node, testing, software
Published: 2023-08-15 16:39:06

---
title: Testing with Node.js: Understand and Choose the Right Tools
published: true
date: 2022-06-27 05:17:17 UTC
tags: javascript, nodejs, testing, software
canonical_url: https://blog.scalablebackend.com/testing-with-node-js-understand-and-choose-the-right-tools-98c0a33fb59a
---

![Testing](https://cdn.hashnode.com/res/hashnode/image/upload/v1692035737286/57638ca0-2cb3-47a2-b60e-96a22955e450.jpeg?w=1600&h=840&fit=crop&crop=entropy&auto=compress,format&format=webp)

If youre here today, there is a 99% chance you want to get started with testing in a higher-level environment, but lack the low-level knowledge. You might be working on Frontend or Backend with Node.js, but dont know where to start. Congratulations, youre in the right place.

### Test types

If you are not familiar with testing, you might get a bit lost. There are [a lot of test types](https://www.guru99.com/types-of-software-testing.html), but some are more common.

The [following article](https://www.atlassian.com/continuous-delivery/software-testing/types-of-software-testing) from Atlassian provides a good starting point.

As we will take our first step in the Node.js test environment, our scope will revolve around unit and integration tests.

### Different tools

Now, you might be wondering about **_where_** to start. Youve seen a Node.js project that uses Jest, heard about Mocha or Chai but you are not sure what those are about.

Great, thats exactly what we will be discussing today. To have a clearer picture, we can separate the different kinds of tools we need.

#### Test runners

You have this vague idea of writing tests but how do you organize and run them? This is the role of test runners. Some of their functionalities are:

- Finding test files and running tests

- Reporting a test success or failure

- Configuring which tests to run or re-run when updated

- Setting up an environment

And a lot more.

Here is a graph comparing the most popular Node.js test runners by download:

[![Node test runners](https://cdn.hashnode.com/res/hashnode/image/upload/v1692035729296/6ba3af3e-ae25-45be-9f68-0af02b391159.png)](https://www.npmtrends.com/jest-vs-mocha-vs-jasmine-vs-ava-vs-qunit)

#### Assertions

Now that you have an environment where you can write your tests, we come to the most important question: **How do I write my first test?**

From our previously cited article, Atlassian says the following about unit tests:

_They consist in testing individual methods and functions of the classes, components, or modules used by your software._

From a practical perspective you can view it as the following:

- Get the result from your individual unit (function for example) in a situation (with defined parameters).

- Ensure the given result match the expected one.

Thats what **assertions** are about: comparing the received result with the expected one to report the test as a success or failure.

Like tests runners, there are several libraries helping you with assertions:

[![Assertion libraries](https://cdn.hashnode.com/res/hashnode/image/upload/v1692035730923/94be6b53-27b6-4cbb-99e4-1f7173c6798f.png)](https://www.npmtrends.com/jest-vs-chai-vs-assert-vs-should-vs-better-assert-vs-unexpected)

#### Spies

With unit and integration testing comes a difficulty:

- You might want to unit test a function that relies on an external dependency.

- For unit as well as integration tests, your function can have a native dependency you cannot use in a JS environment.

- Your function is making an API call but your server is not set up in your testing environment.

Thats where spies are used. They help you create fakes (or [mock objects](https://en.wikipedia.org/wiki/Mock_object)) and replace dependencies with an object you defined.

In the same way, several spy libraries can help you:

[![Spy libraries](https://cdn.hashnode.com/res/hashnode/image/upload/v1692035732481/474b1fe4-fa7e-4ed7-9a7c-3320dce36593.png)](https://www.npmtrends.com/jest-vs-sinon-vs-jack-vs-testdouble)

### Making a choice

Great, you now have a general idea of what tools you need and a list of the most popular ones. Now comes the hardest part: which tools to choose?

#### Test runner

To be honest, I never really considered Jasmine, Ava, and QUnit.

I first started testing with Backend projects. At the time, Mocha was the more widely used, thats the only reason why I started using it (with Chai).

Mocha worked great for a few years and then two changes happened:

- I started to specialize in React

- Jest started to overthrow Mocha

[![Usage of Mocha vs Jest](https://cdn.hashnode.com/res/hashnode/image/upload/v1692035733957/0ec08f92-6e16-47fa-8dd9-fb5a217021e2.png)](https://www.npmtrends.com/jest-vs-mocha)

At this point, I had to do a serious comparison.

[Mocha](https://mochajs.org/#getting-started) is a test runner that lets you choose an external assertion and spy library. It doesnt restrict you but gives you more flexibility.

Jest is a whole testing framework, shipped with React and maintained by Facebook. From the previous sections and graphs, you might have noticed that more than a test runner, Jest includes its own assertion and mock libraries.

Its interesting to note that Jest was built on top of Jasmine.

{% embed https://jestjs.io/ %}

Both are very similar. Of course, their APIs change, and you need to get used to it when going from one to the other.

Im a big fan of having a single library/framework/utility that fulfills a given role. After trying out Jest and experimenting with React, I definitely adopted it.

### Afterward

Once you understand how to write tests, your best move would be to write **_great_** tests.

[Test-Driven Development](https://en.wikipedia.org/wiki/Test-driven_development) is a software development process that will definitely help you in writing great tests. Another useful tool is [Code Coverage](https://www.atlassian.com/continuous-delivery/software-testing/code-coverage).

I would like to complete the article from Atlassian on Code Coverage by saying the following:

_If your Code Coverage is below 100% you can be sure you didnt test everything. If its 100% you dont know._

Code Coverage can tell you if your code has been executed during your tests. Sometimes, youll end up executing code without really testing it. To be sure that you really tested everything, you must resort to [Mutation Testing](https://en.wikipedia.org/wiki/Mutation_testing).

{% embed https://stryker-mutator.io/ %}

Mutation Testing is great but really expensive, and cannot be used as much as unit/integration testing.

Once you get into testing, you often see the following pyramid:

![Testing Pyramid](https://cdn.hashnode.com/res/hashnode/image/upload/v1692035735285/ee08cab4-5c37-4090-b7a1-82a83e798b53.png)

What this represents is how many tests you should have. As unit tests are cheap to write and run, you should have plenty of them.

Still cheap but less than unit tests are: integration tests. Its expected for an application to have a lot of integration tests but less than unit tests.

Finally, youll have e2e tests but in fewer numbers, as those are expensive to set up, write, and run.

Good luck on your testing journey.

* * *

Cover photo by [flowforfrank](https://unsplash.com/@flowforfrank) on [Unsplash](https://unsplash.com/s/photos/code-test)