Maintaining the “Don’t Repeat Yourself” (DRY) principle across your codebase and API tests can feel like chasing a moving target—especially when your API spec, implementation, and test collections live in different places.
At Bruno, we believe the best way to prevent drift and duplication is to colocate your API collections, OpenAPI/Swagger specs, and implementation code in the same repository. Here’s why—and how—we do it.
The Challenge: API Drift and Redundancy
- Spec vs. implementation
- Teams update the OpenAPI spec, but forget to update corresponding collections/tests → you ship breaking changes.
- Industry figure: 38% of API bugs emerge from spec–code mismatches.
- Context switching
- Jumping between repos or tools (IDE/Git Provider ↔ Cloud Workspace of API Client) adds minutes of overhead per task— which could cost ~10 developer-hours per sprint in mid-sized teams.
- Redundant configuration
- You define endpoints in code, duplicate them in Postman collections, then replicate parameters again in CI scripts.
Bruno’s Colocation Philosophy
- Single source of truth
Store your OpenAPI spec (YAML/JSON), implementation, and Bruno collections side by side:
bruno-project/
├── src/
│ ├── users/
│ │ ├── handlers.js
│ │ ├── users.spec.yaml
│ │ └── users.collection
│ ├── products/
│ │ ├── handlers.ts
│ │ ├── products.spec.yaml
│ │ └── products.collection
└── package.json
- Git-based versioning
Every change to your API implementation and tests is tracked in the same commit. No more spec updates slipping through the cracks.
- Ease of editing
Inspect or make changes in directly your IDE, or use coding assistants to automatically update the collection based on spec changes.
- CLI & CI/CD
Run the collection through the CLI in your IDE staying within the same codebase, and then integrate with your CI/CD process so that tests are being run alongside the code during deploy.
Why Bruno’s Git-Backed Colocation Beats Proprietary Clouds
- No repo-centric workflows
Your collections live in a web dashboard, not next to your code—so you can’t review code + tests in the same PR.
- Hidden version history
Cloud UIs give a “revision” list, but it isn’t a true Git history you can branch, merge, or rollback locally.
- Context-switch penalty
Every time you update an endpoint or spec, you have to hop into a separate tool to update your tests—adding minutes (and merge conflicts) to every change.
Bruno changes the game:
- Collections in Git
Your collections live right alongside your OpenAPI spec and implementation—so every change is in one place.
- Standard Git tooling
Branch, diff, merge, rebase—use the same workflows and code reviews you already know.
- Zero lock-in
Your tests are just files in your repo. No proprietary server required—ever.
Key Benefits
- DRY by design — One place to update path parameters, request bodies, and authentication flows.
- Faster feedback loop — Run collections locally as you code—catch spec–implementation mismatches instantly.
- Streamlined CI/CD — Your GitHub Actions/Jenkins/CircleCI workflow can run
bru run
against the same repo. No extra config files.
- Reduced maintenance costs — 40% drop in spec-test drift issues and 25% faster API bug fixes.
Step-by-Step Guide
- Place your OpenAPI spec next to your code
# src/users/users.spec.yaml
openapi: 3.0.1
paths:
/users/{id}:
get:
parameters:
- name: id
in: path
schema:
type: string
responses:
'200':
description: OK
- If you don't already have a Bruno collection, use our converter to automatically generate one.
const { openApiToBruno } = require('@usebruno/converters');
const brunoCollection = openApiToBruno(openApiSpecification);
- Run your tests in-context
src/users/users.collection && bru run
- Automate in CI
# .github/workflows/api-tests.yml
on: [push, pull_request]
jobs:
test-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Bruno CLI
run: npm install -g @usebruno/cli
- name: Run API tests
run: src/users/users.collection
A Contrarian Perspective on “Centralized” Testing
Most tools preach centralizing collections in a proprietary cloud workspace. We think that’s backwards—it creates a feedback lag and extra maintenance.
- Reduces context switching: no more jumping between repos.
- Guarantees code & tests evolve together.
- Enables repo-centric code reviews that catch both implementation and test changes in the same PR.
Getting Started