Zum Inhalt springen

Bruno-Befehle

Bruno ist ein leichtgewichtiger, Open-Source, Git-nativer API-Client, der zum Testen und Entwickeln von APIs konzipiert ist. Im Gegensatz zu Postman werden Ihre Sammlungen als Nur-Text-Dateien (.bru-Format) gespeichert, die mit Git versioniert werden können, was es ideal für Teamzusammenarbeit und CI/CD-Pipelines macht.

Installation

PlattformBefehl
macOS (Homebrew)brew install bruno
Linux (Snap)snap install bruno
Linux (APT)sudo apt-get install bruno
Windows (Chocolatey)choco install bruno
npmnpm install -g @usebruno/cli
DownloadBesuchen Sie usebruno.com/downloads

Erste Schritte

Bruno GUI starten

bruno

Neue Sammlung erstellen

bruno create-collection my-api-collection

Vorhandene Sammlung öffnen

bruno /path/to/collection

Sammlungsverwaltung

Sammlungsstruktur

Bruno speichert Sammlungen als Verzeichnisse mit .bru-Dateien:

my-api-collection/
├── bruno.json          # Sammlungsmetadaten
├── environments/
│   ├── Development.json
│   └── Production.json
├── auth/
│   └── auth.bru
└── users/
    ├── get-all-users.bru
    ├── create-user.bru
    └── update-user.bru

Von Postman importieren

# In Bruno GUI: Import → Postman-Sammlungs-JSON auswählen
# Oder CLI verwenden (falls für Ihre Bruno-Version verfügbar)

Anfragen in Ordnern organisieren

Erstellen Sie Ordner in Ihrer Sammlung, um Anfragen zu organisieren:

  • Klicken Sie mit der rechten Maustaste in den Sammlungsbaum → Neuer Ordner
  • Benennen Sie Ordner logisch (z. B. users, products, auth)
  • Ziehen Sie Anfragen zwischen Ordnern

Sammlung exportieren

# Sammlungen werden als Nur-Text-Dateien (.bru-Format) gespeichert
# Übertragen Sie sie einfach zu Git oder teilen Sie das Verzeichnis

Bru-Sprache (Anfrage-Format)

Bruno verwendet .bru-Dateien – eine einfache, lesbare Markup-Sprache für Anfragen.

Basis-Anfrage-Datei

meta {
  name: Get All Users
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/api/users
  auth: bearer
}

params:query {
  limit: 10
  offset: 0
}

headers {
  Content-Type: application/json
  User-Agent: Bruno/v1
}

auth:bearer {
  token: {{authToken}}
}

Anfrage mit Text

meta {
  name: Create User
  type: http
  seq: 2
}

post {
  url: {{baseUrl}}/api/users
}

headers {
  Content-Type: application/json
}

body:json {
  {
    "name": "John Doe",
    "email": "john@example.com",
    "role": "admin"
  }
}

Formular-Daten-Anfrage

meta {
  name: Upload Profile Picture
  type: http
  seq: 3
}

post {
  url: {{baseUrl}}/api/users/{{userId}}/avatar
}

body:form-urlencoded {
  username: johndoe
  email: john@example.com
}

Multipart-Formular (Datei-Upload)

meta {
  name: Upload File
  type: http
  seq: 4
}

post {
  url: {{baseUrl}}/api/files/upload
}

body:multipartForm {
  file: @/path/to/file.pdf
  description: My document
}

CLI-Befehle

Sammlung oder Anfrage ausführen

# Gesamte Sammlung ausführen
bru run /path/to/collection

# Spezifische Anfrage ausführen
bru run /path/to/collection/requests/get-users.bru

# Mit spezifischer Umgebung ausführen
bru run /path/to/collection --env Production

# Im JSON-Reporter-Format
bru run /path/to/collection --reporter json

# Mit HTML-Report
bru run /path/to/collection --reporter html --output report.html

Verfügbare Reporter

ReporterBefehl
CLI (Standard)bru run collection --reporter cli
JSONbru run collection --reporter json
HTMLbru run collection --reporter html --output report.html
JUnitbru run collection --reporter junit

Mit Variablen ausführen

# Umgebungsvariablen übergeben
bru run /path/to/collection --env Development

# Spezifische Variable überschreiben
bru run /path/to/collection --env Production --variable apiKey=abc123

