Buns Test-Runner unterstützt jetzt integrierte Code-Coverage-Berichterstattung. Dies macht es einfach zu sehen, wie viel der Codebasis von Tests abgedeckt ist, und Bereiche zu finden, die derzeit nicht gut getestet sind.
Coverage aktivieren
bun:test unterstützt das Anzeigen, welche Codezeilen von Tests abgedeckt sind. Um diese Funktion zu verwenden, übergeben Sie --coverage an die CLI. Es gibt einen Coverage-Bericht in der Konsole aus:
bun test --coverage
-------------|---------|---------|-------------------
File | % Funcs | % Lines | Uncovered Line #s
-------------|---------|---------|-------------------
All files | 38.89 | 42.11 |
index-0.ts | 33.33 | 36.84 | 10-15,19-24
index-1.ts | 33.33 | 36.84 | 10-15,19-24
index-10.ts | 33.33 | 36.84 | 10-15,19-24
index-2.ts | 33.33 | 36.84 | 10-15,19-24
index-3.ts | 33.33 | 36.84 | 10-15,19-24
index-4.ts | 33.33 | 36.84 | 10-15,19-24
index-5.ts | 33.33 | 36.84 | 10-15,19-24
index-6.ts | 33.33 | 36.84 | 10-15,19-24
index-7.ts | 33.33 | 36.84 | 10-15,19-24
index-8.ts | 33.33 | 36.84 | 10-15,19-24
index-9.ts | 33.33 | 36.84 | 10-15,19-24
index.ts | 100.00 | 100.00 |
-------------|---------|---------|-------------------Standardmäßig aktivieren
Um die Coverage-Berichterstattung standardmäßig immer zu aktivieren, fügen Sie die folgende Zeile zu Ihrer bunfig.toml hinzu:
[test]
# Coverage immer aktivieren
coverage = trueStandardmäßig enthalten Coverage-Berichte Testdateien und schließen Sourcemaps aus. Dies ist normalerweise das, was Sie wollen, aber es kann in bunfig.toml anders konfiguriert werden.
[test]
coverageSkipTestFiles = true # Standard falseCoverage-Schwellenwerte
Es ist möglich, einen Coverage-Schwellenwert in bunfig.toml anzugeben. Wenn Ihre Testsuite diesen Schwellenwert nicht erreicht oder überschreitet, wird bun test mit einem Nicht-Null-Exit-Code beendet, um den Fehler anzuzeigen.
Einfacher Schwellenwert
[test]
# Um 90% Zeilen- und Funktions-Coverage zu erfordern
coverageThreshold = 0.9Detaillierte Schwellenwerte
[test]
# Um unterschiedliche Schwellenwerte für Zeilen und Funktionen festzulegen
coverageThreshold = { lines = 0.9, functions = 0.9, statements = 0.9 }Das Festlegen eines dieser Schwellenwerte aktiviert fail_on_low_coverage, wodurch der Testlauf fehlschlägt, wenn die Coverage unter dem Schwellenwert liegt.
Coverage-Reporter
Standardmäßig werden Coverage-Berichte in der Konsole ausgegeben.
Für persistente Coverage-Berichte in CI-Umgebungen und für andere Tools können Sie eine --coverage-reporter=lcov-CLI-Option oder coverageReporter-Option in bunfig.toml übergeben.
[test]
coverageReporter = ["text", "lcov"] # Standard ["text"]
coverageDir = "path/to/somewhere" # Standard "coverage"Verfügbare Reporter
| Reporter | Beschreibung |
|---|---|
text | Gibt eine Textzusammenfassung der Coverage in der Konsole aus |
lcov | Speichert Coverage im lcov-Format |
LCOV-Coverage-Reporter
Um einen lcov-Bericht zu generieren, können Sie den lcov-Reporter verwenden. Dies generiert eine lcov.info-Datei im Coverage-Verzeichnis.
[test]
coverageReporter = "lcov"# Oder über CLI
bun test --coverage --coverage-reporter=lcovDas LCOV-Format wird von verschiedenen Tools und Diensten umfassend unterstützt:
- Code-Editoren: VS Code-Erweiterungen können Coverage inline anzeigen
- CI/CD-Dienste: GitHub Actions, GitLab CI, CircleCI
- Coverage-Dienste: Codecov, Coveralls
- IDEs: WebStorm, IntelliJ IDEA
Verwendung von LCOV mit GitHub Actions
name: Test mit Coverage
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 --coverage --coverage-reporter=lcov
- name: Coverage zu Codecov hochladen
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.infoDateien von Coverage ausschließen
Testdateien überspringen
Standardmäßig sind Testdateien in Coverage-Berichten enthalten. Sie können sie ausschließen mit:
[test]
coverageSkipTestFiles = true # Standard falseDies schließt Dateien, die mit Testmustern übereinstimmen (z. B. *.test.ts, *.spec.js), vom Coverage-Bericht aus.
Bestimmte Pfade und Muster ignorieren
Sie können bestimmte Dateien oder Dateimuster von Coverage-Berichten ausschließen, indem Sie coveragePathIgnorePatterns verwenden:
[test]
# Einzelnes Muster
coveragePathIgnorePatterns = "**/*.spec.ts"
# Mehrere Muster
coveragePathIgnorePatterns = [
"**/*.spec.ts",
"**/*.test.ts",
"src/utils/**",
"*.config.js"
]Diese Option akzeptiert Glob-Muster und funktioniert ähnlich wie Jests collectCoverageFrom-Ignore-Muster. Dateien, die mit einem dieser Muster übereinstimmen, werden von der Coverage-Berechnung und -Berichterstattung sowohl in Text- als auch in LCOV-Ausgaben ausgeschlossen.
Häufige Anwendungsfälle
[test]
coveragePathIgnorePatterns = [
# Utility-Dateien ausschließen
"src/utils/**",
# Konfigurationsdateien ausschließen
"*.config.js",
"webpack.config.ts",
"vite.config.ts",
# Bestimmte Testmuster ausschließen
"**/*.spec.ts",
"**/*.e2e.ts",
# Build-Artefakte ausschließen
"dist/**",
"build/**",
# Generierte Dateien ausschließen
"src/generated/**",
"**/*.generated.ts",
# Vendor/Third-Party-Code ausschließen
"vendor/**",
"third-party/**"
]Sourcemaps
Intern transpiliert Bun standardmäßig alle Dateien, sodass Bun automatisch eine interne Source-Map generiert, die Zeilen Ihres ursprünglichen Quellcodes auf Buns interne Darstellung abbildet. Wenn Sie dies aus irgendeinem Grund deaktivieren möchten, setzen Sie test.coverageIgnoreSourcemaps auf true; dies ist selten außerhalb von fortgeschrittenen Anwendungsfällen wünschenswert.
[test]
coverageIgnoreSourcemaps = true # Standard falseCoverage-Standards
Standardmäßig schließen Coverage-Berichte:
- Aus
node_modules-Verzeichnisse - Aus Dateien, die über Nicht-JS/TS-Loader geladen werden (z. B.
.css,.txt), es sei denn, ein benutzerdefinierter JS-Loader wird angegeben - Ein Testdateien selbst (kann mit
coverageSkipTestFiles = truedeaktiviert werden) - Können zusätzliche Dateien mit
coveragePathIgnorePatternsausschließen
Erweiterte Konfiguration
Benutzerdefiniertes Coverage-Verzeichnis
[test]
coverageDir = "coverage-reports" # Standard "coverage"Mehrere Reporter
[test]
coverageReporter = ["text", "lcov"]Coverage mit bestimmten Testmustern
# Coverage nur für bestimmte Testdateien ausführen
bun test --coverage src/components/*.test.ts
# Coverage mit Namensmuster ausführen
bun test --coverage --test-name-pattern="API"CI/CD-Integration
GitHub Actions-Beispiel
name: Coverage-Bericht
on: [push, pull_request]
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Bun einrichten
uses: oven-sh/setup-bun@v2
- name: Abhängigkeiten installieren
run: bun install
- name: Tests mit Coverage ausführen
run: bun test --coverage --coverage-reporter=lcov
- name: Zu Codecov hochladen
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
fail_ci_if_error: trueGitLab CI-Beispiel
test:coverage:
stage: test
script:
- bun install
- bun test --coverage --coverage-reporter=lcov
coverage: '/Lines\s*:\s*(\d+.\d+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/lcov.infoCoverage-Berichte interpretieren
Textausgabe-Erklärung
-------------|---------|---------|-------------------
File | % Funcs | % Lines | Uncovered Line #s
-------------|---------|---------|-------------------
All files | 85.71 | 90.48 |
src/ | 85.71 | 90.48 |
utils.ts | 100.00 | 100.00 |
api.ts | 75.00 | 85.71 | 15-18,25
main.ts | 80.00 | 88.89 | 42,50-52
-------------|---------|---------|-------------------- % Funcs: Prozentsatz der Funktionen, die während der Tests aufgerufen wurden
- % Lines: Prozentsatz der ausführbaren Zeilen, die während der Tests ausgeführt wurden
- Uncovered Line #s: Spezifische Zeilennummern, die nicht ausgeführt wurden
Was man anstreben sollte
- 80%+ Gesamt-Coverage: Wird allgemein als gut angesehen
- 90%+ kritische Pfade: Wichtige Geschäftslogik sollte gut getestet sein
- 100% Utility-Funktionen: Pure Funktionen und Utilities sind einfach vollständig zu testen
- Niedrigere Coverage für UI-Komponenten: Oft akzeptabel, da sie Integrationstests erfordern können
Best Practices
Fokus auf Qualität, nicht nur Quantität
// Gut: Tatsächliche Funktionalität testen
test("calculateTax sollte verschiedene Steuersätze handhaben", () => {
expect(calculateTax(100, 0.08)).toBe(8);
expect(calculateTax(100, 0.1)).toBe(10);
expect(calculateTax(0, 0.08)).toBe(0);
});
// Vermeiden: Nur Zeilen für Coverage treffen
test("calculateTax existiert", () => {
calculateTax(100, 0.08); // Keine Assertions!
});Randfälle testen
test("Benutzereingabe-Validierung", () => {
// Normalen Fall testen
expect(validateEmail("user@example.com")).toBe(true);
// Randfälle testen, die Coverage sinnvoll verbessern
expect(validateEmail("")).toBe(false);
expect(validateEmail("invalid")).toBe(false);
expect(validateEmail(null)).toBe(false);
});Coverage verwenden, um fehlende Tests zu finden
# Coverage ausführen, um ungetesteten Code zu identifizieren
bun test --coverage
# Bestimmte Dateien ansehen, die Aufmerksamkeit benötigen
bun test --coverage src/critical-module.tsMit anderen Qualitätsmetriken kombinieren
Coverage ist nur eine Metrik. Berücksichtigen Sie auch:
- Code-Review-Qualität
- Integrationstest-Coverage
- Fehlerbehandlungstests
- Performance-Tests
- Typsicherheit
Fehlerbehebung
Coverage wird für einige Dateien nicht angezeigt
Wenn Dateien nicht in Coverage-Berichten erscheinen, wurden sie möglicherweise nicht von Ihren Tests importiert. Coverage verfolgt nur Dateien, die tatsächlich geladen werden.
// Stellen Sie sicher, dass Sie die zu testenden Module importieren
import { myFunction } from "../src/my-module";
test("meine Funktion funktioniert", () => {
expect(myFunction()).toBeDefined();
});Falsche Coverage-Berichte
Wenn Sie Coverage-Berichte sehen, die nicht Ihren Erwartungen entsprechen:
- Überprüfen Sie, ob Source-Maps korrekt funktionieren
- Überprüfen Sie Dateimuster in
coveragePathIgnorePatterns - Stellen Sie sicher, dass Testdateien tatsächlich den zu testenden Code importieren
Performance-Probleme mit großen Codebasen
Für große Projekte kann die Coverage-Sammlung Tests verlangsamen:
[test]
# Große Verzeichnisse ausschließen, für die Sie keine Coverage benötigen
coveragePathIgnorePatterns = [
"node_modules/**",
"vendor/**",
"generated/**"
]Erwägen Sie, Coverage nur in CI oder bestimmten Branches auszuführen, anstatt bei jedem Testlauf während der Entwicklung.