Convert Figma logo to code with AI

forwardemail logosupertest

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

14,135
773
14,135
172

Top Related Projects

14,068

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

7,071

Newman is a command-line collection runner for Postman

48,796

Fast, easy and reliable testing for anything that runs in a browser.

Quick Overview

Supertest is a high-level abstraction for testing HTTP servers, built on top of the popular SuperAgent library. It provides a fluent API for making HTTP assertions, making it easier to write expressive and readable tests for your Node.js HTTP servers.

Pros

  • Easy to use and intuitive API for testing HTTP endpoints
  • Supports both callback and promise-based testing styles
  • Integrates well with popular testing frameworks like Mocha and Jest
  • Allows for testing of both Express applications and raw Node.js http servers

Cons

  • Limited to testing HTTP servers, not suitable for other types of testing
  • May introduce additional complexity for simple API tests
  • Requires a running server for tests, which can slow down test execution
  • Some users report occasional issues with certain types of assertions

Code Examples

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

request(app)
  .get('/users')
  .expect('Content-Type', /json/)
  .expect(200)
  .end((err, res) => {
    if (err) throw err;
  });
  1. POST request with data:
const request = require('supertest');
const app = require('../app');

request(app)
  .post('/users')
  .send({ name: 'John', email: 'john@example.com' })
  .set('Accept', 'application/json')
  .expect('Content-Type', /json/)
  .expect(201)
  .then(response => {
    assert(response.body.id);
  });
  1. Testing with async/await:
const request = require('supertest');
const app = require('../app');

it('should create a new user', async () => {
  const response = await request(app)
    .post('/users')
    .send({ name: 'Jane', email: 'jane@example.com' });
  
  expect(response.status).toBe(201);
  expect(response.body).toHaveProperty('id');
});

Getting Started

To use Supertest in your project, first install it via npm:

npm install supertest --save-dev

Then, in your test file:

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

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

Run your tests using your preferred test runner (e.g., Mocha, Jest).

Competitor Comparisons

14,068

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

Pros of Supertest (ladjs)

  • More established and widely used in the Node.js community
  • Extensive documentation and examples available
  • Larger contributor base and more frequent updates

Cons of Supertest (ladjs)

  • Slightly larger package size
  • May have more dependencies, potentially increasing complexity
  • Some users report occasional issues with certain edge cases

Code Comparison

Supertest (ladjs):

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

request(app)
  .get('/user')
  .expect('Content-Type', /json/)
  .expect(200, done);

Supertest (forwardemail):

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

supertest(app)
  .get('/user')
  .expect('Content-Type', /json/)
  .expect(200, done);

The code usage is nearly identical between the two libraries, with the main difference being the import statement. Both provide a similar API for making HTTP assertions in tests.

While Supertest (ladjs) has been the go-to choice for many developers due to its maturity and widespread adoption, Supertest (forwardemail) aims to provide a more lightweight alternative with potentially fewer dependencies. The choice between the two may depend on specific project requirements and preferences.

7,071

Newman is a command-line collection runner for Postman

Pros of Newman

  • Integrates seamlessly with Postman collections, allowing easy execution of existing API tests
  • Supports detailed reporting options, including HTML and JSON formats
  • Offers CLI functionality for easy integration into CI/CD pipelines

Cons of Newman

  • Requires Postman collections, which may not be suitable for all testing scenarios
  • Less flexible for writing custom test logic compared to SuperTest
  • Steeper learning curve for those not familiar with Postman ecosystem

Code Comparison

SuperTest:

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

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; }
    console.log('collection run complete!');
});

SuperTest is more code-centric and allows for direct integration with testing frameworks like Mocha. Newman, on the other hand, relies on Postman collections and environments, offering a more configuration-based approach to API testing.

48,796

Fast, easy and reliable testing for anything that runs in a browser.

Pros of Cypress

  • Provides an all-in-one testing framework with built-in assertion library and mocking capabilities
  • Offers a powerful, interactive test runner with time-travel debugging
  • Supports real-time reloading and automatic waiting for elements

Cons of Cypress

  • Limited to testing web applications and cannot test native mobile apps
  • Runs tests inside the browser, which can lead to some limitations in certain scenarios
  • Has a steeper learning curve compared to simpler HTTP assertion libraries

Code Comparison

Cypress example:

describe('Login', () => {
  it('should log in successfully', () => {
    cy.visit('/login')
    cy.get('#username').type('user@example.com')
    cy.get('#password').type('password123')
    cy.get('button[type="submit"]').click()
    cy.url().should('include', '/dashboard')
  })
})

Supertest example:

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

describe('Login API', () => {
  it('should log in successfully', async () => {
    const response = await request(app)
      .post('/api/login')
      .send({ username: 'user@example.com', password: 'password123' })
      .expect(200);
    expect(response.body).toHaveProperty('token');
  });
});

While Cypress focuses on end-to-end testing of web applications with a browser-based approach, Supertest is primarily used for testing HTTP assertions and API endpoints. Cypress offers a more comprehensive testing solution for web applications, but Supertest provides a simpler and more focused approach for API testing.

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

build status code coverage code style styled with prettier made with lass 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