Convert Figma logo to code with AI

ladjs logosupertest

🕷 Super-agent driven library for testing node.js HTTP servers using a fluent API. Maintained for @forwardemail, @ladjs, @spamscanner, @breejs, @cabinjs, and @lassjs.

13,744
758
13,744
177

Top Related Projects

Ajax for Node.js and browsers (JS HTTP client). Maintained for @forwardemail, @ladjs, @spamscanner, @breejs, @cabinjs, and @lassjs.

105,172

Promise based HTTP client for the browser and node.js

25,682

🏊🏾 Simplified HTTP request client.

14,189

🌐 Human-friendly and powerful HTTP request library for Node.js

A light-weight module that brings the Fetch API to Node.js

6,827

Newman is a command-line collection runner for Postman

Quick Overview

Supertest is a popular Node.js library for testing HTTP servers. It provides a high-level abstraction for testing HTTP, making it easier to send requests and assert responses in your tests. Supertest is often used in combination with testing frameworks like Mocha or Jest.

Pros

  • Easy to use and intuitive API
  • Supports both callback and promise-based testing
  • Integrates well with various Node.js testing frameworks
  • Allows for testing of both Express applications and raw Node.js http servers

Cons

  • Limited to testing HTTP servers only
  • May not be suitable for complex API testing scenarios
  • Doesn't provide built-in support for authentication or session management
  • Can be slower compared to unit tests due to the nature of HTTP requests

Code Examples

  1. Basic GET request test:
const request = require('supertest');
const app = require('../app');

describe('GET /users', function() {
  it('responds with json', function(done) {
    request(app)
      .get('/users')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200, done);
  });
});
  1. POST request with data:
const request = require('supertest');
const app = require('../app');

describe('POST /users', function() {
  it('creates a new user', function(done) {
    request(app)
      .post('/users')
      .send({ name: 'John Doe', email: 'john@example.com' })
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(201)
      .end(function(err, res) {
        if (err) return done(err);
        expect(res.body.name).to.equal('John Doe');
        done();
      });
  });
});
  1. Using async/await:
const request = require('supertest');
const app = require('../app');

describe('GET /users/:id', function() {
  it('responds with user details', async function() {
    const response = await request(app)
      .get('/users/1')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200);

    expect(response.body.id).to.equal(1);
    expect(response.body.name).to.be.a('string');
  });
});

Getting Started

To use Supertest in your project, follow these steps:

  1. Install Supertest:
npm install supertest --save-dev
  1. In your test file, require Supertest and your app:
const request = require('supertest');
const app = require('../app');
  1. Write your tests using Supertest:
describe('GET /', function() {
  it('responds with 200', function(done) {
    request(app)
      .get('/')
      .expect(200, done);
  });
});
  1. Run your tests using your preferred test runner (e.g., Mocha, Jest).

Competitor Comparisons

Ajax for Node.js and browsers (JS HTTP client). Maintained for @forwardemail, @ladjs, @spamscanner, @breejs, @cabinjs, and @lassjs.

Pros of Superagent

  • More versatile and feature-rich for general HTTP requests
  • Supports both Node.js and browser environments
  • Offers a chainable API for building complex requests

Cons of Superagent

  • Larger library size, which may impact performance in some scenarios
  • Steeper learning curve due to more extensive API
  • Not specifically designed for testing, unlike Supertest

Code Comparison

Superagent:

const superagent = require('superagent');

superagent
  .get('/api/users')
  .query({ limit: 10 })
  .end((err, res) => {
    // Handle response
  });

Supertest:

const request = require('supertest');
const app = require('./app');

request(app)
  .get('/api/users')
  .query({ limit: 10 })
  .expect(200)
  .end((err, res) => {
    // Assert response
  });

Summary

Superagent is a more general-purpose HTTP client library, while Supertest is specifically designed for testing HTTP servers. Superagent offers more flexibility and features for making various types of HTTP requests, but Supertest provides a simpler API focused on testing Express.js applications. The choice between the two depends on the specific use case, with Supertest being more suitable for testing scenarios and Superagent for broader HTTP client needs.