Bei Fehler fehlschlagen

# Mit nicht-Null-Status beenden, wenn ein Test fehlschlägt (nützlich für CI/CD)
bru run /path/to/collection --failOnError

Ausführliche Ausgabe

# Detaillierte Anfrage-/Antwortwort-Informationen anzeigen
bru run /path/to/collection --verbose

Umgebungsvariablen

Umgebungsdatei erstellen

Umgebungsdateien werden als environments/EnvName.json gespeichert:

{
  "baseUrl": "https://api.example.com",
  "apiKey": "your-api-key-here",
  "authToken": "bearer-token",
  "userId": "12345",
  "timeout": 5000
}

Variablen in Anfragen verwenden

get {
  url: {{baseUrl}}/api/users/{{userId}}
  timeout: {{timeout}}
}

headers {
  Authorization: Bearer {{authToken}}
  X-API-Key: {{apiKey}}
}

Umgebungen wechseln

# Über CLI
bru run /path/to/collection --env Development

# Über GUI: Umgebungs-Dropdown in Bruno-Schnittstelle auswählen

Umgebungsvariablen-Typen

TypBeispielVerwendung
String"apiKey": "abc123"{{apiKey}}
Number"timeout": 5000{{timeout}}
Boolean"debug": true{{debug}}
Object"config": {...}Zugriff mit Scripting

Secrets-Management

# .env-Datei für sensible Daten erstellen (zu .gitignore hinzufügen)
echo "PROD_API_KEY=secret123" > .env

# In Umgebungsdatei mit Referenz verwenden
# Oder Bruno-GUI verwenden, um Felder als "Secret" zu markieren

Pre-Request-Skripte

Fügen Sie JavaScript hinzu, bevor die Anfrage gesendet wird:

// Dynamische Werte setzen
bru.setEnvVar('timestamp', Date.now());
bru.setEnvVar('nonce', Math.random().toString(36).substring(7));

// Bedingte Logik
if (bru.getEnvVar('env') === 'production') {
  bru.setEnvVar('timeout', 10000);
}

// Debug-Info protokollieren
console.log('Sending request to', bru.getEnvVar('baseUrl'));

Post-Response-Skripte

Führen Sie JavaScript nach Erhalt der Antwort aus:

// Zugriff auf Antwortdaten
const responseData = res.getBody();
const statusCode = res.getStatus();
const headers = res.getHeaders();

// Werte für nächste Anfrage speichern
if (statusCode === 200) {
  bru.setEnvVar('authToken', responseData.token);
  bru.setEnvVar('userId', responseData.user.id);
}

// Antwort protokollieren
console.log('Status:', statusCode);
console.log('Response:', JSON.stringify(responseData, null, 2));

Häufige Response-Operationen

// Statuscode abrufen
const status = res.getStatus();

// Body als String abrufen
const body = res.getBody();

// JSON-Body parsen
const data = res.getBody(true); // true = als JSON parsen

// Header abrufen
const contentType = res.getHeader('content-type');

// Spezifischen Header abrufen
const authHeader = res.getHeader('authorization');

Assertions und Tests

Integrierte Test-Assertions

// Statuscode-Assertion
tests['Status is 200'] = (res.getStatus() === 200);

// Response-Body enthält
tests['Response contains user'] = res.getBody().includes('john');

// JSON-Response-Validierung
const data = res.getBody(true);
tests['User ID exists'] = data.user && data.user.id > 0;

// Response-Zeit
tests['Response time < 500ms'] = res.getResponseTime() < 500;

// Header-Validierung
tests['Content-Type is JSON'] = res.getHeader('content-type').includes('application/json');

Komplexes Test-Beispiel

const data = res.getBody(true);

tests['Status is 201'] = res.getStatus() === 201;
tests['ID is a number'] = typeof data.id === 'number';
tests['Email is valid'] = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(data.email);
tests['Created at is ISO date'] = !isNaN(Date.parse(data.createdAt));

// Für nächste Anfrage speichern
if (tests['Status is 201']) {
  bru.setEnvVar('newUserId', data.id);
}

Authentifizierung

Bearer Token

auth:bearer {
  token: {{authToken}}
}

Basic Auth

auth:basic {
  username: {{username}}
  password: {{password}}
}

