bun test unterstützt verschiedene Ausgabeformate durch Reporter. Dieses Dokument behandelt sowohl integrierte Reporter als auch die Implementierung eigener benutzerdefinierter Reporter.
Integrierte Reporter
Standard-Konsolen-Reporter
Standardmäßig gibt bun test Ergebnisse in einem menschenlesbaren Format in der Konsole aus:
test/package-json-lint.test.ts:
✓ test/package.json [0.88ms]
✓ test/js/third_party/grpc-js/package.json [0.18ms]
✓ test/js/third_party/svelte/package.json [0.21ms]
✓ test/js/third_party/express/package.json [1.05ms]
4 bestanden
0 fehlgeschlagen
4 expect()-Aufrufe
4 Tests in 1.44ms ausgeführtWenn ein Terminal keine Farben unterstützt, vermeidet die Ausgabe nicht-ASCII-Zeichen:
test/package-json-lint.test.ts:
(pass) test/package.json [0.48ms]
(pass) test/js/third_party/grpc-js/package.json [0.10ms]
(pass) test/js/third_party/svelte/package.json [0.04ms]
(pass) test/js/third_party/express/package.json [0.04ms]
4 bestanden
0 fehlgeschlagen
4 expect()-Aufrufe
4 Tests über 1 Dateien ausgeführt. [0.66ms]Punkte-Reporter
Der Punkte-Reporter zeigt . für bestandene Tests und F für Fehler an – nützlich für große Testsuiten.
bun test --dots
bun test --reporter=dotsJUnit-XML-Reporter
Für CI/CD-Umgebungen unterstützt Bun die Generierung von JUnit-XML-Berichten. JUnit-XML ist ein weit verbreitetes Format für Testergebnisse, das von vielen CI/CD-Systemen einschließlich GitLab, Jenkins und anderen geparst werden kann.
Verwendung des JUnit-Reporters
Um einen JUnit-XML-Bericht zu generieren, verwenden Sie das --reporter=junit-Flag zusammen mit --reporter-outfile, um die Ausgabedatei anzugeben:
bun test --reporter=junit --reporter-outfile=./junit.xmlDies gibt weiterhin wie üblich in der Konsole aus und schreibt gleichzeitig den JUnit-XML-Bericht am Ende des Testlaufs in den angegebenen Pfad.
Konfiguration über bunfig.toml
Sie können den JUnit-Reporter auch in Ihrer bunfig.toml-Datei konfigurieren:
[test.reporter]
junit = "path/to/junit.xml" # Ausgabepfad für JUnit-XML-BerichtUmgebungsvariablen in JUnit-Berichten
Der JUnit-Reporter fügt automatisch Umgebungsinformationen als <properties> in die XML-Ausgabe ein. Dies kann hilfreich sein, um Testläufe in CI-Umgebungen zu verfolgen.
Insbesondere werden die folgenden Umgebungsvariablen einbezogen, wenn verfügbar:
| Umgebungsvariable | Eigenschaftsname | Beschreibung |
|---|---|---|
GITHUB_RUN_ID, GITHUB_SERVER_URL, GITHUB_REPOSITORY, CI_JOB_URL | ci | CI-Build-Informationen |
GITHUB_SHA, CI_COMMIT_SHA, GIT_SHA | commit | Git-Commit-Identifikatoren |
| System-Hostname | hostname | Maschinen-Hostname |
Dies erleichtert die Nachverfolgung, für welche Umgebung und welchen Commit ein bestimmter Testlauf war.
Aktuelle Einschränkungen
Der JUnit-Reporter hat derzeit einige Einschränkungen, die in zukünftigen Updates behoben werden:
stdout- undstderr-Ausgaben einzelner Tests sind nicht im Bericht enthalten- Präzise Zeitstempelfelder pro Testfall sind nicht enthalten
GitHub Actions-Reporter
Bun test erkennt automatisch, wenn es innerhalb von GitHub Actions ausgeführt wird, und gibt GitHub Actions-Annotationen direkt in die Konsole aus. Es ist keine spezielle Konfiguration erforderlich, außer Bun zu installieren und bun test auszuführen.
Für ein Beispiel für eine GitHub Actions-Workflow-Konfiguration siehe den Abschnitt CI/CD-Integration der CLI-Dokumentation.
Benutzerdefinierte Reporter
Bun ermöglicht es Entwicklern, benutzerdefinierte Test-Reporter zu implementieren, indem sie das WebKit Inspector Protocol mit zusätzlichen testspezifischen Domains erweitern.
Inspector Protocol für Tests
Zur Unterstützung der Testberichterstattung erweitert Bun das standardmäßige WebKit Inspector Protocol mit zwei benutzerdefinierten Domains:
- TestReporter: Meldet Test-Erkennung, Ausführungsstart und Abschluss-Events
- LifecycleReporter: Meldet Fehler und Ausnahmen während der Testausführung
Diese Erweiterungen ermöglichen es Ihnen, benutzerdefinierte Berichterstattungstools zu erstellen, die detaillierte Informationen über die Testausführung in Echtzeit empfangen können.
Wichtige Events
Benutzerdefinierte Reporter können auf diese wichtigen Events lauschen:
TestReporter.found: Wird ausgelöst, wenn ein Test entdeckt wirdTestReporter.start: Wird ausgelöst, wenn ein Test zu laufen beginntTestReporter.end: Wird ausgelöst, wenn ein Test abgeschlossen istConsole.messageAdded: Wird ausgelöst, wenn während eines Tests eine Konsolenausgabe erfolgtLifecycleReporter.error: Wird ausgelöst, wenn ein Fehler oder eine Ausnahme auftritt
Reporter-Vergleich
| Reporter | Beschreibung | Best für |
|---|---|---|
| Standard (console) | Menschenlesbare Ausgabe mit Farben und Symbolen | Lokale Entwicklung |
| dots | Zeigt . für Bestanden und F für Fehler an | Große Testsuiten |
| junit | XML-Format für CI/CD-Systeme | CI/CD-Pipelines, GitLab, Jenkins |
Reporter-Auswahl
CLI-Flags
# Standard-Reporter verwenden (standardmäßig)
bun test
# Punkte-Reporter verwenden
bun test --reporter=dots
# JUnit-Reporter mit Ausgabedatei
bun test --reporter=junit --reporter-outfile=./results.xml
# Mehrere Reporter kombinieren (wenn unterstützt)
bun test --reporter=console --reporter=junit --reporter-outfile=./results.xmlKonfigurationsdatei
[test]
# Standard-Reporter für alle Testläufe
# (derzeit nur über CLI-Flags konfigurierbar)
[test.reporter]
# JUnit-Ausgabepfad konfigurieren
junit = "./reports/junit.xml"Benutzerdefinierten Reporter erstellen
Um einen benutzerdefinierten Reporter zu erstellen, müssen Sie das Inspector Protocol verwenden und auf Test-Events lauschen.
Grundgerüst für benutzerdefinierten Reporter
import { WebSocket } from "bun";
// Dies ist ein vereinfachtes Beispiel
// Ein vollständiger Reporter würde das Inspector Protocol verwenden
interface TestEvent {
type: "found" | "start" | "end";
testFile: string;
testName?: string;
duration?: number;
error?: Error;
}
class CustomReporter {
private results: TestEvent[] = [];
onTestFound(event: TestEvent) {
this.results.push(event);
console.log(`Test gefunden: ${event.testName}`);
}
onTestStart(event: TestEvent) {
console.log(`Test startet: ${event.testName}`);
}
onTestEnd(event: TestEvent) {
console.log(`Test abgeschlossen: ${event.testName} (${event.duration}ms)`);
if (event.error) {
console.error(`Fehler: ${event.error.message}`);
}
}
onFinish() {
const passed = this.results.filter(r => !r.error).length;
const failed = this.results.filter(r => r.error).length;
console.log(`\nErgebnisse: ${passed} bestanden, ${failed} fehlgeschlagen`);
}
}HTML-Reporter-Beispiel
import { writeFile } from "bun";
interface TestResult {
file: string;
name: string;
passed: boolean;
duration: number;
error?: string;
}
class HTMLReporter {
private results: TestResult[] = [];
addResult(result: TestResult) {
this.results.push(result);
}
async generateReport(outputPath: string) {
const passed = this.results.filter(r => r.passed).length;
const failed = this.results.filter(r => !r.passed).length;
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Test-Bericht</title>
<style>
.pass { color: green; }
.fail { color: red; }
.summary { font-weight: bold; }
</style>
</head>
<body>
<h1>Test-Bericht</h1>
<p class="summary">
${passed} bestanden, ${failed} fehlgeschlagen, ${this.results.length} insgesamt
</p>
<table>
<tr>
<th>Datei</th>
<th>Test</th>
<th>Status</th>
<th>Dauer</th>
</tr>
${this.results.map(r => `
<tr class="${r.passed ? 'pass' : 'fail'}">
<td>${r.file}</td>
<td>${r.name}</td>
<td>${r.passed ? '✓' : '✗'}</td>
<td>${r.duration}ms</td>
</tr>
`).join('')}
</table>
</body>
</html>
`;
await writeFile(outputPath, html);
}
}JSON-Reporter-Beispiel
import { writeFile } from "bun";
interface TestResult {
file: string;
name: string;
passed: boolean;
duration: number;
error?: string;
}
interface TestReport {
timestamp: string;
total: number;
passed: number;
failed: number;
results: TestResult[];
}
class JSONReporter {
private results: TestResult[] = [];
addResult(result: TestResult) {
this.results.push(result);
}
async generateReport(outputPath: string) {
const passed = this.results.filter(r => r.passed).length;
const failed = this.results.filter(r => !r.passed).length;
const report: TestReport = {
timestamp: new Date().toISOString(),
total: this.results.length,
passed,
failed,
results: this.results,
};
await writeFile(outputPath, JSON.stringify(report, null, 2));
}
}Reporter in CI/CD verwenden
GitHub Actions
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun test --reporter=junit --reporter-outfile=./junit.xml
- name: JUnit-Bericht hochladen
uses: actions/upload-artifact@v3
with:
name: test-results
path: ./junit.xmlGitLab CI
test:
stage: test
script:
- bun install
- bun test --reporter=junit --reporter-outfile=./report.xml
artifacts:
reports:
junit: ./report.xmlJenkins
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'bun install'
sh 'bun test --reporter=junit --reporter-outfile=./report.xml'
}
post {
always {
junit 'report.xml'
}
}
}
}
}Best Practices
Lokale Entwicklung
Für die lokale Entwicklung ist der Standard-Konsolen-Reporter normalerweise am besten:
# Standardausgabe für lokale Entwicklung
bun test
# Punkte-Reporter für schnellere Übersicht bei großen Testsuiten
bun test --dotsCI/CD-Pipelines
Für CI/CD-Umgebungen sollten Sie JUnit-XML für Integration mit CI-Tools verwenden:
# JUnit für CI-Integration
bun test --reporter=junit --reporter-outfile=./test-results.xmlMehrere Reporter
Wenn Sie mehrere Ausgabeformate benötigen:
# Sowohl Konsolen- als auch JUnit-Ausgabe
bun test --reporter=junit --reporter-outfile=./results.xml
# Konsolenausgabe erfolgt weiterhin standardmäßigBenutzerdefinierte Reporter
Erstellen Sie benutzerdefinierte Reporter für spezielle Anforderungen:
- HTML-Berichte für Stakeholder
- JSON-Berichte für benutzerdefinierte Verarbeitung
- Integration mit proprietären Systemen