Mocha Chai Tutorial: How to Install & Test Node.js Apps
Mocha and Chai are the go-to duo for unit testing Node.js applications: Mocha runs your tests, Chai handles the assertions, and together they cover everything from simple equality checks to async HTTP calls. This tutorial shows you exactly how to install Mocha and Chai with npm, write your first test in under a minute, and automate the whole suite with Buddy CI/CD.
Quick Start: How to install Mocha and Chai
If you just need the install command, here it is. From your Node.js project root run:
bashnpm install mocha chai --save-dev$
Then wire up the test runner by adding a test script to your package.json:
json{ "scripts": { "test": "mocha" } }
Drop your specs into a test/ directory (Mocha picks them up by default) and run the suite with:
bashnpm test$
That's the entire setup. The rest of this guide explains what Mocha and Chai do, walks through a working Express.js example, and shows how to automate tests on every git push.
What is Mocha.js? The JavaScript testing framework
Mocha is a feature-rich JavaScript testing framework and one of the simplest test runners for Node.js available. It is designed for unit testing and integration testing, and supports both Test Driven Development (TDD) and Behavior Driven Development (BDD). Contrary to other frameworks such as Jasmine or Jest, Mocha allows for flexible and accurate reporting, asynchronous testing, test coverage reports, and can use any assertion library.
What is the Chai assertion library?
Chai is a BDD / TDD assertion library that works perfectly with Mocha (and Jasmine). It lets you make readable assertions about values, types, and behaviors in your tests, using interfaces like expect, should, and assert to verify the expected outcomes of your code.
Full setup: building a Node.js app to test
Install Node.js
Make sure you have npm installed: nodejs.org/en/download/package-manager.
Initializing the Node.js project
Create a directory for the application:
bashmkdir myapp && cd myapp$
Now initialize npm. We'll use it to create a package.json and add the Mocha framework:
bashnpm init$
When asked for the details of the application provide the following:
- name:
hello-world - entry point:
app.js - test command:
./node_modules/.bin/mocha
You can confirm the rest of the values with enter.
Create a Hello World app with Express
To build the app, we'll use the Express Node.js web application framework:
bashnpm install express --save$
--save adds this package to package.json where all dependencies are stored.
Main of Hello World
With everything installed, we can create app.js, a JS file with a simple HTTP server that will serve our Hello World website:
js//Load express module with `require` directive var express = require('express') var app = express() //Define request response in root URL (/) app.get('/', function (req, res) { res.send('Hello World') }) //Launch listening server on port 8080 app.listen(8080, function () { console.log('App listening on port 8080!') })
Run the app
The application is ready to launch:
bashnode app.js$
Go to http://localhost:8080/ in your browser to view it.
Writing Your First Mocha & Chai Test
Every application requires testing before deployment. Mocha runs your tests in Node.js; Chai handles the assertions. Together they give you a full stack for Mocha Chai unit testing. Below we set up both and write our first test.
Install Mocha and Chai with npm
If you skipped the Quick Start, add the Mocha and Chai packages as dev dependencies:
bashnpm install mocha chai --save-dev$
Mocha Chai unit testing: setup and first test
Time to define our first unit test. To keep things in order, we'll store all test files in a separate test directory:
bashmkdir test$
Now, add the first test file:
bashtouch test/test-pages.js$
Writing your first Chai test with Mocha: Chai is the assertion library (expect, should); Mocha is the test runner. Together, Mocha and Chai give you a full stack for unit testing in Node.js. In the sample below we use chai.expect to assert the response body and status.
The test script verifies the content of the website. For that, we need an HTTP client:
bashnpm install request --save-dev$
Our sample Mocha test file with the unit test should look like this now:
jsvar expect = require('chai').expect; var request = require('request'); it('Main page content', function(done) { request('http://localhost:8080' , function(error, response, body) { expect(body).to.equal('Hello World'); done(); }); });
Run Mocha tests in Node.js
Run the file to trigger the tests:
bashnpm test$
Image loading...
Let's add some more tests that will check the status of the homepage and /about page:
jsvar expect = require('chai').expect; var request = require('request'); it('Main page content', function(done) { request('http://localhost:8080' , function(error, response, body) { expect(body).to.equal('Hello World'); done(); }); }); it('Main page status', function(done) { request('http://localhost:8080' , function(error, response, body) { expect(response.statusCode).to.equal(200); done(); }); }); it('About page content', function(done) { request('http://localhost:8080/about' , function(error, response, body) { expect(response.statusCode).to.equal(404); done(); }); });
Run npm test again and see the results. The /about page is not ready yet, so it will return a 404:
Image loading...
Grouping tests with describe()
A very useful feature in Mocha testing is describe(), a function that lets you better organize your tests by grouping them, as in this snippet:
jsvar expect = require('chai').expect; var request = require('request'); describe('Status and content', function() { describe ('Main page', function() { it('status', function(done){ request('http://localhost:8080/', function(error, response, body) { expect(response.statusCode).to.equal(200); done(); }); }); it('content', function(done) { request('http://localhost:8080/' , function(error, response, body) { expect(body).to.equal('Hello World'); done(); }); }); }); describe ('About page', function() { it('status', function(done){ request('http://localhost:8080/about', function(error, response, body) { expect(response.statusCode).to.equal(404); done(); }); }); }); });
Run npm test yet again. The results look different now:
Image loading...
Automating Mocha tests
The main principle of CI is that every change to code should be automatically tested for errors. Contrary to popular belief, this does not mean employing a DevOps expert to set up a CI server and script the whole process in the terminal window.
Instead, you can use Buddy, a tool that provides a preconfigured test environment for your JavaScript code and speeds up configuration and running tests.
Version control
Before we get down to automation, we need to start with the very basis of CI/CD. All source code, including package.json, must first be put under version control.
bashgit init echo 'node_modules' > .gitignore git add . git commit -m 'my first commit'$$$$
node_modules has been added to .gitignore as dependencies should never be stored in the source code repository.
Now, if you want to cooperate on a project with other developers (and automate your tests) you need to add a remote location on your Git hosting service and push the code to it:
bashgit remote add origin URL git push origin --all$$
Pipeline configuration
With your project under version control, you can configure a pipeline that streamlines the whole testing process down to a git push. Configuration does not require scripting as it's fully visualized in the UI:
Image loading...
- Add a new pipeline and set the trigger mode to the git push event.
- Add the Node action and define your commands just like you did locally.
Live test results with Buddy
Want to see your Mocha test results in real time? Buddy offers a dedicated Mocha reporter that streams live results while your tests are running, with no more waiting for the entire suite to finish. It also automatically detects flaky and slow tests.
Check out the Unit Tests documentation to learn more, or jump straight to the Mocha reporter setup.
Mocha and Chai in Node.js: quick reference
- Install:
npm install mocha chai --save-dev - Run tests:
npm test(with"test": "mocha"inpackage.json) - Test files: put specs in
test/(e.g.test/*.js) so Mocha finds them by default - Docs: Mocha, Chai
Additional resources
- Unit Tests Overview - Real-time test results and analytics in Buddy
- Mocha Reporter Setup - Configure live reporting for Mocha
- How to configure a CI/CD pipeline for a Node project
- How to write Selenium tests in Node.js with WebdriverIO
- Testing JWT Secured Node and Express RESTful API with Chai and Mocha
Actions used in this guide:
Jarek Dylewski
Customer Support
A journalist and an SEO specialist trying to find himself in the unforgiving world of coders. Gamer, a non-fiction literature fan and obsessive carnivore. Jarek uses his talents to convert the programming lingo into a cohesive and approachable narration.