API-Schlüssel (Header)

headers {
  X-API-Key: {{apiKey}}
  Authorization: ApiKey {{apiKey}}
}

API-Schlüssel (Query-Parameter)

params:query {
  api_key: {{apiKey}}
  apiToken: {{token}}
}

OAuth 2.0

auth:oauth2 {
  grant_type: authorization_code
  authorization_url: https://provider.com/oauth/authorize
  token_url: https://provider.com/oauth/token
  client_id: {{clientId}}
  client_secret: {{clientSecret}}
  scope: read write
}

Digest Auth

auth:digest {
  username: {{username}}
  password: {{password}}
}

Anfrage-Typen und Methoden

GET-Anfrage

meta {
  name: Fetch User
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/api/users/{{userId}}
}

params:query {
  includeProfile: true
  fields: id,name,email
}

POST-Anfrage

post {
  url: {{baseUrl}}/api/users
}

body:json {
  {
    "name": "Jane Doe",
    "email": "jane@example.com"
  }
}

PUT/PATCH-Anfrage

put {
  url: {{baseUrl}}/api/users/{{userId}}
}

body:json {
  {
    "name": "Jane Smith",
    "status": "active"
  }
}

DELETE-Anfrage

delete {
  url: {{baseUrl}}/api/users/{{userId}}
}

Anfrage mit Headers

headers {
  Content-Type: application/json
  Accept: application/json
  User-Agent: Bruno/v1.0
  X-Request-ID: {{requestId}}
  Authorization: Bearer {{token}}
}

Erweiterte Funktionen

Variablen auf Sammlungsebene

Definieren Sie Variablen in bruno.json:

{
  "name": "My API Collection",
  "version": "1.0",
  "variables": {
    "baseUrl": "https://api.example.com",
    "version": "v1",
    "defaultTimeout": 5000
  }
}

Anfrage-Sequenzierung

Kontrollieren Sie die Ausführungsreihenfolge in CLI runner:

meta {
  name: Authenticate
  type: http
  seq: 1
}
meta {
  name: Get User Data
  type: http
  seq: 2
}

Anfragen werden in seq-Reihenfolge ausgeführt.

GraphQL-Abfragen

meta {
  name: GraphQL Query
  type: http
  seq: 1
}

post {
  url: {{baseUrl}}/graphql
}

body:graphql {
  query {
    user(id: "{{userId}}") {
      id
      name
      email
    }
  }
}

Query-Parameter

params:query {
  page: 1
  limit: 10
  sort: -createdAt
  filter: status:active
}

Git-Workflow

Warum Git-Native wichtig ist

# Sammlungen werden als Textdateien gespeichert
.bru/
├── users/
   ├── get-user.bru
   └── create-user.bru
└── products/
    └── list-products.bru

# Einfache Versionskontrolle
git add .
git commit -m "Update API requests"
git push origin main

# Merge-Konflikte sind handhabbar
# Änderungen in Pull Requests überprüfen
# Mit Team zusammenarbeiten

Zusammenarbeits-Workflow

# Teamkollege klont Sammlung
git clone https://github.com/team/api-collection.git
cd api-collection

# Bruno CLI installieren
npm install -g @usebruno/cli

# Tests lokal ausführen
bru run . --env Development

# Änderungen vornehmen
# Neue Anfragen hinzufügen oder vorhandene aktualisieren

# Commiten und pushen
git add .
git commit -m "Add payment API endpoints"
git push origin feature/payments

Sensible Dateien ignorieren

# .gitignore im Sammlungsstamm
.env
.env.local
environments/Production.json
!environments/Production.json.example
secrets/
node_modules/

CI/CD-Integration

GitHub Actions

name: API Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install Bruno CLI
        run: npm install -g @usebruno/cli

      - name: Run API tests
        run: bru run . --env CI --reporter json --output test-results.json

      - name: Upload results
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: test-results
          path: test-results.json

GitLab CI

api-tests:
  image: node:18
  script:
    - npm install -g @usebruno/cli
    - bru run . --env CI --reporter json --output test-results.json
  artifacts:
    paths:
      - test-results.json
    reports:
      junit: test-results.json

Lokaler Pre-commit Hook

#!/bin/bash
# .git/hooks/pre-commit