105,172

Promise based HTTP client for the browser and node.js

Pros of Axios

  • Supports both browser and Node.js environments
  • Provides automatic request and response transformations
  • Offers built-in CSRF protection and request cancellation

Cons of Axios

  • Larger bundle size compared to Supertest
  • More complex setup for simple API testing scenarios
  • Lacks some specific testing-focused features present in Supertest

Code Comparison

Axios:

const axios = require('axios');

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Supertest:

const request = require('supertest');
const express = require('express');

const app = express();

request(app)
  .get('/user')
  .query({ ID: 12345 })
  .expect(200)
  .end(function(err, res) {
    if (err) throw err;
  });

Summary

Axios is a versatile HTTP client for both browser and Node.js, offering features like request/response transformations and CSRF protection. It's well-suited for general-purpose API interactions. Supertest, on the other hand, is specifically designed for testing HTTP servers, providing a more streamlined API for asserting HTTP responses in test environments. While Axios offers broader functionality, Supertest excels in simplicity for API testing scenarios.

25,682

🏊🏾 Simplified HTTP request client.

Pros of Request

  • More versatile and can be used for various HTTP requests beyond testing
  • Supports a wider range of HTTP methods and features
  • Has a larger ecosystem of plugins and extensions

Cons of Request

  • Requires more setup and configuration for testing purposes
  • Less focused on testing-specific features
  • Deprecated and no longer actively maintained

Code Comparison

Request:

const request = require('request');

request('http://www.example.com', (error, response, body) => {
  console.log('statusCode:', response && response.statusCode);
  console.log('body:', body);
});

Supertest:

const request = require('supertest');
const express = require('express');
const app = express();

request(app)
  .get('/')
  .expect(200)
  .end((err, res) => {
    if (err) throw err;
  });

Summary

While Request is more versatile for general HTTP requests, Supertest is specifically designed for testing HTTP servers. Supertest provides a more streamlined and testing-focused API, making it easier to write and maintain tests for Express applications. Request, on the other hand, offers more flexibility for various HTTP-related tasks but requires more setup for testing scenarios. It's worth noting that Request is deprecated, which may impact its long-term viability for new projects.

14,189

🌐 Human-friendly and powerful HTTP request library for Node.js

Pros of Got

  • More feature-rich HTTP client with support for various protocols (HTTP, HTTPS, HTTP2)
  • Built-in request retrying and pagination support
  • Extensive documentation and active community support

Cons of Got

  • Steeper learning curve due to more advanced features
  • Larger package size compared to SuperTest
  • May be overkill for simple API testing scenarios

Code Comparison

SuperTest:

const request = require('supertest');
const app = require('../app');

request(app)
  .get('/users')
  .expect(200)
  .end((err, res) => {
    if (err) throw err;
  });

Got:

const got = require('got');

(async () => {
  try {
    const response = await got('http://example.com/users');
    console.log(response.body);
  } catch (error) {
    console.error(error);
  }
})();

Summary

SuperTest is specifically designed for testing HTTP servers and is often used in conjunction with testing frameworks like Mocha. It provides a simple and intuitive API for making assertions about HTTP responses.

Got, on the other hand, is a more general-purpose HTTP client with a wider range of features. It's suitable for both testing and production use cases, offering advanced functionality like request retrying, pagination, and support for various protocols.

Choose SuperTest for straightforward API testing in Node.js applications, especially when working with Express.js. Opt for Got when you need a more powerful HTTP client with additional features and flexibility across different scenarios.

A light-weight module that brings the Fetch API to Node.js

Pros of node-fetch

  • Lightweight and focused on HTTP requests, making it more versatile for various use cases
  • Implements the Fetch API, providing a familiar interface for developers coming from browser-based JavaScript
  • Supports both CommonJS and ES modules, offering flexibility in different Node.js environments

