 Wonder how to write tests for you API. Well you can use [SuperTest](https://www.npmjs.com/package/supertest) which is can be used to test HTTP endpoints. Before starting **SuperTest** let’s create a simple API using node + express. In express let’s use the the route given to us by them in order to learn **SuperTest** library. This article is not focusing on crating a rest API using express framework. Let’s go to the /routes/users.js file and create some endpoints. **var** express = require('express'); **var** router = express.Router(); _/\*\* \* get all users \*/ _router.get('/', **function** (req, res, next) { **return** res.json('all users sent'); }); _/\*\* \* Get a specific user \*/ _router.get('/:id', **function** (req, res, next) { **if** (req.params.id === 'U001') { // just to demo **return** res.json("user U001 found"); } **return** res.status(404).json('user not found'); }); _/\*\* \* Add a user \*/ _router.post('/', **function** (req, res, next) { **let** content = req.body; **if** (content.id) { //just to demo **return** res.status(201).json("user created"); } **return** res.status(400).json('user not created'); }); module.exports = router; I’ve crated two simple get methods to fetch user data and a post method to save a user. LOL, I was kidding there’s no actual database integration or save functionality just sending some JSON outputs based on some dummy logic 😹 and status codes to test our API. You can create a real working API. But remember to send relevant [HTTP status codes](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) so it’s easy when writing unit tests later. Now let’s focus on writing API tests using **SuperTest**. First you need to install the dependency as a devDependancy. npm install supertest --save-dev This will include mocha as well because super test use mocha test framework. But you don’t need to install it it comes with **supertest**. Then lets create a directory called _test_ in the root level of the project and create a file called _apiTest.js._ This file is the file where we write the API tests. First thing we need is the supertest module. //apiTest.js const request = require('supertest'); Then we need to pass the http.Server to the request() method of supertest. To do that let’s include our express app as follows. //apiTest.js const request = require('supertest'); const app = require('../app'); //reference to you app.js file The let’s write the first API test to test the [http://localhost:3000/users](http://localhost:3000/users) endpoint . If this endpoint works correctly it should return status code 200. That’s how the user route file is implemented . See the following code res.json() will automatically set the status code 200. So no worries. _//from users.js route file /\*\* \* get all users \*/ _router.get('/', **function** (req, res, next) { **return** res.json('all users sent'); }); Ok, how we write the test for this route in out apiTest.js using supertest. //apiTest.js**const** request = require('supertest'); **const** app = require('../app'); //==================== user API test ==================== _/\*\* \* Testing get all user endpoint \*/ _describe('GET /users', **function** () { it('respond with json containing a list of all users', **function** (done) { request(app) .get('/users') .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(200, done); }); }); Here **describe** method is coming from mocha test framework. We simply specify the endpoint name as the first argument and then the function to write the test case. Here Mocha **describe**() is for grouping the test cases while **it**() is used to write the real test cases. We give a simple description of what we are going to test as the first argument in it() function. Then the callback function to be called. **request**() needs the HTTP.server so we pass our express app reference. Then in **get**() we specify the route endpoint. Here we are in the app so can omit [http://localhost:3000/](http://localhost:3000/) part. Just give the route endpoint. in **set**() we set the HTTP header attributes. Then in **expect**() we check for the return values including Header values and body values. In this example we check whether the returned content type is JSON. Because we send the response as JSON using res.json() method. Then expect(200) is to check the returned status code is equal to 200. Then we end the test by calling _done_ our callback function. Right so far so good. But how can we run this tests. Well you have to use make this change in your _package.json_ file. "scripts": { "start": "node ./bin/www", "test": "mocha 'test/apiTest.js'" //path to your test file } Now you can run the test cases by simply using \> npm test After running the test file you’ll see this output. \> mocha 'test/apiTest.js' GET /users GET /users 200 5.289 ms - 16 ✓ respond with json containing a list of all users 1 passing (38ms) Let’s continue writing more test cases of all the endpoints in the users.js file. **const** request = require('supertest'); **const** app = require('../app'); //==================== user API test ==================== _/\*\* \* Testing get all user endpoint \*/ _describe('GET /users', **function** () { it('respond with json containing a list of all users', **function** (done) { request(app) .get('/users') .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(200, done); }); }); _/\*\* \* Testing get a user endpoint by giving an existing user \*/ _describe('GET /user/:id', **function** () { it('respond with json containing a single user', **function** (done) { request(app) .get('/users/U001') .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(200, done); }); }); _/\*\* \* Testing get a user endpoint by giving a non-existing user \*/ _describe('GET /user/:id', **function** () { it('respond with json user not found', **function** (done) { request(app) .get('/users/idisnonexisting') .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(404) //expecting HTTP status code .expect('"user not found"') // expecting content value .end((err) => { **if** (err) **return** done(err); done(); }); }); }); _/\*\* \* Testing post user endpoint \*/ _describe('POST /users', **function** () { **let** data = { "id": "1", "name": "dummy", "contact": "dummy", "address": "dummy" } it('respond with 201 created', **function** (done) { request(app) .post('/users') .send(data) .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(201) .end((err) => { **if** (err) **return** done(err); done(); }); }); }); _/\*\* \* Testing post user endpoint \*/ _describe('POST /users', **function** () { **let** data = { //no id "name": "dummy", "contact": "dummy", "address": "dummy" } it('respond with 400 not created', **function** (done) { request(app) .post('/users') .send(data) .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(400) .expect('"user not created"') .end((err) => { **if** (err) **return** done(err); done(); }); }); }); If you look closely at the code in _apiTest.js_ file you’ll get the rhythm. I’ve only showed GET and POST methods but you can try PUT and DELETE methods with real working API. If you run this test file using _npm test_ command finally you’ll see an output like this. \> mocha 'test/apiTest.js' GET /users GET /users 200 5.610 ms - 16 ✓ respond with json containing a list of all users GET /user/:id GET /users/U001 200 0.870 ms - 17 ✓ respond with json containing a single user GET /user/:id GET /users/idisnonexisting 404 0.458 ms - 16 ✓ respond with json user not found POST /users POST /users 201 10.196 ms - 14 ✓ respond with 201 created POST /users POST /users 400 0.607 ms - 18 ✓ respond with 400 not created 5 passing (62ms) Better to refer [https://github.com/visionmedia/supertest](https://github.com/visionmedia/supertest) for more knowledge.