OpenAPI to Bruno Converter
Overview
Convert OpenAPI specifications (versions 3.0+) to Bruno API collections with automatically generated test blocks, proper authentication configuration, and request chaining support. The conversion creates a complete Bruno collection including directory structure, environment files, and executable test assertions.
Quick Start
Basic Conversion
For simple conversion from OpenAPI to Bruno:
python scripts/openapi_to_bruno.py <openapi-file> <output-directory> [collection-name]
Example:
python scripts/openapi_to_bruno.py api-spec.yaml ./my-bruno-collection "My API"
This generates:
- •
bruno.json- Collection configuration - •
environments/- Environment files from OpenAPI servers - •Organized
.brufiles for each endpoint - •Test blocks with assertions
- •Authentication configuration
When to Use This Skill
Use this skill when:
- •Converting OpenAPI/Swagger specifications to Bruno format
- •Setting up API testing from existing contracts
- •Generating collections with tests from API documentation
- •Creating Bruno collections for CI/CD integration
- •Migrating from OpenAPI-based tools to Bruno
Conversion Workflow
Step 1: Locate OpenAPI Specification
Identify the OpenAPI specification file (YAML or JSON format):
# Common locations ./openapi.yaml ./swagger.json ./api/openapi.yml ./docs/api-spec.yaml
Step 2: Run Conversion Script
Execute the conversion script with appropriate parameters:
python scripts/openapi_to_bruno.py <spec-file> <output-dir> [name]
Parameters:
- •
<spec-file>: Path to OpenAPI YAML or JSON file - •
<output-dir>: Target directory for Bruno collection - •
[name]: Optional collection name (defaults to spec title)
Step 3: Review Generated Collection
The converter creates:
output-directory/
├── bruno.json # Collection config
├── environments/
│ ├── production.bru # From servers
│ ├── staging.bru
│ └── development.bru
└── <organized-endpoints>/
├── users/
│ ├── get-users.bru
│ ├── create-user.bru
│ └── user-id/
│ └── get-user.bru
└── auth/
└── login.bru
Step 4: Customize as Needed
After generation, review and customize:
- •Test assertions for specific business logic
- •Environment variables and secrets
- •Pre-request scripts for test data generation
- •Request chaining variables
OpenAPI Mapping
URL and Servers
OpenAPI servers → Bruno environments
# OpenAPI
servers:
- url: https://api.example.com/v1
description: Production
- url: https://staging.example.com/v1
description: Staging
# Bruno: environments/production.bru
vars {
baseUrl: https://api.example.com/v1
}
# Bruno: environments/staging.bru
vars {
baseUrl: https://staging.example.com/v1
}
Paths and Operations
OpenAPI paths → Bruno .bru files
Organization strategy:
- •By tags: Groups endpoints by OpenAPI tags
- •By path structure: Uses path hierarchy for folders
- •By operationId: Uses operation ID for filename
Example:
# OpenAPI
paths:
/users/{id}:
get:
tags: [users]
operationId: getUserById
Creates: users/get-user-by-id.bru
Authentication
OpenAPI security schemes → Bruno auth blocks
Bearer Token
# OpenAPI
securitySchemes:
bearerAuth:
type: http
scheme: bearer
# Bruno
auth:bearer {
token: {{accessToken}}
}
API Key
# OpenAPI
securitySchemes:
apiKey:
type: apiKey
in: header
name: X-API-Key
# Bruno
headers {
X-API-Key: {{apiKey}}
}
Basic Auth
# OpenAPI
securitySchemes:
basicAuth:
type: http
scheme: basic
# Bruno
auth:basic {
username: {{username}}
password: {{password}}
}
OAuth 2.0
# OpenAPI
securitySchemes:
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://example.com/oauth/authorize
tokenUrl: https://example.com/oauth/token
# Bruno
auth:oauth2 {
grant_type: authorization_code
authorization_url: {{authUrl}}
access_token_url: {{tokenUrl}}
}
Parameters
Query parameters → params:query block
Path parameters → URL template variables {{paramName}}
Header parameters → headers block
Request Bodies
OpenAPI requestBody → Bruno body blocks
JSON
# OpenAPI
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
# Bruno
body:json {
{
"name": "string",
"email": "string"
}
}
Form Data
# OpenAPI
requestBody:
content:
application/x-www-form-urlencoded:
schema:
properties:
username:
type: string
# Bruno
body:form-urlencoded {
username: value
}
Responses
OpenAPI responses → Bruno test assertions
The converter analyzes response schemas to generate appropriate tests.
Test Generation
The skill automatically generates comprehensive test blocks based on OpenAPI specifications and established testing patterns.
Status Code Tests
Generated for every endpoint based on expected response:
test("Status code is 200", function() {
expect(res.getStatus()).to.equal(200);
});
Expected codes:
- •GET: 200
- •POST: 201 or 200
- •PUT/PATCH: 200 or 204
- •DELETE: 204 or 200
Schema Validation Tests
Generated from OpenAPI response schemas:
Object responses:
test("Response has required fields", function() {
const data = res.getBody();
expect(data).to.have.property('id');
expect(data).to.have.property('name');
expect(data).to.have.property('email');
});
test("Field types are correct", function() {
const data = res.getBody();
if (data.id !== undefined) {
expect(data.id).to.be.a('number');
}
if (data.name !== undefined) {
expect(data.name).to.be.a('string');
}
});
Array responses:
test("Response is array", function() {
const data = res.getBody();
expect(data).to.be.an('array');
});
test("Array items have correct structure", function() {
const data = res.getBody();
if (data.length > 0) {
expect(data[0]).to.have.property('id');
expect(data[0]).to.have.property('name');
}
});
Performance Tests
test("Response time acceptable", function() {
expect(res.getResponseTime()).to.be.below(2000);
});
Request Chaining
For POST and PUT operations, the converter includes variable saving for request chaining:
test("Save resource ID", function() {
const data = res.getBody();
if (data && data.id) {
bru.setVar("resourceId", data.id);
}
});
This enables follow-up requests to use the created resource:
get {
url: {{baseUrl}}/resources/{{resourceId}}
}
Pre-request Scripts
Generated when request bodies are present:
script:pre-request {
// Generate test data if needed
const timestamp = Date.now();
// bru.setVar("testValue", `value_${timestamp}`);
}
Uncomment and customize to generate unique test data.
Advanced Patterns
Handling Authentication Flows
For APIs requiring authentication:
- •Token-based auth: Create a login endpoint request first
- •Save token in tests:
javascript
test("Token received", function() { const data = res.getBody(); bru.setVar("accessToken", data.token); }); - •Use in subsequent requests:
code
auth:bearer { token: {{accessToken}} }
CRUD Operation Sequences
The converter sets up request chaining for typical CRUD flows:
Sequence 1: Create → Verify
- •POST
/users→ SaveuserId - •GET
/users/{{userId}}→ Verify creation
Sequence 2: Create → Update → Delete
- •POST
/users→ SaveuserId - •PUT
/users/{{userId}}→ Update resource - •DELETE
/users/{{userId}}→ Clean up
Environment-Specific Configuration
Customize generated environments for different contexts:
# environments/development.bru
vars {
baseUrl: http://localhost:3000
apiKey: dev_key_123
}
vars:secret {
accessToken: dev_token
}
# environments/production.bru
vars {
baseUrl: https://api.example.com
apiKey: prod_key_456
}
vars:secret {
accessToken: prod_token
}
Customization
Enhancing Generated Tests
After conversion, enhance tests with business logic validation:
test("Business rule validation", function() {
const user = res.getBody();
// Domain-specific checks
expect(user.email).to.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
expect(user.age).to.be.within(18, 120);
expect(user.role).to.be.oneOf(['admin', 'user', 'guest']);
});
Adding Test Data Generation
Enhance pre-request scripts for dynamic test data:
script:pre-request {
const timestamp = Date.now();
const randomId = Math.random().toString(36).substring(7);
bru.setVar("testEmail", `test_${timestamp}@example.com`);
bru.setVar("testUsername", `user_${randomId}`);
bru.setVar("testPassword", `Pass${randomId}!123`);
}
Organizing Complex APIs
For large APIs, organize by:
- •Tags: Use OpenAPI tags for logical grouping
- •Versioning: Separate v1, v2 endpoints
- •Modules: Group related functionality (auth, users, orders)
References
For detailed information about specifications and syntax:
- •openapi-spec.md: Complete OpenAPI 3.0 specification reference with all object types, authentication schemes, and data formats
- •bruno-syntax.md: Comprehensive Bruno .bru file syntax including all blocks, authentication types, and test patterns
- •test-patterns.md: Test generation patterns for different scenarios including CRUD operations, authentication flows, and request chaining
These references are loaded as needed when:
- •Clarifying OpenAPI structure or features
- •Understanding Bruno syntax details
- •Implementing specific test patterns
- •Debugging conversion issues
Troubleshooting
Script Execution
If the script fails to execute:
# Make executable chmod +x scripts/openapi_to_bruno.py # Run with Python directly python3 scripts/openapi_to_bruno.py <spec> <output>
Missing Dependencies
Install required Python packages:
pip install pyyaml
Invalid OpenAPI Spec
Validate your OpenAPI specification before conversion:
# Online validators https://editor.swagger.io/ # CLI tools openapi-generator validate -i openapi.yaml
Path Parameter Issues
Path parameters must use correct OpenAPI format:
# Correct
/users/{userId}
# Incorrect
/users/:userId
Response Schema Issues
Ensure response schemas are properly defined:
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/User'
Running Generated Tests
Execute tests using Bruno CLI:
# Run entire collection bru run <collection-directory> --env production # Run specific folder bru run <collection-directory>/users --env development # Generate report bru run <collection-directory> --output results.json