{"id":13503318,"url":"https://github.com/jondot/hypertesting","last_synced_at":"2025-10-16T12:58:45.145Z","repository":{"id":66314295,"uuid":"177000040","full_name":"jondot/hypertesting","owner":"jondot","description":"A declarative and contextual contract-driven testing framework for your API.","archived":false,"fork":false,"pushed_at":"2019-04-14T09:59:59.000Z","size":365,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-22T13:07:04.898Z","etag":null,"topics":["contract-testing","express","jest","testing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jondot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-21T18:12:13.000Z","updated_at":"2021-09-21T10:19:36.000Z","dependencies_parsed_at":"2023-05-18T16:04:05.083Z","dependency_job_id":null,"html_url":"https://github.com/jondot/hypertesting","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/jondot/hypertesting","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Fhypertesting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Fhypertesting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Fhypertesting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Fhypertesting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jondot","download_url":"https://codeload.github.com/jondot/hypertesting/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Fhypertesting/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261296912,"owners_count":23137218,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contract-testing","express","jest","testing"],"created_at":"2024-07-31T22:02:46.176Z","updated_at":"2025-10-16T12:58:45.036Z","avatar_url":"https://github.com/jondot.png","language":"TypeScript","readme":"![](media/cover.png)\n\n# Hypertesting\n\nA declarative and contextual contract-driven testing framework for your API.\n\n\n✅ Use `integration` to compose an first-class [hypercontroller](https://github.com/jondot/hypercontroller) and [TypeORM](https://typeorm.io) based integration testing experience   \n✅ Use `yaml` to describe your end-to-end acceptance tests stories  \n✅ Write contextual acceptance tests without code - access previous request results, add custom scripts and generate test blocks in your YAML.  \n✅ Powered by [Jest](https://jestjs.io), [supertest](https://github.com/visionmedia/supertest) and Snapshot driven testing  \n✅ Custom response scrubbing for secrets and sensitive data  \n✅ Run as a standalone binary with `hytest`  \n\n\n## Quick Start\n\nInstall:\n\n```\n$ yarn add --dev hypertesting\n```\n\n\n## Acceptance Tests\n\nIn this way, you can use Hypertesting in any project, including projects that are not related to Node.js. \n\nWrite your testing story (`requests/api.yaml`):\n\n```yaml\n- id: my-first-request\n  desc: just a normal GET request\n  method: get\n  path: /\n```\n\nIf you want to scrub sensitive data or remove unstable snapshot results (things that change between runs, such as dates):\n\n\n```yaml\n- id: my-first-request\n  desc: just a normal GET request\n  method: get\n  path: /\n  scrub:\n  - header.connection\n```\n\nIn any case hypertesting comes with default scrubbing logic, and this addition would be on top of it.\n\nNow create a Jest spec and point it to your yaml file. In addition you need to specify how to open and close your app.\n\n\nHere's an example using an Express `app`:\n\n```js\nimport path from 'path'\nimport hypertesting from 'hypertesting'\nimport app from '../index'\n\nconst test = hypertesting(() =\u003e Promise.resolve({ \n    app, \n    closeApp: () =\u003e {} \n}))\ndescribe('app', () =\u003e {\n  it('hypertest', async () =\u003e {\n    await test(path.join(__dirname, 'requests'))\n  })\n})\n```\n\nYou should have your expected results in `__snapshots__`. Use Jest as you would for other types of tests to update, verify and run tests:\n\n```\n$ yarn jest\n```\n\nTo see this in action you can run the tests in [examples/app]:\n\n```\n$ cd examples/app\n$ yarn \u0026\u0026 yarn test\n```\n\n\n\n### White Box Testing\n\n\nIn 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:\n\n```js\n() =\u003e Promise.resolve({ \n    app, \n    closeApp: () =\u003e {} \n})\n```\n\nIn the same sense we can prepare a database and clean it up, set up other services, configuration and so on.\n\n### Black Box Testing\n\nTo use hypertesting in a black-box scenario, point `app` to a URL:\n\n```\nconst test = hypertesting(() =\u003e Promise.resolve({ \n    app: 'http://localhost:3000', \n    closeApp: () =\u003e {} \n}))\n```\n\nIn 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.\n\n\n### Parameter Passing\n\nBy 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.\n\nHere's a common case where we have to have a JWT token before being able to access a service endpoint. \n\nWe log in, get a JWT token and use it in the next request.\n\n```yaml\n- id: login_1\n  desc: Login to the service successfully\n  path: /auth/login\n  method: post\n  body:\n    username: jondot@gmail.com\n    password: world\n- id: see-account\n  desc: see account with token from login\n  path: /account\n  method: get\n  headers:\n    authorization: bearer \u003c%= vars('login_1.json.token') %\u003e\n```\n\nUnder the hood, all `yaml` files are actually [EJS](https://ejs.co) (embedded Javascript) template files as well, meaning you can apply any logic, variables, or Javascript code directly into the `yaml` request stories!\n\n```yaml\n- id: see-account\n  desc: see account with token from login\n  path: /account\n  method: get\n  headers:\n    authorization: bearer \u003c%= vars('login_1.json.token') %\u003e\n```\n\nWhat 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.\n\nAccessing results is done with the `vars` function:\n\n```\n\u003c%= vars('login_1.json.token') %\u003e\n```\n\nAnd more generally:\n\n\n```\n\u003c%= vars('[previous-request-id].[response object]') %\u003e\n```\n\nWhere `response object` is your regular [supertest](https://github.com/visionmedia/supertest) response. So you can pick headers, body, status code and even the original request.\n\n### Standalone\n\nTo start quickly or in a production environment that doesn't include Node.js, you can use Hypertesting without Node.js, or the `hypertesting` library.\n\nFirst, get a copy of [hytest from the Releases section](https://github.com/jondot/hypertesting/releases).\n\nThen, write your test story in `api.yaml` and use a driving script:\n\n```js\nconst { hypertest } = require('/snapshot/hypertesting/dist')\nconst path = require('path')\n\nconst test = hypertest(\n  () =\u003e Promise.resolve({ app: 'https://google.com', closeApp: () =\u003e {} }),\n  {\n    expect\n  }\n)\ndescribe('app', () =\u003e {\n  it('requests', async () =\u003e {\n    await test(path.join(__dirname, 'requests'))\n  })\n})\n\n```\n\nThen run:\n\n```\n$ ls examples/stand-alone\nrequests/\nrequests.js\n\n$ cd examples/stand-alone \u0026\u0026 hytest requests.js\n```\n\nTo run this example, check out [examples/stand-alone](examples/stand-alone).\n\n\n\n\n\n\n\n\n## Fullstack Integration Tests\n\nIf you use [hypercontroller](https://github.com/jondot/hypercontroller) and [TypeORM](https://typeorm.io) then Hypertesting is optimized to give you a first class API testing experience. \n\n\nIt should look like this:\n\n```js\nimport createServer from '../../server'\nimport { stack: { integration } } from 'hypertesting'\n\nconst scrubPaths = [\n  'header.date',\n  'header.etag',\n  'req.url',\n  'req.headers.authorization',\n  { path: 'text', regex: /\"id\":.*,/, filler: '\"id\":\"scrubbed\",' }\n]\nconst req = integration(\n  createServer,  // a hypercontroller friendly createServer\n  scrubPaths, // see above\n  'users.yaml' // database fixture, loaded before each test\n)\n\ndescribe('account', () =\u003e {\n  req('should forbid access without a token', async (request, snapshot) =\u003e {\n    snapshot(await request.get('/account'))\n  })\n})\n```\n\nAnd `createServer` simply returns a Hypercontroller server:\n\n```js\nconst createServer = () =\u003e\n  server\n    .start(createConnection)\n    .then(({ opts }) =\u003e console.log(`Listening on ${opts.port}`))\n)\n```\n\n## Scrubber\n\nYou can use hypertesting's scrubber for anything you like without having to use the whole thing:\n\n```js\nimport { scrubber } from 'hypertesting'\n\nconst scrub = scrubber([\n  'header.x-site'\n])\n\nit(\"should make a request\", async ()=\u003e{\n  expect(scrub(await request(\"/foo/bar\"))).toMatchSnapshot()\n})\n```\n\n\n\n\n# Contributing\n\nFork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).\n\n### Thanks:\n\nTo all [Contributors](https://github.com/jondot/hypertesting/graphs/contributors) - you make this happen, thanks!\n\n# Copyright\n\nCopyright (c) 2019 [@jondot](http://twitter.com/jondot). See [LICENSE](LICENSE.txt) for further details.\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjondot%2Fhypertesting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjondot%2Fhypertesting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjondot%2Fhypertesting/lists"}