Cons of node-fetch

  • Requires more setup and configuration for testing scenarios compared to SuperTest
  • Lacks built-in assertion methods, necessitating additional libraries for test assertions
  • May require more code to handle complex testing scenarios, especially for API testing

Code Comparison

node-fetch:

import fetch from 'node-fetch';

const response = await fetch('https://api.example.com/data');
const data = await response.json();
expect(response.status).toBe(200);
expect(data).toHaveProperty('id');

SuperTest:

const request = require('supertest');
const app = require('../app');

request(app)
  .get('/api/data')
  .expect(200)
  .expect('Content-Type', /json/)
  .end((err, res) => {
    expect(res.body).toHaveProperty('id');
  });

Summary

node-fetch is a versatile HTTP client library that closely mimics the browser's Fetch API, making it suitable for various HTTP requests in Node.js. SuperTest, on the other hand, is specifically designed for testing HTTP servers, offering a more streamlined approach to API testing with built-in assertion methods. While node-fetch provides more flexibility, SuperTest excels in simplifying the process of writing and running API tests.

6,827

Newman is a command-line collection runner for Postman

Pros of Newman

  • Supports running Postman collections, allowing for easy integration with existing Postman workflows
  • Provides a command-line interface for automation and CI/CD integration
  • Offers detailed reporting options, including JUnit XML and HTML formats

Cons of Newman

  • Requires Postman collections, which may not be suitable for all testing scenarios
  • Less flexible for custom JavaScript-based assertions compared to SuperTest
  • Steeper learning curve for those unfamiliar with Postman's ecosystem

Code Comparison

SuperTest:

const request = require('supertest');
const app = require('../app');

request(app)
  .get('/users')
  .expect(200)
  .end((err, res) => {
    if (err) throw err;
  });

Newman:

const newman = require('newman');

newman.run({
    collection: require('./my-collection.json'),
    environment: require('./my-environment.json'),
    reporters: 'cli'
}, function (err) {
    if (err) { throw err; }
});

Summary

SuperTest is more lightweight and integrates seamlessly with Node.js applications, making it ideal for unit and integration testing of Express-based APIs. Newman, on the other hand, leverages Postman collections for comprehensive API testing, offering robust reporting and CI/CD integration. The choice between the two depends on your existing workflow, testing requirements, and preference for JavaScript-based assertions versus Postman's GUI-driven approach.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

SuperTest

code coverage Build Status Dependencies PRs Welcome MIT License

HTTP assertions made easy via superagent. Maintained for Forward Email and Lad.

About

The motivation with this module is to provide a high-level abstraction for testing HTTP, while still allowing you to drop down to the lower-level API provided by superagent.

Getting Started

Install SuperTest as an npm module and save it to your package.json file as a development dependency:

npm install supertest --save-dev

Once installed it can now be referenced by simply calling require('supertest');

Example

You may pass an http.Server, or a Function to request() - if the server is not already listening for connections then it is bound to an ephemeral port for you so there is no need to keep track of ports.

SuperTest works with any test framework, here is an example without using any test framework at all:

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;
  });

To enable http2 protocol, simply append an options to request or request.agent:

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, { http2: true })
  .get('/user')
  .expect('Content-Type', /json/)
  .expect('Content-Length', '15')
  .expect(200)
  .end(function(err, res) {
    if (err) throw err;
  });

request.agent(app, { http2: true })
  .get('/user')
  .expect('Content-Type', /json/)
  .expect('Content-Length', '15')
  .expect(200)
  .end(function(err, res) {
    if (err) throw err;
  });

Here's an example with mocha, note how you can pass done straight to any of the .expect() calls:

describe('GET /user', function() {
  it('responds with json', function(done) {
    request(app)
      .get('/user')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200, done);
  });
});

You can use auth method to pass HTTP username and password in the same way as in the superagent:

describe('GET /user', function() {
  it('responds with json', function(done) {
    request(app)
      .get('/user')
      .auth('username', 'password')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200, done);
  });
});