echo "Running API tests..."
bru run . --env Development --failOnError

if [ $? -ne 0 ]; then
  echo "API tests failed. Commit aborted."
  exit 1
fi

Häufige Workflows

REST-API testen

# 1. Umgebung einrichten
bru run /path/to/collection --env Development

# 2. Testergebnisse überprüfen
# Tests bestanden/fehlgeschlagen in der Ausgabe angezeigt

# 3. Report generieren
bru run /path/to/collection --env Development --reporter html --output report.html

Load Testing mit parallelen Anfragen

// Im Pre-Request-Skript
for (let i = 0; i < 10; i++) {
  bru.setEnvVar('iteration', i);
}

Dynamische Daten generieren

// Eindeutige E-Mail pro Anfrage generieren
const timestamp = Date.now();
bru.setEnvVar('dynamicEmail', `user_${timestamp}@example.com`);

// Zufällige ID generieren
bru.setEnvVar('randomId', Math.floor(Math.random() * 10000));

Anfragen verketten

// Im Post-Response-Skript der ersten Anfrage
const data = res.getBody(true);
bru.setEnvVar('userId', data.id);
// Nächste Anfrage verwendet {{userId}}

Debugging

Ausführlichen Modus aktivieren

bru run /path/to/collection --verbose

Anfrage-/Antwortwort-Details anzeigen

In Bruno GUI:

  • Anfrage anklicken
  • “Params”-Registerkarte für Query-Parameter anzeigen
  • “Body”-Registerkarte für Anfrage-Text anzeigen
  • “Response”-Registerkarte für Antwortdaten anzeigen
  • “Tests”-Registerkarte für Testergebnisse anzeigen

Console-Protokollierung

// In Pre-Request- oder Post-Response-Skripten
console.log('Variable value:', bru.getEnvVar('baseUrl'));
console.log('Full response:', res.getBody());
console.log('Status code:', res.getStatus());

Netzwerk-Inspektion

// Response-Header überprüfen
const headers = res.getHeaders();
console.log('All headers:', headers);

// Response-Zeit überprüfen
console.log('Response time:', res.getResponseTime(), 'ms');

Best Practices für Dateistruktur

api-collection/
├── README.md                 # Dokumentation
├── .gitignore               # Sensible Dateien ignorieren
├── bruno.json               # Sammlungsmetadaten
├── environments/            # Umgebungsdateien
│   ├── Development.json
│   ├── Staging.json
│   └── Production.json
├── globals.json             # Globale Variablen
├── auth/
│   ├── login.bru
│   └── refresh-token.bru
├── users/
│   ├── get-all-users.bru
│   ├── get-user-by-id.bru
│   ├── create-user.bru
│   ├── update-user.bru
│   └── delete-user.bru
├── products/
│   ├── list-products.bru
│   └── get-product.bru
└── scripts/
    ├── test-runner.js
    └── helpers.js

Ressourcen

RessourceURL
Offizielle Websiteusebruno.com
GitHub Repositorygithub.com/usebruno/bruno
Dokumentationdocs.usebruno.com
Downloadusebruno.com/downloads
Discord Communitydiscord.gg/usebruno
Bru Language Specgithub.com/usebruno/bru
API Testing Guidedocs.usebruno.com/api-testing
GitHub Issuesgithub.com/usebruno/bruno/issues

Tipps und Tricks

  • Git Diff für Reviews: Da Sammlungen Dateien sind, verwenden Sie git diff, um API-Änderungen vor dem Mergen zu überprüfen
  • Umgebungs-Templates: Erstellen Sie .example.json-Dateien für Umgebungen, um die Konfigurationsstruktur ohne Secrets zu teilen
  • Wiederverwendbare Skripte: Speichern Sie häufige Test-Skripte in separaten .js-Dateien und referenzieren Sie sie
  • Variablen-Scope: Sammlungsvariablen gelten global; Variablen auf Anfrage-Ebene überschreiben sie
  • Leistung: Verwenden Sie --failOnError-Flag in CI/CD, um Test-Fehler früh zu erkennen
  • Dokumentation: Fügen Sie Kommentare in .bru-Dateien mit // Kommentar-Syntax hinzu
  • Versionierung: Beziehen Sie die API-Version in die Base-URL-Variable ein, um einfach zwischen Versionen zu wechseln