Generate OpenAPI/Swagger documentation from your Jest API tests
npm install @foryourdev/jest-swagGenerate OpenAPI/Swagger documentation directly from your Jest API tests! Inspired by rswag, jest-swag brings the same powerful concept to the JavaScript/TypeScript ecosystem.
- API-First Testing: Write Jest tests that double as API documentation
- OpenAPI 3.0 Support: Generate standards-compliant OpenAPI specifications
- Automatic Documentation: Documentation stays in sync with your tests
- Swagger UI Integration: Interactive API documentation out of the box
- TypeScript Support: Fully typed for better developer experience
- Zero Configuration: Works with minimal setup
``bash`
npm install @foryourdev/jest-swag --save-dev
1. Install jest-swag in your Express project:
`bash`
cd your-express-project
npm install @foryourdev/jest-swag --save-dev
2. Setup Swagger UI in your Express app:
`javascript
// app.js or server.js
import express from 'express';
import { setupSwagger } from '@foryourdev/jest-swag';
const app = express();
// Only in development environment
if (process.env.NODE_ENV !== 'production') {
setupSwagger(app, {
routePrefix: '/api-docs',
title: 'My API Documentation',
});
}
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
console.log('API docs available at http://localhost:3000/api-docs');
});
`
3. Create API tests:
`typescript
// tests/api/users.test.ts
import {
path,
get,
post,
tags,
parameter,
requestBody,
response,
jsonContent,
schemas,
} from '@foryourdev/jest-swag';
import request from 'supertest';
import app from '../app';
describe('Users API', () => {
path('/api/users', () => {
get('Get all users', () => {
tags('Users');
parameter({
name: 'page',
in: 'query',
description: 'Page number',
required: false,
schema: schemas.integer(1),
});
response(200, 'Users retrieved successfully', () => {
return request(app).get('/api/users?page=1').expect(200);
});
});
});
});
`
4. Configure Jest to generate docs:
`javascript`
// jest.config.js
module.exports = {
testEnvironment: 'node',
reporters: [
'default',
[
'@foryourdev/jest-swag/dist/reporter.js',
{
title: 'My Express API',
version: '1.0.0',
outputPath: './docs/openapi.json',
},
],
],
};
5. Run tests and access Swagger UI:
`bashRun tests to generate documentation
npm test
$3
1. Install jest-swag:
`bash
cd your-nestjs-project
npm install @foryourdev/jest-swag --save-dev
`2. Setup JestSwag module in your NestJS app:
`typescript
// app.module.ts
import { Module } from '@nestjs/common';
import { JestSwagModule } from '@foryourdev/jest-swag';@Module({
imports: [
// Only in development
...(process.env.NODE_ENV !== 'production'
? [
JestSwagModule.forRoot({
path: 'api-docs',
title: 'My NestJS API Documentation',
}),
]
: []),
// ... other imports
],
})
export class AppModule {}
`3. Create NestJS API tests:
`typescript
// test/users.e2e-spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
import {
path,
get,
post,
tags,
parameter,
requestBody,
response,
jsonContent,
schemas,
} from '@foryourdev/jest-swag';describe('Users (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
path('/users', () => {
get('Get all users', () => {
tags('Users');
response(200, 'Success', () => {
return request(app.getHttpServer()).get('/users').expect(200);
});
});
post('Create user', () => {
tags('Users');
requestBody({
required: true,
content: jsonContent(
schemas.object(
{
name: schemas.string('John Doe'),
email: schemas.string('john@example.com'),
},
['name', 'email'],
),
),
});
response(201, 'User created', () => {
return request(app.getHttpServer())
.post('/users')
.send({ name: 'John', email: 'john@test.com' })
.expect(201);
});
});
});
afterAll(async () => {
await app.close();
});
});
`4. Configure Jest:
`javascript
// jest.config.js
module.exports = {
moduleFileExtensions: ['js', 'json', 'ts'],
rootDir: 'test',
testEnvironment: 'node',
testRegex: '.*\\.spec\\.ts$',
transform: {
'^.+\\.(t|j)s$': 'ts-jest',
},
reporters: [
'default',
[
'@foryourdev/jest-swag/dist/reporter.js',
{
title: 'My NestJS API',
version: '1.0.0',
outputPath: './docs/openapi.json',
servers: [
{ url: 'http://localhost:3000', description: 'Development server' },
],
},
],
],
};
`5. Run tests and access Swagger UI:
`bash
Run e2e tests to generate documentation
npm run test:e2eStart your NestJS application
npm startAccess Swagger UI at http://localhost:3000/api-docs
`🎯 Quick Start
$3
`typescript
// tests/api/users.test.ts
import {
path,
get,
post,
tags,
parameter,
requestBody,
response,
jsonContent,
schemas,
} from '@foryourdev/jest-swag';describe('Users API', () => {
path('/users', () => {
get('Get all users', () => {
tags('Users');
parameter({
name: 'limit',
in: 'query',
description: 'Maximum number of users to return',
required: false,
schema: schemas.integer(10),
});
response(200, 'Successfully retrieved users', () => {
// Your actual test logic here
// expect(response.status).toBe(200);
});
response(400, 'Bad request');
});
post('Create user', () => {
tags('Users');
requestBody({
description: 'User data',
required: true,
content: jsonContent(
schemas.object(
{
name: schemas.string('John Doe'),
email: schemas.string('john@example.com'),
age: schemas.integer(30),
},
['name', 'email'],
),
),
});
response(201, 'User created successfully', () => {
// Your test logic
});
});
});
});
`$3
Add jest-swag reporter to your Jest configuration:
`javascript
// jest.config.js
module.exports = {
// ... other Jest configuration
reporters: [
'default',
[
'jest-swag/dist/reporter.js',
{
title: 'My API Documentation',
version: '1.0.0',
description: 'Generated API documentation',
outputPath: './docs/openapi.json',
servers: [
{ url: 'http://localhost:3000', description: 'Development server' },
{ url: 'https://api.example.com', description: 'Production server' },
],
},
],
],
};
`$3
`bash
Generate documentation while running tests
npm testOr run tests specifically for documentation
npm run test:docsStart your app server (Express/NestJS)
npm start
`$3
After running tests and starting your server:
- Express:
http://localhost:3000/api-docs
- NestJS: http://localhost:3000/api-docs
- Files: docs/openapi.json, docs/openapi.yamlNo need for separate servers! 🎉 Swagger UI is integrated directly into your application.
📚 API Reference
$3
`typescript
import { path, get, post, put, patch, del } from '@foryourdev/jest-swag';path('/users', () => {
get('Get users', () => {
/ ... /
});
post('Create user', () => {
/ ... /
});
put('Update user', () => {
/ ... /
});
patch('Patch user', () => {
/ ... /
});
del('Delete user', () => {
/ ... /
});
});
`$3
`typescript
import { parameter, schemas } from '@foryourdev/jest-swag';parameter({
name: 'userId',
in: 'path',
description: 'User ID',
required: true,
schema: schemas.string(),
});
parameter({
name: 'limit',
in: 'query',
schema: schemas.integer(10),
});
`$3
`typescript
import { requestBody, jsonContent, schemas } from '@foryourdev/jest-swag';requestBody({
description: 'User data',
required: true,
content: jsonContent(
schemas.object(
{
name: schemas.string(),
email: schemas.string(),
},
['name', 'email'],
),
),
});
`$3
`typescript
import { response } from '@foryourdev/jest-swag';response(200, 'Success', () => {
// Your test assertions here
expect(result.status).toBe(200);
});
response(404, 'Not found');
response(500, 'Internal server error');
`$3
`typescript
import { schemas } from '@foryourdev/jest-swag';// Basic types
schemas.string('example');
schemas.number(42);
schemas.integer(10);
schemas.boolean(true);
// Complex types
schemas.array(schemas.string(), ['item1', 'item2']);
schemas.object(
{
id: schemas.string(),
name: schemas.string(),
},
['id'],
{ id: '123', name: 'John' },
);
`⚙️ Configuration
$3
Add to your
jest.config.js:`javascript
module.exports = {
// ... other config
reporters: [
'default',
[
'@foryourdev/jest-swag/dist/reporter.js',
{
title: 'My API Documentation',
version: '1.0.0',
description: 'Generated API documentation',
outputPath: './api-docs/openapi.json',
servers: [
{ url: 'http://localhost:3000', description: 'Development server' },
{ url: 'https://api.example.com', description: 'Production server' },
],
},
],
],
};
`$3
`bash
Generate documentation from saved specs
npx @foryourdev/jest-swag generate --title "My API" --version "2.0.0" --output ./docs/api.jsonServe documentation
npx @foryourdev/jest-swag serve --port 3001 --docs ./docsGenerate with config file
npx @foryourdev/jest-swag generate --config ./jest-swag.config.json
`📄 Configuration File
Create
jest-swag.config.json:`json
{
"title": "My API Documentation",
"version": "1.0.0",
"description": "Comprehensive API documentation",
"outputPath": "./docs/openapi.json",
"servers": [
{
"url": "http://localhost:3000",
"description": "Development server"
},
{
"url": "https://api.example.com",
"description": "Production server"
}
]
}
`🛠️ Scripts
Add these scripts to your
package.json:`json
{
"scripts": {
"test": "jest --reporters=default --reporters=@foryourdev/jest-swag/dist/reporter.js",
"test:docs": "jest --reporters=@foryourdev/jest-swag/dist/reporter.js",
"docs:generate": "@foryourdev/jest-swag generate",
"docs:serve": "@foryourdev/jest-swag serve"
}
}
`🤝 Comparison with rswag
| Feature | jest-swag | rswag |
| ----------------- | --------------------- | ----------- |
| Language | JavaScript/TypeScript | Ruby |
| Test Framework | Jest | RSpec |
| API Specification | OpenAPI 3.0 | OpenAPI 3.0 |
| Documentation UI | Swagger UI | Swagger UI |
| Auto-generation | ✅ | ✅ |
| Type Safety | ✅ (TypeScript) | ✅ (Ruby) |
💡 Examples
Check out the
test/example-api.test.ts` file for comprehensive examples of:- User management API
- Blog posts API
- Complex request/response schemas
- Parameter validation
- Error handling
---
jest-swag - Because your API tests deserve some swag! 😎