One thing to note with the above statement is that superagent now sends any HTTP error (anything other than a 2XX response code) to the callback as the first argument if you do not add a status code expect (i.e. .expect(302)).

If you are using the .end() method .expect() assertions that fail will not throw - they will return the assertion as an error to the .end() callback. In order to fail the test case, you will need to rethrow or pass err to done(), as follows:

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();
      });
  });
});

You can also use promises:

describe('GET /users', function() {
  it('responds with json', function() {
    return request(app)
      .get('/users')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200)
      .then(response => {
         expect(response.body.email).toEqual('foo@bar.com');
      })
  });
});

Or async/await syntax:

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');
  });
});

Expectations are run in the order of definition. This characteristic can be used to modify the response body or headers before executing an assertion.

describe('POST /user', function() {
  it('user.name should be an case-insensitive match for "john"', function(done) {
    request(app)
      .post('/user')
      .send('name=john') // x-www-form-urlencoded upload
      .set('Accept', 'application/json')
      .expect(function(res) {
        res.body.id = 'some fixed id';
        res.body.name = res.body.name.toLowerCase();
      })
      .expect(200, {
        id: 'some fixed id',
        name: 'john'
      }, done);
  });
});

Anything you can do with superagent, you can do with supertest - for example multipart file uploads!

request(app)
  .post('/')
  .field('name', 'my awesome avatar')
  .field('complex_object', '{"attribute": "value"}', {contentType: 'application/json'})
  .attach('avatar', 'test/fixtures/avatar.jpg')
  ...

Passing the app or url each time is not necessary, if you're testing the same host you may simply re-assign the request variable with the initialization app or url, a new Test is created per request.VERB() call.

request = request('http://localhost:5555');

request.get('/').expect(200, function(err){
  console.log(err);
});

request.get('/').expect('heya', function(err){
  console.log(err);
});

Here's an example with mocha that shows how to persist a request and its cookies:

const request = require('supertest');
const should = require('should');
const express = require('express');
const cookieParser = require('cookie-parser');

describe('request.agent(app)', function() {
  const app = express();
  app.use(cookieParser());

  app.get('/', function(req, res) {
    res.cookie('cookie', 'hey');
    res.send();
  });

  app.get('/return', function(req, res) {
    if (req.cookies.cookie) res.send(req.cookies.cookie);
    else res.send(':(')
  });

  const agent = request.agent(app);

  it('should save cookies', function(done) {
    agent
    .get('/')
    .expect('set-cookie', 'cookie=hey; Path=/', done);
  });

  it('should send cookies', function(done) {
    agent
    .get('/return')
    .expect('hey', done);
  });
});

There is another example that is introduced by the file agency.js

Here is an example where 2 cookies are set on the request.

agent(app)
  .get('/api/content')
  .set('Cookie', ['nameOne=valueOne;nameTwo=valueTwo'])
  .send()
  .expect(200)
  .end((err, res) => {
    if (err) {
      return done(err);
    }
    expect(res.text).to.be.equal('hey');
    return done();
  });

API

You may use any superagent methods, including .write(), .pipe() etc and perform assertions in the .end() callback for lower-level needs.

.expect(status[, fn])

Assert response status code.

.expect(status, body[, fn])

Assert response status code and body.

.expect(body[, fn])

Assert response body text with a string, regular expression, or parsed body object.

.expect(field, value[, fn])

Assert header field value with a string or regular expression.

.expect(function(res) {})

Pass a custom assertion function. It'll be given the response object to check. If the check fails, throw an error.

request(app)
  .get('/')
  .expect(hasPreviousAndNextKeys)
  .end(done);

function hasPreviousAndNextKeys(res) {
  if (!('next' in res.body)) throw new Error("missing next key");
  if (!('prev' in res.body)) throw new Error("missing prev key");
}

.end(fn)

Perform the request and invoke fn(err, res).

Notes

Inspired by api-easy minus vows coupling.

License

MIT

NPM DownloadsLast 30 Days