SuperAgent driven library for testing HTTP servers
Supertest is a Node.js library that enables testing of HTTP servers by simulating requests and asserting responses without requiring a live server instance. Built on top of the SuperAgent HTTP client library, it provides a high-level abstraction specifically designed for integration and end-to-end testing of REST APIs. With over 9 million weekly downloads, it's become the de facto standard for HTTP testing in the Node.js ecosystem.
The library's primary value proposition is eliminating the need to spin up a separate server process during testing. For frameworks like Express, Koa, or raw Node.js HTTP servers, Supertest can invoke your application's request handlers directly, making tests faster to execute and simpler to set up in CI/CD pipelines. This approach also avoids port conflicts and reduces test infrastructure complexity.
Supertest is framework-agnostic and integrates seamlessly with popular test runners like Jest, Mocha, Vitest, and Jasmine. Its chainable API allows you to construct readable test assertions that validate status codes, headers, response bodies, and more in a fluent syntax. The library fully supports modern JavaScript patterns including async/await and Promises, making it straightforward to test asynchronous API operations.
Developers use Supertest across the stack—from small open-source projects to enterprise applications—whenever they need reliable, maintainable HTTP API tests. It's particularly common in Node.js backend development where Express or similar frameworks power REST or GraphQL APIs that require thorough integration testing coverage.
const request = require('supertest');
const express = require('express');
const app = express();
app.use(express.json());
app.get('/api/users/:id', (req, res) => {
res.json({ id: req.params.id, name: 'John Doe', email: 'john@example.com' });
});
app.post('/api/users', (req, res) => {
if (!req.body.email) {
return res.status(400).json({ error: 'Email required' });
}
res.status(201).json({ id: '123', ...req.body });
});
describe('User API', () => {
test('GET /api/users/:id returns user data', async () => {
const response = await request(app)
.get('/api/users/42')
.expect('Content-Type', /json/)
.expect(200);
expect(response.body.id).toBe('42');
expect(response.body.name).toBe('John Doe');
});
test('POST /api/users creates user with valid data', async () => {
await request(app)
.post('/api/users')
.send({ name: 'Jane Smith', email: 'jane@example.com' })
.set('Authorization', 'Bearer token123')
.expect(201)
.expect((res) => {
expect(res.body.email).toBe('jane@example.com');
expect(res.body.id).toBeDefined();
});
});
test('POST /api/users returns 400 without email', async () => {
await request(app)
.post('/api/users')
.send({ name: 'Invalid User' })
.expect(400)
.expect({ error: 'Email required' });
});
});Testing Express REST APIs: Validate that your Express routes return correct status codes, headers, and JSON payloads. Supertest can test authentication flows, input validation, error handling, and response formatting without deploying your application to a test server.
Integration testing database operations: Test the full request-response cycle including database reads and writes. You can make a POST request to create a resource, verify the 201 response, then make a GET request to confirm the data was persisted correctly, all within a single test suite.
Testing file uploads and multipart requests: Verify that your API correctly handles file uploads by using Supertest's .attach() method to simulate multipart form data submissions. This is essential for testing avatar uploads, document processing endpoints, or any file-handling API.
CI/CD pipeline testing: Run comprehensive API test suites in continuous integration environments without the overhead of managing separate server processes. Supertest's direct invocation approach makes it ideal for automated testing in GitHub Actions, GitLab CI, or Jenkins.
Testing middleware behavior: Validate that authentication middleware, rate limiting, CORS configuration, and custom middleware chains work correctly by making requests that should trigger specific middleware logic and asserting the expected behavior in responses.
npm install supertestpnpm add supertestbun add supertest