npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

hypertesting

v1.1.4

Published

![](media/cover.png)

Downloads

10

Readme

Hypertesting

A declarative and contextual contract-driven testing framework for your API.

✅ Use integration to compose an first-class hypercontroller and TypeORM based integration testing experience
✅ Use yaml to describe your end-to-end acceptance tests stories
✅ Write contextual acceptance tests without code - access previous request results, add custom scripts and generate test blocks in your YAML.
✅ Powered by Jest, supertest and Snapshot driven testing
✅ Custom response scrubbing for secrets and sensitive data
✅ Run as a standalone binary with hytest

Quick Start

Install:

$ yarn add --dev hypertesting

Acceptance Tests

In this way, you can use Hypertesting in any project, including projects that are not related to Node.js.

Write your testing story (requests/api.yaml):

- id: my-first-request
  desc: just a normal GET request
  method: get
  path: /

If you want to scrub sensitive data or remove unstable snapshot results (things that change between runs, such as dates):

- id: my-first-request
  desc: just a normal GET request
  method: get
  path: /
  scrub:
  - header.connection

In any case hypertesting comes with default scrubbing logic, and this addition would be on top of it.

Now create a Jest spec and point it to your yaml file. In addition you need to specify how to open and close your app.

Here's an example using an Express app:

import path from 'path'
import hypertesting from 'hypertesting'
import app from '../index'

const test = hypertesting(() => Promise.resolve({ 
    app, 
    closeApp: () => {} 
}))
describe('app', () => {
  it('hypertest', async () => {
    await test(path.join(__dirname, 'requests'))
  })
})

You should have your expected results in __snapshots__. Use Jest as you would for other types of tests to update, verify and run tests:

$ yarn jest

To see this in action you can run the tests in [examples/app]:

$ cd examples/app
$ yarn && yarn test

White Box Testing

In the example above we're testing an Express app, and we're telling hypertesting about how we create and close such an app and it will create one for us for each test cycle:

() => Promise.resolve({ 
    app, 
    closeApp: () => {} 
})

In the same sense we can prepare a database and clean it up, set up other services, configuration and so on.

Black Box Testing

To use hypertesting in a black-box scenario, point app to a URL:

const test = hypertesting(() => Promise.resolve({ 
    app: 'http://localhost:3000', 
    closeApp: () => {} 
}))

In this case, again, we have nothing special to do in order to close an app. Since this still runs within the scope of your Jest specs, you can build set up and tear down code as you would otherwise.

Parameter Passing

By default, hypertesting capture the current call's results and passes it to the next call as context. Here's how it looks like when you want to reuse data from previous calls.

Here's a common case where we have to have a JWT token before being able to access a service endpoint.

We log in, get a JWT token and use it in the next request.

- id: login_1
  desc: Login to the service successfully
  path: /auth/login
  method: post
  body:
    username: [email protected]
    password: world
- id: see-account
  desc: see account with token from login
  path: /account
  method: get
  headers:
    authorization: bearer <%= vars('login_1.json.token') %>

Under the hood, all yaml files are actually EJS (embedded Javascript) template files as well, meaning you can apply any logic, variables, or Javascript code directly into the yaml request stories!

- id: see-account
  desc: see account with token from login
  path: /account
  method: get
  headers:
    authorization: bearer <%= vars('login_1.json.token') %>

What you see here is that every yaml file is interpolated progressivly. That is, a request is being made, and the yaml file is re-rendered internally for each request with the previous requests results.

Accessing results is done with the vars function:

<%= vars('login_1.json.token') %>

And more generally:

<%= vars('[previous-request-id].[response object]') %>

Where response object is your regular supertest response. So you can pick headers, body, status code and even the original request.

Standalone

To start quickly or in a production environment that doesn't include Node.js, you can use Hypertesting without Node.js, or the hypertesting library.

First, get a copy of hytest from the Releases section.

Then, write your test story in api.yaml and use a driving script:

const { hypertest } = require('/snapshot/hypertesting/dist')
const path = require('path')

const test = hypertest(
  () => Promise.resolve({ app: 'https://google.com', closeApp: () => {} }),
  {
    expect
  }
)
describe('app', () => {
  it('requests', async () => {
    await test(path.join(__dirname, 'requests'))
  })
})

Then run:

$ ls examples/stand-alone
requests/
requests.js

$ cd examples/stand-alone && hytest requests.js

To run this example, check out examples/stand-alone.

Fullstack Integration Tests

If you use hypercontroller and TypeORM then Hypertesting is optimized to give you a first class API testing experience.

It should look like this:

import createServer from '../../server'
import { stack: { integration } } from 'hypertesting'

const scrubPaths = [
  'header.date',
  'header.etag',
  'req.url',
  'req.headers.authorization',
  { path: 'text', regex: /"id":.*,/, filler: '"id":"scrubbed",' }
]
const req = integration(
  createServer,  // a hypercontroller friendly createServer
  scrubPaths, // see above
  'users.yaml' // database fixture, loaded before each test
)

describe('account', () => {
  req('should forbid access without a token', async (request, snapshot) => {
    snapshot(await request.get('/account'))
  })
})

And createServer simply returns a Hypercontroller server:

const createServer = () =>
  server
    .start(createConnection)
    .then(({ opts }) => console.log(`Listening on ${opts.port}`))
)

Scrubber

You can use hypertesting's scrubber for anything you like without having to use the whole thing:

import { scrubber } from 'hypertesting'

const scrub = scrubber([
  'header.x-site'
])

it("should make a request", async ()=>{
  expect(scrub(await request("/foo/bar"))).toMatchSnapshot()
})

Contributing

Fork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).

Thanks:

To all Contributors - you make this happen, thanks!

Copyright

Copyright (c) 2019 @jondot. See LICENSE for further details.