How to use Mocha/Chai to test Node.js apps
In this guide, we'll create a simple Node application with the Express.js framework, and cover it with Mocha/Chai tests. In the latter part of the article, we'll show you how to automate the testing using Buddy CI/CD.
What is Mocha framework
Mocha is a feature-rich JavaScript testing framework and one of the simplest suites for Node.js test cases available. It is designed for unit testing and integration testing, and supports both Test Driven Development (TDD) and Behavior Driven Development. Contrary to other frameworks, such as Jasmine or Jest, this test suite allows for flexible and accurate reporting, asynchronous testing, test coverage reports and can use any assertion library.
What is Chai library
Chai is a behavior and test-driven development library that which works perfectly well with Mocha – and Jasmine – frameworks. It allows you to make assertions about values, types, and behaviors in your tests, helping you verify the expected outcomes of your code.
Configuration
Install Node.js
Make sure you have the npm manager installed: nodejs.org/en/download/package-manager
Install npm and Mocha
Create a directory for the application:
bashmkdir myapp && cd myapp
$
Now, initalize npm. We'll use it to create a package.json
with 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
We shall use this framework to test the application.
You can confirm the rest of the values with enter.
Create Hello World with Express framework
To build the app, we'll use Express Node.js web application framework:
bashnpm install express --save
$
--save
adds this package to package.json
where all dependencies are stored.
TableMain 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.
Configuring unit tests with Mocha and Chai
Every application requires testing before the deployment to the server, especially a welcome site that determines the first impression. In this test case, we shall use Mocha as the test running framework, and Chai as the assertion library to apply unit testing to our application.
Install Mocha and Chai
Let's add Mocha and Chai packages to the package.json
:
bashnpm install mocha chai --save-dev
$
Add a test file
Time to define our first unit test. To keep things in order, we shall store all test files in a separate test directory:
bashmkdir test
$
Now, add the first test file:
bashtouch test/test-pages.js
$
The test script verifies the content of the website. For that, we need an HTTP client: https://npm.io/package/request
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 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
A very useful feature in Mocha testing is describe()
, a function that allows you to better control your tests by grouping them – like in this code 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. Looks like the results are 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 which provides a preconfigured test environment for your JavaScript code and speeds up configuration and running tests.
Version control
Before we get down to automation, though, 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
have been added to .gitignore
as dependencies should never be stored with 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 will streamline the whole testing process 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.
Additional resources
- 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.