Skip to content

Guide · Open source

How to use supertest: install and write HTTP tests for Node.js

Updated · written with AI from the project's own documentation and checked against our catalogue data

Supertest is an open-source JavaScript library for testing Node.js HTTP servers. You give it an Express-style app or a URL, chain requests and assertions together, and it checks status codes, headers, cookies and response bodies. This guide shows you how to install it, write your first test, and use the common patterns for mocha, promises, async/await, cookies and file uploads.

supertestforwardemail/supertest · ★ 14.4k · MIT

Quick start

  1. 1Install supertest. Run npm install supertest --save-dev in your Node.js project. Node.js and npm are required.
  2. 2Load your app. In your test file, require supertest and pass your Express app or HTTP server to request().
  3. 3Chain a request. Call a method such as .get() or .post() and give it the route path you want to test.
  4. 4Add expectations. Add .expect() calls for status codes, headers, or body content. They run in the order you define them.
  5. 5Finish the test. Use done with .expect(status, done), return a promise, or use async/await. In .end(), pass any error to done().
  6. 6Run your test runner. Run your tests with your chosen framework, such as mocha, to see which assertions pass or fail.

Install supertest with npm

Supertest is installed as an npm package and saved as a development dependency, since it is used only by your tests. You need Node.js and npm available on your machine.

Once installed, you load it with require('supertest') in your test files.

  • Prerequisites: Node.js and npm
  • Install as a dev dependency with the command below
npm install supertest --save-dev

Write your first supertest request

Pass your app to request() and chain a method such as get or post. Each .expect() call adds an assertion. If the server is not already listening, supertest binds it to an ephemeral port for you, so you do not need to manage port numbers.

The example below uses Express. Any Node.js HTTP server that request() accepts works the same way. The example runs without a test framework; when a check fails, .end() passes the error to its callback, so you must rethrow it or pass it to done() to fail a test.

  • You can pass an http.Server or a Function to request()
  • Calling request() with a URL string targets an existing server instead
const request = require('supertest'); const express = require('express'); const app = express(); app.get('/user', function(req, res) { res.status(200).json({ name: 'john' }); }); request(app) .get('/user') .expect('Content-Type', /json/) .expect('Content-Length', '15') .expect(200) .end(function(err, res) { if (err) throw err; });

Use supertest with mocha

Supertest works with any test framework. The README shows mocha, where you pass done straight to an .expect() call. If an assertion fails, the test fails.

For POST requests, use .send() to set the request body. Assertions that fail inside .end() are returned as errors, so pass err to done() to fail the test.

  • Pass done directly to .expect(status, done) to end the test
  • In .end(), call return done(err) when err is set
  • Use .set('Accept', 'application/json') to set request headers
describe('POST /users', function() { it('responds with json', function(done) { request(app) .post('/users') .send({name: 'john'}) .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(200) .end(function(err, res) { if (err) return done(err); return done(); }); }); });

Use promises or async/await

If you prefer not to use done callbacks, return the request chain from the test, or await it. The awaited response exposes headers, status and body, so you can check them with your assertion library's functions.

The README notes that expectations run in the order you define them, which lets you change the response before a later check.

describe('GET /users', function() { it('responds with json', async function() { const response = await request(app) .get('/users') .set('Accept', 'application/json'); expect(response.headers["content-type"]).toMatch(/json/); expect(response.status).toEqual(200); expect(response.body.email).toEqual('foo@bar.com'); }); });

Test cookies and sessions with an agent

Use request.agent(app) to create an agent that stores and resends cookies across requests. This is how you test a login flow or any route that sets a cookie and expects it back later.

The README also shows setting several cookies on one request with the .set('Cookie', ...) header.

  • request.agent(app) keeps cookies between calls
  • Assert set-cookie headers with .expect('set-cookie', ...)
const agent = request.agent(app); it('should save cookies', function(done) { agent .get('/') .expect('set-cookie', 'cookie=hey; Path=/', done); });

Send file uploads and HTTP options

Because supertest is built on superagent, you can use superagent methods such as .field() and .attach() for multipart uploads. The README also shows how to enable HTTP/2 by passing { http2: true } as an option to request() or request.agent(), and how to pass HTTP basic credentials with .auth().

  • Multipart upload methods: .field() and .attach()
  • Basic auth: .auth('username', 'password')
  • HTTP/2: pass { http2: true } to request() or request.agent()
request(app) .post('/') .field('name', 'my awesome avatar') .attach('avatar', 'test/fixtures/avatar.jpg')

What people use it for

  • Checking that a GET route returns status 200 and JSON content
  • Testing that a POST endpoint accepts a form body and returns the expected response
  • Verifying that a login route sets a cookie and that a later request can read it
  • Testing a file upload endpoint with a multipart attachment
  • Checking response headers such as Content-Length on API routes

Frequently asked questions

Is supertest free to use?

Yes. The repository is published under the MIT licence. Check the LICENSE file in the repository for the full terms.

What do I need to install supertest?

You need Node.js and npm. Install supertest as a development dependency with npm install supertest --save-dev.

Can I use supertest without Express?

The README's examples use Express, but request() accepts an http.Server or a Function, so it works with other Node.js HTTP servers. It can also target a URL.

Does supertest work with mocha and Jest?

The README says supertest works with any test framework and shows an example with mocha. It also shows promise and async/await patterns that fit any runner that supports them.

Can supertest test a browser-based app?

No. The README describes HTTP-level testing rather than browser automation, so it does not drive a browser. Use a browser-based end-to-end tool for that.

How does supertest compare to superagent, axios or fastify inject?

Supertest is built on top of superagent and adds a test-focused chain of expect assertions. Superagent and axios are general HTTP clients, while fastify inject is a testing helper for Fastify servers only.

New agent skills, repos and AI tools — every week

The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.

Our verdict

Supertest suits Node.js developers who want readable, chainable tests for HTTP routes, headers, cookies and uploads, especially with Express and a runner like mocha. It is not the right choice if you need browser end-to-end testing or a test framework included with the tool, and it only applies to Node.js HTTP servers.

Install options & downloads