VOLLSTÄNDIGER LEITFADEN

Benutzerhandbuch

Von Ihrer ersten Tracefile bis zur Compliance-Prüfung nach Sicherheitsnormen — alles, was Fucini Coverage Studio kann, und genau, wie Sie es bedienen.

VSIX herunterladen

1. Einführung

Fucini Coverage Studio macht aus den Coverage-Tracedateien, die Ihr Build bereits erzeugt, vollwertige Coverage im Editor — in VS Code und in Visual Studio. Es liest fünfundzwanzig Formate, normalisiert sie in ein kanonisches Fucini-Modell, führt mehrere Läufe deterministisch zusammen und zeigt das Ergebnis im Editor selbst — Randleiste, CodeLens, Hover und eine Covered-Files-Ansicht —, sodass es keinen separaten Viewer gibt, für den Sie den Editor verlassen müssten. Die beiden Editionen teilen sich einen Reader: Derselbe Bericht liefert in beiden dieselben Zahlen, auf die Stelle genau. Dieses Handbuch ist aus Sicht von VS Code geschrieben; wo Visual Studio abweicht, sagt ein Kasten In Visual Studio, wie.

Sie wurde mit Blick auf funktionale Sicherheitsprozesse entwickelt: MC/DC-Coverage, Region- und C++-Instanziierungs-Coverage, ein sicherheitsgewichteter Gesamtscore sowie ein konfigurierbares COMPLIANT-/NON-COMPLIANT-Urteil, das sich an den Denkweisen von IEC 61508, ISO 26262 und DO-178C orientiert.

Fucini Coverage Studio in VS Code: a file opened from the Coverage view, uncovered lines and half-taken branches in the editor, the MC/DC hover, the heatmap, the status-bar card and the annotated sourceScreenshot pending — add assets/img/marketplace-demo.gif (see SCREENSHOTS.md).

2. Installation & Voraussetzungen

  • VS Code ≥ 1.88 — die Mindestversion, die diese Erweiterung unterstützt — oder Visual Studio 2022 oder 2026, Community, Professional oder Enterprise (siehe den Kasten unten).
  • Eine Coverage-Tracedatei, die Ihr Projekt bereits erzeugt (siehe §4).

Installieren Sie die Erweiterung über den Marketplace oder aus einer .vsix-Datei über Extensions → ⋯ → Install from VSIX…. Die Erweiterung aktiviert sich beim Start und fügt der Aktivitätsleiste ein Coverage-Symbol hinzu.

In Visual Studio. Dasselbe Produkt erscheint als zweite Erweiterung, Fucini Coverage Studio für Visual Studio, für Visual Studio 2022 und 2026 — Community, Professional und Enterprise. Es verwendet nicht Visual Studios eigene Code Coverage: In Visual Studio 2022 ist das eine Enterprise-Funktion, sodass dies auf Community und Professional die einzige Coverage ist, die die IDE zeigt. Installieren Sie die .vsix, indem Sie sie öffnen — der VSIX Installer fragt, welches Visual Studio — oder über Extensions → Manage Extensions; die Erweiterung lädt, wenn eine Projektmappe oder ein Ordner geöffnet wird. Das Coverage-Fenster braucht die Microsoft Edge WebView2 Runtime, die Windows 11 und Visual Studio 2026 bereits mitbringen; die Markierungen im Editor funktionieren auch ohne.

3. Schnellstart

Möchten Sie sehen, wie es funktioniert, bevor Sie Ihr eigenes Projekt anbinden? Laden Sie das Demoprojekt herunter (~6 KB — ein kleines C-Projekt mit einer fertigen lcov.info):

  1. Entpacken Sie es irgendwo und öffnen Sie dann coverage-studio-demo.code-workspace in VS Code (File → Open Workspace from File…).
  2. Installieren Sie Fucini Coverage Studio, falls noch nicht geschehen (siehe §2 oben).
  3. Die eigene .vscode/settings.json des Workspace verweist bereits auf die mitgelieferte coverage/lcov.info, sodass Gutter und die Ansicht Covered Files erscheinen, sobald die Erweiterung aktiviert wird — kein Load Coverage-Schritt nötig.
  4. Möchten Sie die Tracedatei selbst neu erzeugen (z. B. mit einem anderen Compiler)? Führen Sie scripts/gen-coverage.sh aus (oder .ps1 unter Windows) — die verfügbaren Compiler-Ziele finden Sie in der eigenen README.md des Workspace.

In Visual Studio. Öffnen Sie eine Projektmappe oder einen Ordner (File → Open → Folder, so wird ein CMake-Projekt geöffnet) — die Demo oben öffnet sich als Ordner, und ihre .vscode/settings.json wird auch dort gelesen. Ein Bericht an der Stelle, die die Einstellungen nennen, wird von selbst geladen, und das Fucini Coverage-Fenster der Ausgabe sagt, welche Dateien; andernfalls Tools → Coverage Studio → Load Coverage File…, einmal — es wird gemerkt. Öffnen Sie eine Quelldatei und wählen Sie Show Coverage in Editor: Rot ist eine Zeile, die nie lief, Bernstein eine Entscheidung, die nur in eine Richtung ging, und Ctrl+Shift+U, N springt zur nächsten nicht abgedeckten Zeile. View → Other Windows → Coverage ist der Baum mit den Zahlen jeder Datei und einem Wert über alle, den die Statusleiste für den Lauf und für die Datei zeigt, in der Sie sind. Tools → Coverage Studio → Getting Started öffnet diese Schritte als Seite mit einem Knopf für jeden; beim ersten Mal öffnet sie sich von selbst.

  1. Erzeugen Sie mit Ihrem üblichen Test-Workflow eine Coverage-Tracefile.
  2. Befehlspalette (Ctrl+Shift+P) → Fucini Coverage: Load Coverage. Ist watch.enabled aktiviert (Standard), wird eine passende Datei automatisch geladen.
  3. Öffnen Sie eine erfasste Quelldatei: Die Statusleiste zeigt ihren Prozentwert, die Coverage-Ansicht füllt sich, das Überfahren einer Zeile zeigt ihre Trefferzahl, und der Lauf erscheint im nativen Test Coverage-Panel. Balken auf nicht abgedeckten Zeilen, eine Heatmap der Trefferzahlen und Inline-×N-Zähler sind eine Einstellung entfernt (editorGutter.mode, hitCounts.inline).
Covered (green) and uncovered (red) gutters in the editorScreenshot pending — add assets/img/gutters.png (see SCREENSHOTS.md).

4. Tracefiles erzeugen

Beim Laden werden folgende Formate automatisch erkannt:

Vollständige Copy-&-Paste-Rezepte für jeden Compiler — darunter Swift, Rust, Go, Python, .NET, PHP und mehr — auf der Seite Coverage-Rezepte: Swift · Clang · GCC · Rust · Go · Python · Java/Kotlin · JS/TS · .NET · PHP · Ruby.

C / C++ — LLVM (llvm-cov)

clang --coverage -fprofile-instr-generate -fcoverage-mapping test.c -o test
LLVM_PROFILE_FILE=test.profraw ./test
llvm-profdata merge -sparse test.profraw -o test.profdata
llvm-cov export ./test -instr-profile=test.profdata --format=json > coverage.json

llvm-cov-JSON ist die umfangreichste Eingabe — sie enthält neben Zeilen, Branches und Funktionen auch Regionen, MC/DC und C++-Template-Instanziierungen.

C / C++ — GCC (gcov → lcov)

gcc --coverage calc.c calc_test.c -o test && ./test
lcov --capture --directory . --output-file lcov.info
# or gcovr --cobertura coverage.xml
# or skip the conversion entirely: gcovr --json coverage.json

JavaScript / TypeScript — Istanbul / nyc

nyc --reporter=json mocha        # emits coverage/coverage-final.json

Java — JaCoCo

mvn test        # emits target/site/jacoco/jacoco.xml

Ruby — SimpleCov

# .resultset.json (built-in) or coverage.json via the simplecov-json gem

Go

go test ./... -coverprofile=coverage.out    # read directly, no conversion

Python — coverage.py

coverage run --branch -m pytest && coverage json    # emits coverage.json

PHP — PHPUnit (Clover)

XDEBUG_MODE=coverage phpunit --coverage-clover clover.xml

.NET / C# — Coverlet (OpenCover)

dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
FormatTypische DateiZusätzliche Metriken
LCOVlcov.infoZeilen, Zweige, Funktionen
llvm-cov JSONcoverage.json+ Regionen, MC/DC, Instanziierungen
Cobertura XMLcoverage.xmlZeilen, Zweige
JaCoCo XMLjacoco.xmlZeilen, Zweige, Funktionen
Istanbul / nyccoverage-final.jsonAnweisungen, Zweige, Funktionen
SimpleCov.resultset.jsonZeilen
Clover XMLclover.xmlZeilen, Zweige, Funktionen
OpenCover XMLcoverage.opencover.xmlZeilen, Zweige, Funktionen
coverage.py JSONcoverage.jsonZeilen, Zweige
gcov / gcovr JSONcoverage.jsonZeilen, Zweige, Funktionen
Go coverage profilecoverage.outZeilen
SonarQube genericcoverage.xmlZeilen, Zweige
GNATcoverage XML (Ada)*.xmlZeilen, Zweige, MC/DC
BullseyeCoverage XMLcoverage.xmlZeilen, Bedingung/Entscheidung
Visual Studio*.coveragexmlZeilen, Zweige
Coveralls JSONcoveralls.jsonZeilen, Zweige
Xcode xccov JSONcoverage.jsonFunktionen und Dateisummen — keine Daten pro Zeile
gcov plain text*.gcovZeilen, Zweige, Funktionsaufrufe
VectorCASTcoverage.xmlZeilen, Zweige, MC/DC-Paare, Funktionen, Funktionsaufrufe
Testwell CTC++*.txtZeilen, Bedingung/Entscheidung
Lauterbach TRACE32*.xmlAnweisungen, Entscheidungen, Bedingungen, MC/DC, Funktionen, Aufrufe, Objektcode
EMMA XML (Java)coverage.xmlZeilen
UCIS / Aldec UCDB*.xmlAnweisungen, Entscheidungszweige
NCover XMLCoverage.xmlZeilen, Funktionen
dotCover DetailedXMLdotCover.xmlZeilen, Funktionen
PIT (mutation)mutations.xmlMutations-Score — keine Coverage
Stryker (mutation)mutation-report.jsonMutations-Score — keine Coverage

Ein natives C++-Projekt, aus Visual Studio heraus gemessen

In Visual Studio. Visual Studios eigene Coverage eines C++-Projekts war Enterprise-only, und das kostenlose OpenCppCoverage-Plugin, das die Lücke füllte, wurde eingestellt. Tools → Coverage Studio → Run Native Project with Coverage nimmt das Startprojekt — eine .vcxproj —, fragt MSBuild, wohin es baut und mit welchem Toolset, und misst es auf eine von zwei Arten. Auf dem ClangCL-Toolset, mit LLVMs llvm-profdata und llvm-cov auf dem Rechner (Visual Studios Komponente C++ Clang tools for Windows bringt sie mit), baut es das Projekt erneut nach coverage\native\ mit -fprofile-instr-generate -fcoverage-mapping, über eine Props-Datei, die MSBuild zuerst importieren soll — am Projekt ändert sich nichts —, führt das Programm mit gesetztem LLVM_PROFILE_FILE aus, führt das Profil zusammen und exportiert coverage\native\lcov.info, regionsgenau. Auf jedem anderen Toolset, mit installiertem OpenCppCoverage, baut es das Projekt, wie es ist — ein Debug-Build hat die PDBs —, und führt es unter OpenCppCoverage aus, das coverage\native\opencppcoverage.xml schreibt. Jeder Befehl geht in den Fucini Coverage-Bereich, und der Bericht wird geladen und gemerkt wie der eines Testlaufs. Einem Projekt, das sich nicht messen lässt, wird gesagt, warum und was zu installieren ist. MSBuild 17.8 (Visual Studio 2022 17.8) oder neuer, für die Frage, die es stellt.

Visual Studio: Run Native Project with Coverage on a C++ project — the instrumented build, the run, and the gutter filling inScreenshot pending — add assets/img/vs-native-run.gif (see SCREENSHOTS.md).
In Visual Studio: Run Native Project with Coverage auf einem C++-Projekt — der Build, der Lauf und der Editor, der sich füllt.

5. Laden & Erkennung

Standardmäßig durchsucht die Erweiterung das Workspace-Stammverzeichnis. Steuern Sie dies präziser mit zwei Einstellungen:

{
  "fuciniCoverage.coverageFile.defaultLocation": "${workspaceFolder}/build",
  "fuciniCoverage.coverageFile.paths": [
    "coverage.json",
    "reports/*.info",
    "${env:CI_ARTIFACTS}/lcov.info",
    "https://ci.example.com/artifacts/latest/coverage.xml"
  ]
}
  • Jeder Eintrag in paths ist relativ zu defaultLocation (oder zum Workspace-Stamm, wenn nicht festgelegt).
  • Ein Eintrag mit * wird rekursiv durchsucht; ein reiner Dateiname wird nur direkt im Basisordner gefunden.
  • Ist paths leer, sucht die Erweiterung zuerst nach coverage.json, dann nach lcov.info, und lädt, was sie zuerst findet.
  • Pick Coverage File verwendet die von Ihnen gewählten Dateien anstelle dieser Pfade — jede Auswahl kommt hinzu, und alle werden zusammengeführt —, bis Sie sie entladen oder diese Einstellungen ändern.
  • Variablen — jede Pfadeinstellung expandiert ${workspaceFolder}, ${workspaceFolderBasename}, ${userHome}, ${env:NAME}, ${command:id} und ${config:section.key}. Eine Variable, die die Erweiterung nicht kennt, bleibt stehen, wie sie geschrieben wurde, sodass ein Tippfehler im Erkennungsprotokoll als der gesuchte Pfad auftaucht, statt zu verschwinden. ${command:id} führt diesen Befehl zuerst aus — nur in einem vertrauenswürdigen Arbeitsbereich und höchstens fünf Sekunden lang —, sodass ${command:cmake.buildDirectory} dem gewählten CMake-Kit folgt.
  • URL-Einträge — ein http(s)://-Eintrag wird bei jedem Laden in den Speicher der Erweiterung geholt und von dort geladen; die Coverage-Ansicht nennt die URL. Jeder Abruf ist bedingt (ETag / Last-Modified), sodass ein unverändertes Artefakt nichts herunterlädt, und schlägt ein Abruf fehl, wird stattdessen die zuletzt heruntergeladene Kopie geladen, mit dem Grund in der Ausgabe. remote.headers fügt Name: value-Header mit expandierten Variablen hinzu, remote.refreshMinutes ruft nach einem Zeitplan erneut ab, und ein #lcov.info-Fragment nennt das Format, wenn die URL selbst nicht auf einen Dateinamen endet.
  • Ignore-Globs — fuciniCoverage.ignore entfernt ganze Dateien (vendored, generiert, von Dritten) beim Laden aus dem Lauf, sodass jede Ansicht, jedes Gate und jeder Export ohne sie zählt; das Ladeergebnis sagt, wie viele weggelassen wurden, und die Ausgabe nennt sie. Muster passen auf den arbeitsbereichsrelativen und den absoluten Pfad, und ein Muster ohne / passt auf einen Ordner- oder Dateinamen in beliebiger Tiefe, wie in .gitignore.
  • Multi-Root-Arbeitsbereiche — jeder Ordner wird nach seinen eigenen Regeln erkannt: defaultLocation, paths, pathRemap, ignore, watch.* und remote.* werden je Ordner gelesen, sodass die eigene .vscode/settings.json eines Ordners oder sein .code-workspace-Eintrag gilt, und ${workspaceFolder} in einem Eintrag meint den eigenen Ordner dieses Eintrags. Die Tracedateien aller Ordner verschmelzen zu einem Lauf, die Coverage-Ansicht gruppiert die Dateien nach Ordner, und ein zum Arbeitsbereich hinzugefügter oder daraus entfernter Ordner lädt die Coverage von selbst neu.
  • Neuladen nach einer Aufgabe — watch.reloadAfterTasks nennt Aufgaben (ein label aus der tasks.json, oder source: name, wie die Liste von Run Task es zeigt), deren Ende die Coverage neu lädt, ob watch.enabled nun an ist oder nicht — für Builds, denen der Watcher nicht folgen kann. Ein absoluter paths-Eintrag außerhalb des Arbeitsbereichs wird ebenfalls abgefragt, sodass eine dort erscheinende Datei geladen wird.
  • Fortschritt, den Sie abbrechen können — ein Ladevorgang mit zehn oder mehr Tracedateien, oder 8 MB oder mehr davon, läuft unter einer Fortschrittsbenachrichtigung mit einer Abbrechen-Schaltfläche, die die gerade gelesene Datei und die Phase nennt; ein kleinerer lässt nur die Statusleiste kreisen. Ein Abbruch lässt den vorherigen Lauf geladen und sagt das.

Seit 1.2026.6 darf auch ein absoluter Eintrag einen Platzhalter enthalten: ${workspaceFolder}/build/coverage-merged/*.lcov.info lädt jede solche Datei in diesem Ordner, und ** steht für beliebige Tiefe. Gesucht wird in den Ordnern vor dem ersten Platzhalter, und sie werden beobachtet, sodass ein Bericht, den ein Build dort schreibt, von selbst lädt. Die Visual-Studio-Edition liest einen solchen Eintrag genauso, und seit 1.2026.5 wird ein relativer Platzhalter auch dort in beliebiger Tiefe gesucht, wie es hier schon immer der Fall war.

Ist kein paths konfiguriert, wird der erste der bekannten Berichtsnamen geladen, der unterhalb des Basisordners gefunden wird. Zuerst die vier, nach denen schon immer gesucht wurde – coverage.json, lcov.info, coverage.out, clover.xml –, dann, seit 0.2026.83, jacoco.xml, coverage.xml, cobertura.xml, coverage.cobertura.xml, coverage.opencover.xml und coverage-final.json, und danach die Orte, an die Standardkonfigurationen schreiben: coverage/ (nyc, Jest, vitest, PHPUnit, SimpleCov), target/site/jacoco/jacoco.xml (Maven), build/reports/jacoco/test/jacocoTestReport.xml (Gradle) und TestResults/*/coverage.cobertura.xml (dotnet test). So zeigt ein Java- oder .NET-Projekt seine Abdeckung gleich beim ersten Öffnen, wie es ein lcov-Projekt schon immer getan hat.

Seit 1.2026.3 braucht eine .NET-Projektmappe noch weniger: Der Ordner TestResults/<run>/ jedes Testprojekts gehört zu den bekannten Orten, nicht nur der des Arbeitsbereichsordners selbst, und die <user>_<machine>_<date>.cobertura.xml von Microsofts Collector wird neben Coverlets coverage.cobertura.xml gefunden — eine Projektmappe, deren Tests im Test Explorer von Visual Studio gelaufen sind, zeigt ihre Coverage also beim ersten Öffnen, jeder Lauf-Ordner wird geladen, und die Zusammenführung behält für jede Datei das Wort des neuesten Laufs. Und fuciniCoverage.ignore.generated, standardmäßig an, lässt Designer- und generierte Dateien — *.Designer.cs, *.g.cs, *.generated.cs, *.razor.g.cs, AssemblyInfo, globale Usings, Migrations/ und obj/ — aus jeder Summe, jeder Seite und jedem Export heraus, bevor ignore angewandt wird, sodass eine generierte Tabelle, die niemand testet, die Projektmappe nicht ihr Gate kostet.

In Visual Studio: Coverage nach jedem Testlauf. Führen Sie Ihre Tests wie gewohnt aus. Tools → Coverage Studio → Collect Coverage in Test Explorer… legt eine .runsettings mit Microsofts Cobertura-Collector neben die Projektmappe. Visual Studio nimmt sie auf, wenn Tools → Options → Test → Auto detect runsettings files eingeschaltet ist; andernfalls wählen Sie sie einmal unter Test → Configure Run Settings aus. Von da an schreibt jeder Lauf einen Bericht unter das Testprojekt, und die Überwachung der Projektmappe lädt ihn in dem Moment, in dem er erscheint, zusammengeführt mit allem, was die Einstellungen benennen — aus dem Test Explorer, einem Terminal oder einem Skript gleichermaßen. Nichts hängt sich in den Test Explorer ein, sodass Visual Studio 2026 und Microsoft.Testing.Platform funktionieren, wie sie sind. Run Tests with Coverage ist der Befehl aus VS Code: Er erkennt dotnet test, vitest, jest, pytest, go, cargo, maven, gradle, phpunit und ctest, führt die Tests mit eingeschalteter Coverage im Output-Fenster aus und lädt, was sie geschrieben haben; ein Testprojekt ohne coverlet.collector wird mit dem Collector ausgeführt, den das Test-SDK mitbringt, und testRun.skipWhenTestsFail behält die letzte gute Coverage auf dem Bildschirm, wenn ein Lauf rot endet.

Ein CI-Artefakt hinter einem Token, jede Viertelstunde erneut geprüft — das Token bleibt in der Umgebung, nie in der settings.json:

{
  "fuciniCoverage.coverageFile.paths": [
    "https://ci.example.com/api/builds/latest/artifacts/coverage#lcov.info"
  ],
  "fuciniCoverage.remote.headers": ["Authorization: Bearer ${env:CI_TOKEN}"],
  "fuciniCoverage.remote.refreshMinutes": 15
}
A tracefile loaded from a URL: the Coverage view names the address it came fromScreenshot pending — add assets/img/remote-tracefile.png (see SCREENSHOTS.md).

Ein Neuladen ist absichtlich still – ein Dialog nach jedem Build ist eine Frage mit nur einer Antwort. Nicht still ist das Coverage-Symbol: Solange die Ansicht nicht vor Ihnen liegt, trägt es die Zahl der erneut gelesenen Tracefiles, und sein Tooltip nennt sie beim Namen. Öffnen Sie die Ansicht, und die Zahl ist weg.

A build rewrites two reports while the Explorer is open: the Coverage icon in the activity bar gains a count, its tooltip names what reloaded, and opening the view clears itScreenshot pending — add assets/img/coverage-badge.gif (see SCREENSHOTS.md).

Dateien, die nie zählen sollen, was auch immer die Tracedatei über sie sagt:

{
  "fuciniCoverage.ignore": ["vendor/**", "**/*.generated.ts", "build/**"]
}

Ein Neuladen, wenn die Testaufgabe endet, für einen Build, dem der Datei-Watcher nicht folgen kann — ein Lauf, der einen per Symlink eingebundenen Ausgabebaum ersetzt, ein Bericht auf einer Netzwerkfreigabe, ein Coverage-Schritt, der seine Datei nachbearbeitet:

{
  "fuciniCoverage.watch.reloadAfterTasks": ["npm: test", "coverage-report"]
}

6. Läufe zusammenführen

Jeder vorhandene paths-Eintrag wird geladen und zu einem Lauf zusammengeführt. Das Zusammenführen ist deterministisch — das Ergebnis hängt nicht von der Ladereihenfolge ab — und eine Datei, die mehr als ein Tracefile gemessen hat, nimmt ihre Zahlen von dem mit der neuesten mtime auf der Festplatte: der eigene Neulauf eines Moduls ersetzt, was ein breiterer, älterer Lauf über sie gesagt hat, statt es zu ergänzen. Die Abdeckungsansicht zeigt, was das bewirkt hat: jede Dateizeile nennt das Tracefile, aus dem ihre Zahlen stammen, das Abzeichen ist umrandet, wo diese Zahlen einen älteren Bericht überstimmt haben, jede Tracefile-Zeile über dem Baum zählt, wie viele ihrer Dateien überstimmt wurden oder andere überstimmt haben, und ein Klick auf eine Tracefile-Zeile hebt ihre Dateien im Baum hervor, bis sie erneut angeklickt wird (coverageView.mergedMarks schaltet Umrandung und Hervorhebung ab).

Four reports merged onto one source file: llvm-cov brings lines, functions, regions, branches, MC/DC and instantiations, two TRACE32 exports bring function calls and object code, and a mutation report brings the mutation scoreScreenshot pending — add assets/img/four-reports-one-file.svg (see SCREENSHOTS.md).

Ein zusammengeführter Lauf kann mehr als die sechs klassischen Metriken enthalten, jede aus dem Bericht, der sie misst: Funktionsaufrufe, Objektcode und einen Mutationsscore neben Zeilen, Funktionen, Regionen, Zweigen, MC/DC und Instanziierungen. Die Coverage-Ansicht zeigt für jede Metrik, die der Lauf enthält, eine Spalte – und keine für eine, die er nicht enthält –, sortiert nach dem Gewicht, das jede Metrik in Ihrer Bewertung hat, die schwerste zuerst, bei jeder Breite – was nicht mehr hineinpasst, wird seitlich gescrollt statt ausgeblendet. Ziehen Sie die Ansicht in das untere Panel, und sie wird zur Tabelle. Die Karten in der Statusleiste, der HTML-Bericht und die CSV- und Markdown-Exporte folgen derselben Regel: Was ein Bericht enthält, wird angezeigt; was er nicht enthält, wird weggelassen und nicht als Null ausgegeben.

The Coverage view in a real window: eight tracefiles from five languages above a tree with MC/DC, Conditions, Branches, Regions and the weighted score in columns beside every file, and a covered C# file open next to itScreenshot pending — add assets/img/coverage-view-editor.png (see SCREENSHOTS.md).
The Coverage view as a wide panel: C, C++, JavaScript, Python and .NET merged into one tree, with MC/DC, branches, regions, functions, lines, instantiations, mutation score, Max CRAP and the weighted score in columns beside every file, and an em dash where a metric does not applyScreenshot pending — add assets/img/coverage-view-columns.png (see SCREENSHOTS.md).
The Coverage view over a workspace of eleven projects: every tracefile listed, the tree collapsed to one row per project with its percentage and bar, scrolled through, expanded, and a file opened from itScreenshot pending — add assets/img/workspace-overview.gif (see SCREENSHOTS.md).
Visual Studio: the Coverage window over a folder of eleven projects — collapsed to one row per project with its bar, then expanded, then a file opened from itScreenshot pending — add assets/img/vs-workspace-overview.gif (see SCREENSHOTS.md).
In Visual Studio: das Coverage-Fenster über einem Ordner mit elf Projekten — eingeklappt auf eine Zeile pro Projekt mit seinem Balken, dann ausgeklappt, dann eine daraus geöffnete Datei.

Aus welchem Bericht eine Datei stammt

Wenn mehrere geladene Berichte dieselbe Datei messen, gewinnt der neueste sie ganz — richtig, wenn der erneute Lauf eines Moduls ersetzt, was ein älterer, breiterer Lauf gesagt hat. Falsch ist es, wenn die Berichte denselben Code absichtlich messen: Dann springt der Editor mit jedem Build zwischen ihnen hin und her, und jeder erzählt nur einen Teil der Geschichte. coverageFile.sources sagt, was stattdessen zu tun ist, je Datei. Drei Situationen verlangen danach:

  • Ein Bericht ist der bessere. Das coverage.json von llvm-cov enthält MC/DC, ein GCC-gcov.info desselben Builds nur Zeilen und Zweige: Wählen Sie coverage.json, und behalten Sie den anderen für die wenigen Dateien, die nur GCC baut.
  • Mehrere Testsuiten eines Builds. Unit-Tests, Integrationstests und Hardware-in-the-Loop schreiben je einen Bericht; jeder für sich lässt Zeilen aus, die die anderen ausgeführt haben. Kombinieren, union: Eine Zeile ist abgedeckt, wo irgendein Bericht sie ausgeführt hat, und die Zählwerte werden addiert.
  • Eine Codebasis, zwei Compiler. Dieselben Quellen, von clang und von GCC gebaut, nehmen unterschiedliche Wege durch toolchain-spezifischen Code — hier ein Intrinsic, dort ein portabler Fallback —, und jeder Bericht sagt, die andere Hälfte sei nie gelaufen. Kombinieren, agree: Eine Zeile ist nur dort abgedeckt, wo jeder Bericht, der sie misst, sie ausgeführt hat, und die Zeilen, in denen sie voneinander abweichen, sind türkis markiert. Das ist die Frage, die ein Cross-Compiler-Abgleich stellt: Was hat jeder Build, den ich ausliefere, tatsächlich ausgeführt?

Die Regeln schreiben Sie selten von Hand. Klicken Sie in der Abdeckungsansicht mit der rechten Maustaste auf eine Datei und wählen Sie Choose Coverage Source... (oder führen Sie Choose Coverage Source for This File... auf der offenen Datei aus): Die Liste zeigt jeden Bericht, der die Datei misst, jeden mit seinen eigenen Zeilen, Zweigen und MC/DC, dann Combine them — agree und Combine them — union; wählen Sie einen aus und geben Sie an, ob er für die Datei, ihren Ordner oder ein Muster gilt. Clear Coverage Source for This File... nimmt die Regel wieder heraus. In den Einstellungen ist jede Regel ein Glob über die Dateien, ein Glob über den Bericht (ein Muster ohne / trifft den Dateinamen des Berichts, {a,b} nennt mehrere) und, zum Kombinieren, "combine": "agree" oder "union". Es entscheidet die erste Regel, deren Dateien passen und deren Bericht die Datei misst; eine Datei, die nur ein Bericht misst, wird ihm nie genommen. Zweige, MC/DC und Regionen einer kombinierten Datei stammen aus dem Bericht, der am meisten davon enthält. coverageFile.mergeStrategy: "order" entscheidet die Dateien, für die keine Regel spricht, nach der Reihenfolge von coverageFile.paths statt nach den Zeiten.

{
  "fuciniCoverage.coverageFile.paths": ["clang.json", "gcc/bits.gcov.json.gz"],
  "fuciniCoverage.coverageFile.sources": [
    { "files": "src/**", "report": "{clang.json,bits.gcov.json.gz}", "combine": "agree" }
  ]
}

Was Sie sehen: Die Zeile der Datei in der Abdeckungsansicht nennt den Bericht, aus dem ihre Zahlen stammen, oder, kombiniert, jeden Bericht und den Modus, mit ≠ n für die strittigen Zeilen. Der Gutter und die Annotated Source markieren diese Zeilen türkis und sagen, welcher Bericht sie wie oft ausgeführt hat. Die Hover-Karte der Statusleiste nennt die Quelle der offenen Datei und, für den ganzen Lauf, die geltenden Regeln und wie über die übrigen Dateien entschieden wurde. samples/c-cross-check aus der Demo ist der Fall mit zwei Compilern, bereit zum Öffnen. Visual Studio kann all das ebenfalls: Choose Coverage Source... auf einer Zeile der Abdeckungsansicht sowie Choose und Clear Coverage Source for This File... unter Tools > Coverage Studio.

Quellen wählen und kombinieren gehört zu den kostenpflichtigen Plänen. In Community gewinnt der neueste Bericht jede Datei, wie ohne Regel, und eine Regel in den Einstellungen wird als ungenutzt gemeldet, statt stillschweigend ignoriert zu werden.

Choose Coverage Source on bits.c: clang.json with lines, branches and MC/DC, bits.gcov.json.gz with lines and branches, and the two ways to combine them
In VS Code: Choose Coverage Source... auf bits.c aus der Abdeckungsansicht — der clang-Bericht, der GCC-Bericht oder beide kombiniert.
Animation in VS Code: bits.c combined by agree with four teal lines, Choose Coverage Source opened from the Coverage view, and the file reloaded combined by union
In VS Code: von agree zu union mit zwei Klicks — die strittigen Zeilen bleiben türkis, die Zahlen ändern sich.
Animation in Visual Studio: bits.c combined by agree, the Coverage window's row menu, Choose Coverage Source and its two dialogs, and the file reloaded combined by union
In Visual Studio: dasselbe über das Zeilenmenü der Abdeckungsansicht — die Berichte, dann wie weit die Regel reicht, dann die neu geladene Datei.
bits.c with the clang and GCC reports combined by agree: the Coverage view row names both reports with four disputed lines, and the builtin and the portable loop are marked in teal
In VS Code: bits.c, clang und GCC kombiniert mit agree — die Zeile zeigt ≠ 4, und die vier Zeilen, die nur ein Build ausgeführt hat, sind türkis.
bits.c with the clang and GCC reports combined by union: every line covered, the four disputed lines still teal, and the status bar naming the union
Dieselbe Datei, kombiniert mit union: Jede Zeile, die einer der beiden Builds ausgeführt hat, ist abgedeckt, also erreicht bits.c 100% seiner Zeilen — und die Zeilen, in denen die Builds voneinander abweichen, bleiben türkis.
The Annotated Source of bits.c, combined by agree: the source line under the title names both reports, and each teal row says how often each report ran it
Die Annotated Source nennt die Kombination unter dem Titel, und jede türkise Zeile, wie oft jeder Bericht sie ausgeführt hat.
The status bar's hover card for bits.c, ending with the coverage source: both reports, combined by agree, disagreeing on four lines
Die Hover-Karte der Datei in der Statusleiste sagt, woher ihre Zahlen stammen; die Karte des Laufs zählt die Dateien, über die jede Regel entschieden hat.
Visual Studio: Choose Coverage Source on bits.c from the Coverage window's row menu — the clang report, the GCC report and the two ways to combine them; behind it the row's agree badge with four disputed lines and the teal lines in the margin
In Visual Studio: Choose Coverage Source... in einer Zeile der Abdeckungsansicht — dieselben Berichte und dieselben zwei Arten, sie zu kombinieren; die Statusleiste nennt die Kombination.

7. Pfad-Remapping

CI-Systeme zeichnen oft absolute Pfade der Build-Maschine auf, die auf Ihrer Arbeitsstation nicht existieren. Schreiben Sie diese mit geordneten Regeln um:

{
  "fuciniCoverage.pathRemap": [
    { "from": "/builds/ci/project", "to": "${workspaceFolder}" },
    { "from": "\\\\", "to": "/" }
  ]
}

Die Regeln werden der Reihe nach angewendet; pro Präfix gewinnt die erste Übereinstimmung. Nutzen Sie dies, um Unterschiede bei Windows-/Unix-Trennzeichen auszugleichen oder einen Containerpfad auf Ihren Checkout abzubilden.

Die Regel müssen Sie nur selten selbst schreiben. Das häufigste „es hat geladen, aber nichts leuchtet auf“ ist eine Tracedatei, deren Pfade aus einem Container oder einem CI-Checkout stammen (/build/src/a.c, /home/runner/work/repo/repo/src/a.c, C:\agent\_work\1\s\src\a.c), während der Arbeitsbereich src/a.c hat. Lässt ein Ladevorgang Dateien unzugeordnet, sucht die Erweiterung die Dateinamen im Arbeitsbereich, leitet die Präfixregel ab, die die meisten davon erklärt, protokolliert sie als [FUCINI_REMAP_002], und das Ladeergebnis bietet Apply Suggested Remap an — ein Klick hängt die Regel an fuciniCoverage.pathRemap an und lädt neu. Suggest Path Remap Rule führt dieselbe Analyse auf Anfrage aus der Palette aus. Ohne den Klick wird nichts geschrieben.

Ein to darf ${workspaceRoot} verwenden, das für den Arbeitsbereichsordner steht, in dem die Tracedatei liegt; in einem Multi-Root-Arbeitsbereich versucht es zuerst diesen Ordner, dann jeden anderen Ordner, in dem sich die Datei findet. Die Regeln selbst werden je Ordner gelesen, sodass jeder Stamm eines Multi-Root-Arbeitsbereichs seine eigenen tragen kann.

8. Coverage im Editor

  • Ränder & Übersichtsleiste — standardmäßig zeigt der eigene Gutter des Editors nur Befunde: MC/DC-Balken, Seit-letztem-Lauf-Dreiecke, Punkte auf bearbeiteten Zeilen. editorGutter.mode fügt Balken nur auf nicht abgedeckten Zeilen oder eine Heatmap der Trefferzahlen hinzu (unten); die farbcodierte Ansicht einer ganzen Datei ist die Annotated Source.
  • Funktions-CodeLens — Coverage-% über jeder Funktion; Klick springt zur ersten nicht abgedeckten Zeile. Umschaltbar über codeLens.enabled.
  • Branch- & MC/DC-Hover — beim Überfahren einer Entscheidungszeile werden Taken/Not-taken-Zahlen je Zweig und eine Vektortabelle je Bedingung angezeigt. Farbige Randleiste aktivierbar über mcdcGutter.enabled.
  • Warnungen für toten Code — Funktionen mit messbaren Zeilen und null Coverage werden im Problems-Panel markiert (deadCode.enabled).
  • Next / Previous Uncovered — zwischen Lücken springen.
  • Statusleiste — ein laufweites $(dashboard) NN%-Element und ein Element je Datei, beide farbcodiert nach dem Gesamtscore; Hover zeigt eine vollständige Metriktabelle.
  • Explorer-Badges — Abdeckungs-Badges je Datei und je Ordner, mit der Aufschlüsselung je Metrik beim Überfahren. Standardmäßig aus: mit explorerBadges.enabled einschalten.
  • Seit dem letzten Lauf – ein rotes Dreieck auf jeder Zeile, die im vorherigen Lauf ausgeführt wurde und in diesem nicht, ein grünes für den umgekehrten Fall, mit Übersichtslineal und Trefferzahlen beim Überfahren.
  • Bearbeitete Puffer – jede Markierung, jeder Hover und jede CodeLens wandert beim Bearbeiten mit dem Text mit und zieht sich von einer umgeschriebenen Zeile zurück, wo ein grauer Punkt sagt, warum.
  • Inline-Trefferzahlen — hitCounts.inline schreibt ×12 hinter jede Zeile, auf der eine Anweisung beginnt, ×0 eingeschlossen: die Zahl, die schon immer beim Überfahren zu sehen war, ohne Überfahren. Toggle Inline Hit Counts schaltet sie um; das Statusleisten-Menü bietet sie als Anzeigen oder Ausblenden an, je nachdem, was gerade zutrifft.
  • Problems-Einträge je Zeile — problems.perLine setzt eine Informations-Diagnose, mit einer Wellenlinie im Editor, auf jeden zusammenhängenden Block von Zeilen, die in einem geöffneten Dokument nie liefen (eine vierzigzeilige tote Funktion ist ein Eintrag, nicht vierzig), und als uncoveredAndPartial auf jede Zeile, deren Zweig nie genommen wurde. Die Einträge folgen ihren Zeilen beim Bearbeiten und verschwinden, wenn das Dokument geschlossen wird; der Eintrag je Datei hinter problems.enabled ist unverändert.
  • Zeilenfärbung — lineHighlight legt eine durchscheinende Färbung hinter die Zeilen selbst, für das, was der Randstreifen markiert (uncovered, oder heatmap auch für die ausgeführten Zeilen). Eine eigene Einstellung, damit der Randstreifen sauber bleiben kann, während die Lücken gefärbt werden, oder umgekehrt.
  • Übersichtslineal — overviewRuler entscheidet über den Streifen in der Bildlaufleiste unabhängig vom Randstreifen: follow (mit den Balken, wie bisher), uncovered (immer, der Randstreifen darf also aus sein, während die Bildlaufleiste die Lücken der Datei weiterhin abbildet) oder off.
  • Welche Tracedatei eine Zeile abgedeckt hat — sind mehrere Berichte zusammengeführt, endet der Hover mit der Trefferzahl mit Abgedeckt von: und jedem Bericht, der diese Zeile abgedeckt hat, samt Suite-Name aus lcovs TN:; ein Klick auf eine Tracedatei-Zeile in der Ansicht Coverage hebt die von ihr beigesteuerten Zeilen in jedem offenen Editor hervor.
Function CodeLens and MC/DC hover tooltipScreenshot pending — add assets/img/codelens-hover.png (see SCREENSHOTS.md).
A function CodeLens on a C# method: 37.14% covered, 13 of 35 lines, branches 10 of 22, complexity 22, CRAP 142.2 — with the uncovered branches of the method marked underneathScreenshot pending — add assets/img/codelens-crap.png (see SCREENSHOTS.md).
Alt+N jumps from one uncovered line to the next, Alt+P goes backScreenshot pending — add assets/img/jump-between-gaps.gif (see SCREENSHOTS.md).
Explorer badges: a coverage percentage on every measured file and folder of all five demo projects, beside a covered C# file with its gutters, hit counts and CodeLensScreenshot pending — add assets/img/explorer-badges.png (see SCREENSHOTS.md).

Editor-Gutter-Modi

editorGutter.mode entscheidet, was der eigene Gutter des Editors über die Coverage zeigt, zusätzlich zu den Befunden, die er immer zeigt. off (der Standard) ist nur diese. uncovered setzt einen Balken auf jede Zeile, die nie lief, und einen bernsteinfarbenen auf jede Zeile mit einem nie genommenen Zweig, und nichts auf abgedeckte Zeilen, sodass eine grüne Wand die drei roten nicht verdeckt. coverage fügt einen grünen Balken auf jeder abgedeckten Zeile hinzu, sodass die ganze Datei rot, bernsteinfarben und grün in den Farben der Farbskala erscheint. heatmap legt stattdessen einen warmen Farbton auf jede ausgeführte Zeile, umso heißer, je öfter sie lief — er zeigt, wie oft eine Zeile lief, nicht, ob sie abgedeckt ist, daher ist eine Datei mit 100% dort gelb bis braun, nie grün. Choose Editor Gutter Mode... wählt einen aus der Palette oder dem Statusleisten-Menü; die Modus-Schaltfläche rechts in der Statusleiste oder Alt+G schaltet mit einem Druck zum nächsten weiter (statusBar.showModeToggle blendet die Schaltfläche aus). Beide schreiben die Einstellung. Das Beispiel schaltet die Balken auf nicht abgedeckten Zeilen und die Inline-Zähler zusammen ein:

{
  "fuciniCoverage.editorGutter.mode": "uncovered",
  "fuciniCoverage.hitCounts.inline": true
}
Uncovered mode: a red bar and wash on lines that never ran, amber on a line with a branch arm never taken, and the execution count written after each lineScreenshot pending — add assets/img/gutters.png (see SCREENSHOTS.md).
The coverage mode in VS Code: green bars on lines that ran in full, amber where a branch arm never did, red where nothing ran; the status bar names lcov.info as the report and the mode button reads Coverage
In VS Code: der Modus coverage — grün, wo eine Zeile vollständig lief, bernsteinfarben, wo ein Zweig nie lief, rot, wo nichts lief. Das Statusleisten-Element der Datei nennt den Bericht, aus dem ihre Zahlen stammen; die Modus-Schaltfläche daneben zeigt Coverage.
Alt+G pressed four times: heatmap, off, uncovered and back to coverage
In VS Code: viermal Alt+G — heatmap, off, uncovered und zurück zu coverage.
Visual Studio: Gutter: Coverage on Quote.cs, green, amber and red bars beside the hit counts
In Visual Studio: Gutter: Coverage (Red, Amber, Green) auf Quote.cs.

Die Heatmap ist relativ zur Datei. Der Farbton einer Zeile vergleicht ihren Zähler mit der heißesten Zeile derselben Datei, auf einer logarithmischen Skala, in fünf Stufen – so sind ein Schleifenrumpf, der tausendmal lief, und eine Funktion, die zweimal lief, beide sichtbar, statt dass das eine das andere überdeckt, und eine Datei, in der alles genau einmal lief, ist gleichmäßig warm statt gleichmäßig blass. In einem dunklen Design reicht die Farbskala von gedämpftem Oliv bis zu kräftigem Orange, in einem hellen Design von blassem Gelb bis Braun: In beiden Fällen bedeutet mehr Farbe mehr Ausführungen, und Rot bleibt den Zeilen vorbehalten, die nie ausgeführt wurden. lineHighlight: "heatmap" legt dieselben Farbtöne als Lasur hinter den Code, und hitCounts.inline schreibt den genauen Zähler hinter die Zeile.

{
  "fuciniCoverage.editorGutter.mode": "heatmap",
  "fuciniCoverage.lineHighlight": "heatmap",
  "fuciniCoverage.hitCounts.inline": true
}
The heatmap on a dark theme: functions that ran once in dim olive, the decision that ran five times in vivid orange, lines that never ran in redScreenshot pending — add assets/img/heatmap-dark.png (see SCREENSHOTS.md).
The same file on a light theme: pale yellow for lines that ran once, brown for the hottestScreenshot pending — add assets/img/heatmap-light.png (see SCREENSHOTS.md).
Switching from uncovered mode to the heatmap, on a dark and then on a light themeScreenshot pending — add assets/img/heatmap.gif (see SCREENSHOTS.md).

Die Farben bestimmen Sie. colorScale.lowColor, midColor und highColor geben das Rot, Bernstein und Grün des Gutters, der Färbungen und jeder Prozentzahl vor; heatmap.colors und heatmap.colorsDark enthalten die fünf Farbtöne der Heatmap für ein helles und ein dunkles Design, von der Zeile, die am seltensten lief, bis zu der, die am häufigsten lief. Die Einstellungsseite zeigt das Ergebnis, bevor etwas gespeichert wird: unter Colour scale bleibt eine Vorschau sichtbar, während die Zeilen vorbeiscrollen — der Verlauf mit seinen zwei Stützpunkten, einige Prozentzahlen in ihren Farben und ein kleiner heller und ein kleiner dunkler Editor, gefärbt im Modus coverage und in der Heatmap —, und sie wird neu gezeichnet, sobald eine Farbe gewählt wird.

{
  "fuciniCoverage.heatmap.colors": ["#e3f2fd", "#90caf9", "#42a5f5", "#1e88e5", "#0d47a1"]
}
The settings page in VS Code: two colours typed in, the pinned colour preview repainting each time
In VS Code: zwei Farben in die Einstellungsseite eingetippt — die Vorschau wird jedes Mal neu gezeichnet.
Visual Studio: the same settings page and the same colour preview
In Visual Studio: dieselbe Seite, dieselbe Vorschau.

Der Teil einer Zeile, der nie ausgeführt wurde

Eine Zeile ist abgedeckt oder sie ist es nicht – und die Wahrheit liegt oft dazwischen: return x > hi ? hi : x; wurde ausgeführt, ihr hi-Arm jedoch nie. Ist lineHighlight eingeschaltet, wird der nie ausgeführte Teil einer ausgeführten Zeile im Editor eingefärbt, und zwar für jedes Format, das Spaltenbereiche enthält (llvm-cov, Istanbul, Go, dotnet-coverage) – dieselben Abschnitte, die auch der annotierte Quelltext markiert. Nur in Zeilen, die ausgeführt wurden: Eine Zeile, die nie ausgeführt wurde, ist bereits als Ganzes markiert. Ein C++-Template gilt dort als ausgeführt, wo irgendeine Instanziierung es ausgeführt hat; was jede einzelne Instanziierung getan hat, zeigt die Instanziierungsmetrik.

An executed line whose opening brace is tinted: the if ran, the block it opens never didScreenshot pending — add assets/img/partial-line.png (see SCREENSHOTS.md).

Welche Tests diese Zeile ausgeführt haben

Manche Berichte sagen nicht nur, dass eine Zeile ausgeführt wurde, sondern auch, welche Tests sie ausgeführt haben: coverage.py, geschrieben mit coverage json --show-contexts und dynamic_context = test_function in .coveragerc, OpenCover, erfasst mit -coverbytest, und eine lcov-Tracefile, geschrieben mit einem Abschnitt je Test (TN:), deren Abschnitte zu einem Datensatz mit einem Test je Zeile addiert werden. Zeigen Sie mit der Maus auf den Zeilenanfang, wo der Trefferzähler steht, und die Tests werden genannt — gekürzt auf Klasse und Methode, die ersten fünf namentlich, der Rest als Anzahl; die CodeLens der Funktion sagt, wie viele Tests sie ausgeführt haben. Show Tests That Ran This Line — die Befehlspalette, das Kontextmenü des Editors, in Visual Studio Tools → Coverage Studio oder Ctrl+Shift+U, T — listet sie auf, die fleißigsten zuerst, und öffnet den gewählten dort, wo er im Arbeitsbereich geschrieben steht. Ein dotnet test-Lauf kann nicht sagen, welcher Test was ausgeführt hat; setzen Sie testRun.perTest, und Run Tests with Coverage listet die Testklassen auf und führt sie eine nach der anderen aus, jeden Bericht mit seiner Klasse versehen, sodass der Hover, die Lens und der Befehl auch für .NET antworten können. Die Information wird pro Datei gehalten und übersteht daher das Zusammenführen mit einem Bericht, der nichts über Tests weiß.

{
  "fuciniCoverage.testRun.perTest": true
}
# .coveragerc
[run]
dynamic_context = test_function

coverage run -m pytest && coverage json --show-contexts
Hovering the start of two lines of a Python file: each names the tests that ran it; an uncovered line names noneScreenshot pending — add assets/img/tests-per-line.gif (see SCREENSHOTS.md).
Show Tests That Ran This Line: the caret on a line, the list of tests that ran it busiest first, and the picked test opened where it is writtenScreenshot pending — add assets/img/tests-for-line.gif (see SCREENSHOTS.md).
Show Tests That Ran This Line: die Liste, die fleißigsten zuerst, und der Test geöffnet, wo er geschrieben steht.
Visual Studio: the caret on line 62 of Quote.cs, Show Tests That Ran This Line, the dialog listing Tests.QuoteTests, and Go to Test opening QuoteTests.cs
In Visual Studio: Show Tests That Ran This Line auf Zeile 62 von Quote.cs — der Test, der sie ausführte, und Go to Test, das ihn öffnet.

Bestanden oder fehlgeschlagen, an den Markierungen

Eine abgedeckte Zeile sieht gleich aus, ob ihr Test bestanden hat oder nicht. Wo der Bericht sagt, welche Tests eine Zeile ausgeführt haben, und die Ergebnisdatei des Runners sagt, wie sie ausgegangen sind, erhält eine Zeile, die ein fehlgeschlagener Test ausgeführt hat, einen roten Balken an ihrem Anfang und einen Streifen im Übersichtslineal; ihr Hover nennt die fehlgeschlagenen Tests, und Show Tests That Ran This Line schreibt failed neben jeden. Ist ein Test rot, sieht man in dem Code nach, durch den er gelaufen ist. Die Ergebnisse werden bei jedem Laden aus dem Ordner jedes Berichts gelesen — jede .trx und die Namen, unter denen JUnit-Ergebnisse geschrieben werden (TEST-*.xml, junit*.xml, test-results*.xml) — und aus testResults.paths, als Pfade oder Globs relativ zum Ordner. Run Tests with Coverage verlangt von dotnet test eine test-results.trx neben dem Bericht, sodass bei eingeschaltetem testRun.perTest nichts einzurichten ist. testResults.enabled schaltet das Lesen ab.

{
  "fuciniCoverage.testResults.paths": ["build/test-results/**/*.xml", "reports/junit.xml"]
  }
A failing test: a red bar on the lines it ran, the hover naming it under Failing tests that ran this line, and Show Tests That Ran This Line writing failed beside itScreenshot pending — add assets/img/pass-fail.gif (see SCREENSHOTS.md).
Visual Studio: a failing test — the red bar on the lines it ran, the hover naming it, and Show Tests That Ran This Line writing failed beside itScreenshot pending — add assets/img/vs-pass-fail.gif (see SCREENSHOTS.md).
In Visual Studio: ein roter Test — der rote Balken auf den Zeilen, die er ausführte, der Hover, der ihn nennt, und Show Tests That Ran This Line, das failed daneben schreibt.

Die Tests, die von einer Änderung betroffen sind

Ein vollständiger Lauf beantwortet langsam, was Run Tests Affected by My Changes… sofort beantwortet: Welche von allen Tests sind durch den Code gelaufen, den ich gerade bearbeitet habe? git wird nach dem Diff des Arbeitsverzeichnisses gegen testImpact.baseRef gefragt — standardmäßig HEAD, also das, was noch nicht committet ist; origin/main für alles, was der Branch ändert —, und die Tests, die eine geänderte Zeile ausgeführt haben, werden aufgelistet, zuerst der, der am meisten von der Änderung ausgeführt hat. Die Wahl eines Tests öffnet ihn. Wo die Berichte aus einem Lauf je Test stammen (testRun.perTest), führt der erste Eintrag nur diese Tests aus, jede Klasse in ihren eigenen Bericht, sodass die Berichte aller anderen Klassen bestehen bleiben und die Summen die der ganzen Suite bleiben. Ein Test, der nur Zeilen unterhalb einer Einfügung oder Entfernung ausgeführt hat, wird ebenfalls aufgelistet: Sein Bericht würde sonst die falschen Zeilen nennen.

An uncommitted edit, Run Tests Affected by My Changes…, the list with the test that ran most of the change first, and the run of only those testsScreenshot pending — add assets/img/test-impact.gif (see SCREENSHOTS.md).
Visual Studio: an edit, Run Tests Affected by My Changes…, the list with the test that ran most of the change first, and the run of only thoseScreenshot pending — add assets/img/vs-test-impact.gif (see SCREENSHOTS.md).
In Visual Studio: eine Änderung, Run Tests Affected by My Changes…, die Liste mit dem Test zuerst, der den größten Teil der Änderung ausführte, und der Lauf nur dieser Tests.

Die wenigsten Tests, die noch jede Zeile ausführen

Show Minimal Test Set… beantwortet zwei Fragen aus denselben Zeilen je Test: welche wenigen Tests noch jede Zeile ausführen würden, die die Suite ausführt — für den schnellen Lauf vor einem Commit —, und welche Tests keine Zeile ausführen, die nicht schon ein anderer ausführt. Die ausgewählten Tests stehen zuerst, jeder mit den Zeilen, die er hinzufügt, und den Zeilen, die nur er ausführt; dann der Rest, jeder mit dem Vermerk, dass er nichts hinzufügt. Gewählt wird nach dem Greedy-Verfahren — der Test, der am meisten ausführt, dann der, der dazu am meisten hinzufügt —, die Auswahl liegt also nahe an der kleinsten Menge und ist jedes Mal dieselbe. Redundant nach Zeilen heißt nicht redundant nach dem, was ein Test prüft: Ein Test, der keine Zeile hinzufügt, kann trotzdem der einzige sein, der einen Wert prüft, den diese Zeilen liefern. Die Liste sagt, wo man hinsieht, wenn eine Suite ausgedünnt wird, nie, was zu löschen ist.

Show Minimal Test Set…: the chosen tests first, then the tests that add nothingScreenshot pending — add assets/img/minimal-test-set.png (see SCREENSHOTS.md).
Visual Studio: Show Minimal Test Set… — the chosen tests, then the tests that add nothingScreenshot pending — add assets/img/vs-minimal-test-set.png (see SCREENSHOTS.md).
In Visual Studio: Show Minimal Test Set… — die gewählten Tests, dann die Tests, die nichts hinzufügen.

Diesen Test ausführen, mit Coverage

Setzen Sie den Cursor in einen Test und führen Sie Run This Test with Coverage aus — die Befehlspalette, das Kontextmenü des Editors, in Visual Studio Tools → Coverage Studio oder Ctrl+Shift+U, R —, und dieser Test allein läuft mit eingeschalteter Coverage: die Testmethode, in der der Cursor steht, oder die Testklasse bzw. der describe-Block, wenn er zwischen Methoden steht, oder die Datei, wenn er über jeder Klasse steht. Was unter dem Cursor liegt, wird aus dem Text gelesen, daher funktioniert es für C#, VB und F# ([Fact], [Test], [TestMethod] und dergleichen), JavaScript und TypeScript (it, test, describe) und Python (def test_…), welcher Sprachdienst auch immer installiert ist. Das Rezept des Ordners wird darauf eingeengt — dotnet test --filter "FullyQualifiedName~…", jest oder vitest <file> -t "…", eine pytest-Node-ID —, und was es geschrieben hat, wird geladen wie jeder Lauf; ein Runner, der sich nicht einengen lässt, sagt es, und Run Tests with Coverage führt sie alle aus.

Run This Test with Coverage: the caret in a Fact, the one dotnet test --filter run in the terminal, the gutter of the class under test filling inScreenshot pending — add assets/img/run-this-test.gif (see SCREENSHOTS.md).
Run This Test with Coverage: ein Test, ein Lauf, die getestete Klasse leuchtet auf.
Visual Studio: the caret in the Fact AGoldCustomerGetsTenPercent, Run This Test with Coverage, the run appearing in the Tracefiles list and the lenses saying run by 1 test(s)
In Visual Studio: Run This Test with Coverage in einem [Fact] — der Lauf in der Liste Tracefiles, die Zeilen über den Methoden sagen, dass ein Test den Code ausführte.

Go und Rust. In einer Go-Datei läuft das func TestXxx unter dem Cursor (oder Fuzz…, Example…) für sich allein, in seinem eigenen Paket und unter seinem genauen Namen — go test ./pkg/calc -run "^TestTotal$" —, und außerhalb eines Tests läuft das Paket der Datei. In einer Rust-Datei läuft die #[test]-Funktion unter ihrem Pfad im Crate mit --exact; steht der Cursor in einem mod und in keinem Test, laufen die Tests dieses Moduls; ein Integrationstest unter tests/ läuft in seinem eigenen Binary (--test api). Ein Runner bekommt nur Dateien seiner eigenen Sprache: Eine TypeScript-Datei in einem Go-Ordner bekommt einen Satz, keinen leeren Lauf.

Coverage nach jedem Speichern

Mit eingeschaltetem testRun.onSave führt das Speichern einer Quelldatei kurz danach die Tests aus, die sie abdecken, mit Coverage, und die Randleiste folgt. Bei einer .NET-Projektmappe wird das Projekt der gespeicherten Datei über den .csproj-Graphen gefunden, und nur die Testprojekte, die darauf verweisen — direkt oder über andere Projekte —, werden ausgeführt, je ein dotnet test <project>; jeder andere Runner führt sein ganzes Rezept aus; eine Datei, die kein Projekt besitzt und kein Bericht misst, führt nichts aus. Mehrere Speichervorgänge nacheinander sind ein Lauf, und ein laufender Lauf wird nicht unterbrochen. Der Rest ist, wie Run Tests with Coverage es macht: das Terminal, der Output-Bereich, der geladene Bericht. Standardmäßig aus — es ist eine Gewohnheit, die man wählt, kein Standard, den man entdeckt.

{
  "fuciniCoverage.testRun.onSave": true
}
Coverage after every save: an edit to a C# file, Ctrl+S, the covering test project runs by itself, and the gutter changesScreenshot pending — add assets/img/coverage-on-save.gif (see SCREENSHOTS.md).
Coverage nach jedem Speichern: bearbeiten, speichern, und kurz darauf folgt die Randleiste.
Visual Studio: with testRun.onSave on, a comment line added to Quote.cs and saved, the tests running by themselves and the lens above Price changing
In Visual Studio: testRun.onSave an — Quote.cs gespeichert, die Tests laufen von selbst, die Zeile über der Methode ändert sich.

Die App selbst, mit Coverage

Ein Testlauf sagt, was die Tests erreichen. Was ein Mensch erreicht — der sich vor einem Release durch die Bildschirme klickt oder die Schritte eines Kunden nachspielt —, ist ebenfalls Coverage, und Run App with Coverage… erfasst sie. Die .NET-App des Ordners — eine Exe, eine WinExe, ein Web- oder Worker-Projekt, nie ein Testprojekt; eine Auswahl, wo es mehrere gibt — wird unter Microsofts dotnet-coverage in einer eigenen Konsole gestartet, damit sich in eine Konsolen-App tippen lässt, und läuft, bis Sie sie schließen. Was Sie durchlaufen haben, wird dann geladen wie jeder Lauf, und in einer Coverage-Sitzung wird es zu dem addiert, was die Tests ausgeführt haben. Wie die App geendet hat, wird dem Lauf nicht angelastet. Das Werkzeug muss einmal installiert werden: dotnet tool install --global dotnet-coverage.

Run App with Coverage…: the console app started under dotnet-coverage, a few inputs, closed, and its coverage loadedScreenshot pending — add assets/img/run-app.gif (see SCREENSHOTS.md).
Visual Studio: Run App with Coverage… — the console app, a few inputs, closed, and its coverage loadedScreenshot pending — add assets/img/vs-run-app.gif (see SCREENSHOTS.md).
In Visual Studio: Run App with Coverage… — die Konsolenanwendung, ein paar Eingaben, geschlossen, und ihre Abdeckung geladen.

Mutanten – und wo sie sitzen

Ein Mutationswerkzeug – PIT für Java, Stryker für JavaScript, C# und Scala, Mull für C und C++ – verändert Ihren Code in kleinen Schritten und lässt die Tests gegen jede Änderung laufen. Eine Änderung, die kein Test bemerkt, ist ein überlebender Mutant: Der Code wurde ausgeführt, und nichts hat geprüft, was er getan hat. Der Mutationsscore sagt, wie viele entdeckt wurden; seit 0.2026.83 sagt der Editor, wo die übrigen sitzen. Eine Zeile mit einem Mutanten trägt einen Hinweis am Zeilenende (⚑ 2 mutants survived), der geänderte Text ist unterstrichen, sofern der Bericht angibt, welcher Text es war (Stryker und Mull tun das), das Übersichtslineal erhält einen Streifen, und der Hover zeigt, was geändert wurde, wie viele Tests die Stelle ausgeführt haben und – bei den entdeckten Mutanten – welcher Test sie entdeckt hat.

A surviving mutant in the editor: the note after the line, the underlined text, and the hover naming the change — ConditionalBoundary: value <= loScreenshot pending — add assets/img/mutant-hover.png (see SCREENSHOTS.md).

Überlebt bedeutet: Tests haben den geänderten Code ausgeführt und alle bestanden. Ungetestet (im Bericht no coverage) bedeutet, dass überhaupt kein Test diesen Code ausführt – es konnte also nichts auffallen. Entdeckte Mutanten werden im Hover gezählt und nie markiert, und Mutanten, die nie ein fairer Test waren – etwa einer, der nicht kompilieren würde –, bleiben außerhalb des Scores. Der annotierte Quelltext hat unter jeder solchen Zeile eine eigene Zeile und eine Schaltfläche Next Mutant (U), und die HTML-Berichte haben einen Abschnitt Surviving Mutants, der zur Zeile verlinkt. Es muss nichts eingeschaltet werden, und ein Projekt ohne Mutationsbericht sieht nichts davon.

Surviving mutants marked in the editor, the hover naming the change, and the annotated source jumping from one to the next with UScreenshot pending — add assets/img/mutants.gif (see SCREENSHOTS.md).

Würde ein Test es bemerken? Ein Mutationslauf am Cursor

Der Mutationslauf eines Projekts dauert eine Stunde; der einer einzelnen Funktion eine Minute. Run Mutation Tests Here führt diese Minute aus: Die Funktion, in der der Cursor steht — oder die markierten Zeilen, oder die Datei —, ist das, was der Mutations-Runner des Ordners mutieren soll, und sein Bericht wird neben der Coverage auf dem Bildschirm geladen, wo die überlebenden Mutanten markiert werden. Für C# ist es Stryker.NET (dotnet tool install --global dotnet-stryker), dem der Zeichenbereich und das Testprojekt genannt werden, das auf das Projekt der Datei verweist; für JavaScript und TypeScript StrykerJS, dem die Zeilen genannt werden; für Java PIT mit Maven, dem die Klasse genannt wird. Wie der Runner geendet hat, wird dem Lauf nicht angelastet: Ein Score unter seinem Schwellenwert ist ein Exit-Code und trotzdem ein Bericht. Hat ein Runner nichts geschrieben, wird das gesagt, zusammen mit dem, was er installiert braucht.

Run Mutation Tests Here on one function: Stryker.NET runs that minute, and the surviving mutants are marked in the editorScreenshot pending — add assets/img/mutation-here.gif (see SCREENSHOTS.md).
Visual Studio: Run Mutation Tests Here on one function, and the surviving mutants markedScreenshot pending — add assets/img/vs-mutation-here.gif (see SCREENSHOTS.md).
In Visual Studio: Run Mutation Tests Here auf einer einzelnen Funktion, und die überlebenden Mutanten markiert.

VS Codes eigene Test-Coverage-Ansicht

Mit eingeschaltetem testCoverage.publish (dem Standard) geht jeder geladene Lauf auch in die native Test-Coverage-Ansicht des Editors — das Coverage-Panel des Test Explorers, die Prozentzahlen je Datei, die er in den Explorer setzt, und den editoreigenen Schalter Show Inline Coverage — als Zeilen, Zweige und Funktionen, mit bei Bedarf geladenen Details, aus welcher Tracedatei auch immer sie stammen und ohne beteiligten Test-Adapter. Show in Test Coverage View veröffentlicht den aktiven Lauf und öffnet das Panel, was auch immer die Einstellung sagt; das Statusleisten-Menü bietet es hinter quickActions.showTestCoverage an. Ausgeschaltet erscheint überhaupt kein Eintrag Fucini Coverage im Test Explorer. Nennt eine Tracedatei ihre Tests (die TN:-Abschnitte von lcov), erscheint jeder Test unter Fucini Coverage im Test Explorer, und die Ansicht kann die Abdeckung einer Datei nach Test filtern.

VS Code's own Test Coverage view filled from the loaded reports, one bar each for statements, branches and functionsScreenshot pending — add assets/img/test-coverage-view.png (see SCREENSHOTS.md).

Nicht abgedeckte Zeilen im Problems-Panel

Standardmäßig aus, weil es seiner Natur nach laut ist, und immer nur für die geöffneten Dokumente — ein Lauf mit zweitausend Dateien kann das Panel nicht fluten. Unabhängig von problems.enabled, das bei einem Eintrag je Datei bleibt:

{
  "fuciniCoverage.problems.perLine": "uncoveredAndPartial"
}
The Problems panel: one entry per file below the statement threshold, and a possible-dead-code entry for every function that never ranScreenshot pending — add assets/img/problems-panel.png (see SCREENSHOTS.md).

9. Diff-Coverage

Beschränken Sie Dekorationen auf Zeilen, die sich gegenüber einer git-Basisreferenz geändert haben — ideal, um genau zu prüfen, was ein PR abgedeckt hat und was nicht:

{
  "fuciniCoverage.gitDiff.enabled": true,
  "fuciniCoverage.gitDiff.baseRef": "origin/main"
}
Diff coverage: only the five lines changed against the base ref are marked and judged — 5 of 5 lines, 7 of 8 branchesScreenshot pending — add assets/img/diff-coverage.png (see SCREENSHOTS.md).

In Visual Studio. Dieselben zwei Einstellungen, aus denselben Dateien gelesen: Die Erweiterung führt git diff <baseRef> für jede Datei des Laufs selbst aus und schneidet den Lauf auf die Zeilen zu, die Ihr Branch geändert hat — in der Randleiste, im Coverage-Fenster und in den Gates. Der Output-Bereich sagt, was git geantwortet hat, wenn es nichts antwortet.

Ein Gate für neuen Code

threshold.newCode ist ein eigenes Gate neben denen für den ganzen Lauf: der Mindestanteil der messbaren, gegenüber gitDiff.baseRef geänderten Zeilen, der gelaufen sein muss. Ein Projekt mit insgesamt 62% kann trotzdem verlangen, dass getestet ist, was heute geschrieben wird. Gezählt wird bei jedem Laden am ganzen Lauf, der auf dem Bildschirm bleibt — gitDiff.enabled ist das andere: die geänderten Zeilen anstelle des Laufs. Check Coverage Thresholds und die Compliance-Einträge im Problems-Panel melden sein Scheitern in einem eigenen Satz: New code 72.00% < 80% (18 of 25 line(s) changed against origin/main ran). Eine Änderung ohne messbare Zeile — Kommentare, ein README — lässt nichts scheitern.

{
  "fuciniCoverage.threshold.newCode": 80,
  "fuciniCoverage.gitDiff.baseRef": "origin/main"
  }
Check Coverage Thresholds failing New code 72.00% < 80% beside a run that passes its own gatesScreenshot pending — add assets/img/new-code-gate.png (see SCREENSHOTS.md).
Visual Studio: Check Coverage Thresholds failing the new-code gate in the Error List, beside a run that passes its own gatesScreenshot pending — add assets/img/vs-new-code-gate.png (see SCREENSHOTS.md).
In Visual Studio: Check Coverage Thresholds lässt das Gate für neuen Code durchfallen, neben einem Lauf, der seine eigenen Gates besteht.

Neuer Code nach Git-Tag, nach Autor, nach Datum

Neuer Code sind standardmäßig die Zeilen, die das Arbeitsverzeichnis gegenüber gitDiff.baseRef ändert — einem Branch, einem Commit oder einem Tag: "v1.4.0" ist alles seit diesem Release. Zwei Einstellungen fragen, was eine Ref nicht kann. gitDiff.author nimmt einen Teil eines Autorennamens, und neuer Code sind dann die Zeilen, die git diesem Autor zuschreibt; gitDiff.since nimmt ein Datum, und es sind die Zeilen, die an diesem Datum oder später zuletzt geändert wurden, über welchen Branch auch immer sie hereinkamen; beide zusammen: die Zeilen dieses Autors seit diesem Datum. Sie werden aus git blame gelesen, Datei für Datei — was ein großer Lauf bei jedem Laden spürt —, und treten für die Diff-Coverage und das Gate oben an die Stelle des Diffs. Eine noch nicht committete Zeile zählt in jedem Fall.

{
  "fuciniCoverage.gitDiff.author": "Ada",
  "fuciniCoverage.gitDiff.since": "2026-09-01"
  }
The same gate scoped by author and date: new code by Ada since 2026-09-01Screenshot pending — add assets/img/new-code-author.png (see SCREENSHOTS.md).

Indirekte Änderungen: was sich bewegt hat, obwohl es niemand angefasst hat

Ein Diff sagt, welche Zeilen sich geändert haben; zwei Läufe sagen, welche Zeilen nicht mehr oder neuerdings laufen. Einen Blick wert sind die Zeilen, bei denen beide nicht übereinstimmen: Code, den niemand bearbeitet hat und der nicht mehr läuft, weil ein Test gelöscht wurde, ein vorgelagerter Zweig jetzt früh zurückkehrt, eine Fixture sich geändert hat. Ein Review des Diffs kann sie nicht sehen — sie liegen per Definition außerhalb. Show Indirect Coverage Changes… listet sie je Datei auf, die Datei, die am meisten verloren hat, zuerst, und öffnet die gewählte an ihrer ersten solchen Zeile. Der Lauf wird gegen die CI-Baseline gehalten, wo baseline.report eine nennt — an ihr wird ein Pull Request gemessen —, und sonst gegen den Lauf davor; die Zeilen, die das Arbeitsverzeichnis gegenüber gitDiff.baseRef ändert, und alles unterhalb einer Stelle, an der diese Änderung die Zeilen der Datei verschiebt, bleiben außen vor.

Show Indirect Coverage Changes…: a file that lost lines nobody edited, after a test was removed between two runsScreenshot pending — add assets/img/indirect-changes.png (see SCREENSHOTS.md).
Visual Studio: Show Indirect Coverage Changes… — a file that lost lines nobody editedScreenshot pending — add assets/img/vs-indirect-changes.png (see SCREENSHOTS.md).
In Visual Studio: Show Indirect Coverage Changes… — eine Datei, die Zeilen verlor, die niemand bearbeitet hat, nachdem zwischen zwei Läufen ein Test entfernt wurde.

10. Der Gesamtscore

Statt sechs Zahlen auszugeben, fasst die Erweiterung sie zu einem gewichteten harmonischen Mittel (WHM) zusammen. Für Metriken mit Prozentwerten pᵢ und Gewichten wᵢ:

WHM = ( Σ wᵢ ) / ( Σ wᵢ / pᵢ )

Ein harmonisches Mittel wird von seinem kleinsten Term dominiert, sodass eine schwache Metrik nicht durch eine perfekte überdeckt werden kann — genau die Eigenschaft, die man von einer Sicherheitsschranke erwartet. Standardgewichte:

MetrikGewichtungBegründung
MC/DC4IEC 61508 SIL 3–4 / ISO 26262 ASIL C–D / DO-178C DAL A–B.
Zweige2IEC 61508 SIL 2+ / ISO 26262 ASIL B+.
Bedingungen3Zwischen Zweigen und MC/DC (DO-178C, ISO 26262).
Regionen1.5Pfade innerhalb einer Anweisung (z. B. teilweise Kurzschlussauswertung).
Zeilen1IEC 61508 SIL 1+ / ISO 26262 ASIL A+.
Funktionen1Prüfung auf toten Code.
Instanziierungen0.5Abdeckung von C++-Templates; engster Geltungsbereich.
Funktionsaufrufe1Aufrufstellen, die ausgeführt wurden (gcov, VectorCAST, Testwell CTC++, TRACE32).
Objektcode0Aus, solange Sie ihm kein Gewicht geben: Er schließt die Anweisungsabdeckung ein.
Mutationsscore0Aus, solange Sie ihm kein Gewicht geben: Er ist keine Abdeckung.

Setzen Sie ein Gewicht auf 0, um diese Metrik aus dem Score auszuschließen. Metriken, die in den Daten nicht vorhanden sind (z. B. MC/DC bei einem reinen lcov-Lauf), werden einfach weggelassen.

Objektcode und der Mutationsscore haben das Gewicht 0, bis Sie etwas anderes festlegen (whmWeights.objectCode, whmWeights.mutation). Die Objektcode-Abdeckung schließt die Anweisungsabdeckung ein; wer beide gewichtet, zählt also denselben Nachweis doppelt. Ein Mutationsscore ist überhaupt keine Abdeckung – eine Testsuite kann jede Zeile ausführen und nichts erkennen. Beide haben dennoch eine eigene Spalte und einen eigenen Schwellenwert.

The default weights of the composite score: MC/DC 4, branches 2, regions 1.5, lines, functions and function calls 1, instantiations 0.5; object code and mutation score 0 until given a weightScreenshot pending — add assets/img/score-weights.svg (see SCREENSHOTS.md).

Bedingungsabdeckung

a && b ist eine Entscheidung – zwei Zweige – und zwei Bedingungen mit vier Ausgängen. Eine Testsuite kann beide Zweige nehmen und b doch nie als falsch sehen: Die Zweigabdeckung ist vollständig, die Bedingungsabdeckung liegt bei drei von vier. Diese Stufe liegt in DO-178C und ISO 26262 zwischen Zweigabdeckung und MC/DC, und seit 0.2026.83 ist sie eine eigene Metrik, statt in den Zweigen aufzugehen: eine Zeile in den Karten der Statusleiste, eine Spalte in der Coverage-Ansicht, in den Berichten und den Exporten, ein Gewicht von 3 im Score (whmWeights.conditions) und eine Schranke (threshold.conditions; im Profil standard ohne Schranke, 100 unter safety).

One decision, a && b, and the same two tests: branches 2 of 2, conditions 3 of 4 because b is never seen false, MC/DC 1 of 2 because b is never shown to matterScreenshot pending — add assets/img/branch-condition-mcdc.svg (see SCREENSHOTS.md).

Gelesen aus den condition-Probes von BullseyeCoverage, einem TRACE32-cond-Export und GCC 14, gebaut mit -fcondition-coverage. Ein Bericht, der Bedingungen nicht von Entscheidungen unterscheidet, hat weder eine solche Zeile noch Spalte noch ein Gewicht. Wenn Sie Bullseye oder TRACE32 verwenden: Bedingungen zählten bisher als Zweige; Ihr Zweigprozentsatz ändert sich daher mit dieser Version und mit dem neuen Gewicht auch Ihr Gesamtscore. Setzen Sie whmWeights.conditions auf 0, um den Score wie bisher zu erhalten.

GCC 14, Zeile für Zeile. -fcondition-coverage lässt gcov sagen, welches Ergebnis welcher Bedingung fehlt — Bedingung 1 nie wahr, Bedingung 0 mit keinem der beiden Ergebnisse —, und jede Bedingung wird auf ihrer Zeile markiert und im Hover genannt, aus gcovs JSON und aus seinem Textlisting (condition outcomes covered 3/6). Die Metrik steht dort, wo die anderen stehen: threshold.conditions ist ihr Gate und bleibt unbewertet, wo ein Lauf keinen solchen Wert hat, Copy Coverage Summary hat eine Spalte Conditions, badge.metric nimmt conditions, und das Suchfeld nimmt conditions < 80. Der Branch-Wert einer Funktion lässt die Ergebnisse ihrer Bedingungen aus, wie der der Datei und der des Laufs.

GCC 14 condition coverage: the mark on the line and the hover naming the outcome never seenScreenshot pending — add assets/img/gcc-conditions.png (see SCREENSHOTS.md).

Komplexität und CRAP

Manche Berichte enthalten die zyklomatische Komplexität jeder Funktion: OpenCover (das Format, das Coverlet schreibt), JaCoCo, Clover und Cobertura. Wo das der Fall ist, berechnet die Erweiterung für die Funktion einen CRAP-Score – Change Risk Anti-Patterns – aus dieser Komplexität und aus der Abdeckung, die sie selbst gemessen hat:

CRAP = complexity² × (1 − coverage)³ + complexity

Eine einfache, vollständig getestete Funktion erhält als Score ihre eigene Komplexität und nicht mehr; eine komplexe, kaum getestete landet im dreistelligen Bereich. Im C#-Beispiel des Demoprojekts hat Price() die Komplexität 22 und etwa 37 % abgedeckte Zeilen, was 142,2 ergibt, während Shipping() die Komplexität 12 hat und vollständig abgedeckt ist, was 12 ergibt. Die übliche Grenze ist 30: Eine Funktion, die sie erreicht oder überschreitet, wird im HTML-Bericht unter Riskiest Methods aufgeführt, die schlechteste zuerst.

CRAP against line coverage for two methods: Price() with complexity 22 sits at 142.2 and needs about 75% coverage to get under 30; Shipping() with complexity 12 is fully covered and scores 12Screenshot pending — add assets/img/crap-curve.svg (see SCREENSHOTS.md).

Die Komplexität und der Score stehen im CodeLens der Funktion und neben der Funktion im annotierten Quelltext. Max CRAP ist der höchste Score aller Funktionen einer Datei – der schlechteste, kein Durchschnitt – und ist eine Spalte in der Coverage-Ansicht, im HTML-Bericht und in den CSV- und Markdown-Exporten. Er dient der Information: Er hat keinen Schwellenwert und kein Gewicht im Gesamtscore. Berichte, die keine Komplexität enthalten (lcov, gcov, Istanbul, coverage.py), haben keinen CRAP-Score und auch keine leere Spalte.

Seit 0.2026.83 gibt es ihn auch für C und C++. llvm-cov meldet keine Komplexität, daher wird sie aus den Zweigdaten gezählt, die der Bericht ohnehin enthält: die Bedingungen, die in der eigenen Datei der Funktion geschrieben stehen, plus eins – McCabes Definition, und das, was die Werkzeuge auf Quelltextebene für .NET und Java zählen. Bedingungen, die aus einem Makro einer anderen Datei stammen – jedes assert zum Beispiel –, werden nicht mitgezählt.

The Riskiest Methods section of the HTML report: Price() with complexity 22, 37.14% of its lines covered, CRAP 142.2Screenshot pending — add assets/img/riskiest-methods.png (see SCREENSHOTS.md).

Risk hotspots, und welche Dateien gezeigt werden

Unter dem Baum der Coverage-Ansicht listet Risk hotspots die Funktionen, in denen komplexer Code auf wenig Coverage trifft, die schlimmste zuerst, und jede öffnet ihre Datei an der Funktion. Eine Funktion qualifiziert sich über den CRAP-Score — hotspots.crapThreshold, standardmäßig 30, der Wert, den die Autoren der Metrik vorgeschlagen haben — oder allein über die zyklomatische Komplexität, hotspots.complexityThreshold, standardmäßig aus; nur Berichte, die Komplexität enthalten (OpenCover, Cobertura aus Coverlet, JaCoCo, llvm-cov), haben welche. Community sieht die Anzahl und den schlechtesten Score; die Rangliste ist Pro. Neben der Sortierung sagt ein zweites Dropdown, welche Dateien der Baum zeigt — alle, Dateien mit Lücken, ungetestete Dateien oder die seit dem letzten Lauf geänderten Dateien; Ordner folgen ihren Dateien und behalten ihre eigenen Zahlen. Beides gibt es auch in Visual Studio, im Coverage-Fenster.

Visual Studio: the Coverage window with the filter beside the sort and the risk hotspots under the treeScreenshot pending — add assets/img/vs-hotspots.png (see SCREENSHOTS.md).
In Visual Studio: das Coverage-Fenster, mit dem Filter neben der Sortierung und den Risk hotspots unter dem Baum.

Namespaces, Klassen und Methoden

Für einen .NET-Bericht, der seine Klassen nennt — Cobertura und Coverlets coverage.cobertura.xml, OpenCover —, zeichnet ein drittes Dropdown, Folders / Namespaces, denselben Lauf als Namespaces, Klassen und Methoden: Die Zahl eines Namespace ist die Summe seiner Klassen, die einer Klasse die ihrer Methoden, genau wie die eines Ordners die seiner Dateien ist, mit derselben Sortierung und demselben Filter. Eine Methodenzeile öffnet die Datei an der Methode; eine in keinem Namespace deklarierte Klasse steht unter (no namespace). Die Wahl wird nach coverageView.perspective geschrieben; ein Lauf, der keine Klassennamen trägt, hat kein Dropdown und zeigt seine Ordner. In Visual Studio hat das Coverage-Fenster dasselbe Dropdown.

The Coverage view drawn as namespaces, classes and methods, the dropdown on Namespaces, a method row about to open its fileScreenshot pending — add assets/img/namespace-perspective.png (see SCREENSHOTS.md).
Derselbe Lauf nach Namespace, Klasse und Methode.
Visual Studio: the Coverage window with the dropdown on Namespaces, the Pricing namespace open on Customer and its methods
In Visual Studio: das Coverage-Fenster nach Namespace, Klasse und Methode.

Unter den Schaltflächen und Dropdowns ein Suchfeld. Ein Wort behält die Zeilen, deren Name oder Pfad es enthält — jedes getippte Wort muss vorkommen; ein Vergleich behält die Zeilen, deren Zahl ihn besteht — < 80% auf den Wert, lines >= 90, branches = 0, functions != 100, mcdc < 50 —, und invoice < 80 verlangt beides. Methodenzeilen der Namespace-Perspektive und die Risk hotspots werden mit den Dateien durchsucht, sodass eine Funktion dort gefunden wird, wo der Lauf sie hat. Der Baum wird beim Tippen gefiltert, in der Seite, ohne Neuzeichnen; ein Ordner mit einem Treffer öffnet sich dafür und schließt sich wieder, wenn das Feld leer wird; Esc leert es. Dasselbe Feld, dieselbe Grammatik, in Visual Studio.

Typing lines < 80 into the Coverage view's search box: the tree keeps only the files under eighty percent, folders opening to show themScreenshot pending — add assets/img/tree-search.gif (see SCREENSHOTS.md).
Den Baum durchsuchen: ein Name, dann lines < 80.

Der Baum folgt dem Editor

Die Datei, die Sie gerade ansehen, ist in der Coverage-Ansicht hervorgehoben, die Ordner darüber werden aufgeklappt, und ihre Zeile wird in den sichtbaren Bereich gescrollt — der Baum muss nicht mehr nach der Datei durchsucht werden, die schon geöffnet ist. Ansonsten behält der Baum seine Scrollposition, und nichts wird neu gezeichnet. coverageView.followActiveEditor, standardmäßig eingeschaltet, schaltet es für alle ab, die den Baum lieber dort lassen, wo sie ihn hingestellt haben.

Switching editor tabs: the Coverage view's highlighted row follows, the folders above it openedScreenshot pending — add assets/img/follow-editor.gif (see SCREENSHOTS.md).
Visual Studio: switching documents, and the Coverage window's highlighted row followingScreenshot pending — add assets/img/vs-follow-editor.gif (see SCREENSHOTS.md).
In Visual Studio: der Wechsel zwischen Dokumenten, und die hervorgehobene Zeile im Coverage-Fenster folgt mit.

11. Compliance-Prüfung

Das COMPLIANT-/NON-COMPLIANT-Urteil (angezeigt in der annotierten Quellansicht, im HTML-Bericht und in beiden Statusleisten-Hovers) wird durch metrikspezifische Schwellenwerte und einen Modus bestimmt:

The status-bar hover card: NON-COMPLIANT, 3 of 5 gates below threshold — functions and regions pass, lines and branches miss narrowly (amber), MC/DC misses outright (red)Screenshot pending — add assets/img/statusbar.png (see SCREENSHOTS.md).
ModusCOMPLIANT, wenn …
strict (default)jede einzeln geprüfte Metrik erreicht ihren eigenen Schwellenwert — keine Kompromisse.
whmder einzelne gewichtete Gesamtscore erreicht threshold.weighted.
bothsowohl die gewichtete Prüfung ALS AUCH die strenge Prüfung je Metrik sind erfüllt.
eitherdie gewichtete Prüfung ODER die strenge Prüfung je Metrik ist erfüllt (am lockersten).

Ein Schwellenwert von 0 schaltet diese Schranke aus, und eine Metrik, die der Bericht nicht enthält, wird nie beurteilt. Wofür ein Schwellenwert steht, den Sie nicht gesetzt haben, entscheidet das Profil weiter unten. Führen Sie Fucini Coverage: Check Coverage Thresholds aus, um bei Bedarf zu prüfen.

In Visual Studio. Tools → Coverage Studio → Check Coverage Thresholds beurteilt den Lauf anhand derselben threshold.*-Schlüssel und sagt es in der Statusleiste und im Output-Bereich; mit compliance.diagnostics, problems.enabled, problems.perLine oder deadCode.enabled stehen die Befunde in der Error List neben denen des Compilers — ein Eintrag je Datei unter einem Gate, einer je nicht abgedecktem Bereich, einer je Funktion, die nie gelaufen ist — und jeder öffnet seine Datei an der Zeile.

Visual Studio: Check Coverage Thresholds, with the findings in the Error List beside the compiler's ownScreenshot pending — add assets/img/vs-error-list.png (see SCREENSHOTS.md).
In Visual Studio: Check Coverage Thresholds, mit den Befunden in der Error List.

Schwellenwertprofile

threshold.profile legt fest, wofür ein Schwellenwert steht, den Sie nicht gesetzt haben. standard, der Standard seit 0.2026.82, ist das, woran sich ein gewöhnliches, nicht sicherheitsrelevantes Projekt messen lassen kann. safety bedeutet jede Schranke auf 100 – das, was ein Sicherheitsnachweis verlangt, und genau das, was bis 0.2026.81 ausgeliefert wurde.

Metrikstandardsafety
Zeilen80100
Funktionen80100
Regionen75100
Zweige70100
Gesamtscore75100
MC/DC, Instanziierungen, Funktionsaufrufe, Objektcodeohne Schranke100
Bedingungenohne Schranke100
Mutationsscoreohne Schrankeohne Schranke

Ein Schwellenwert, den Sie selbst gesetzt haben, hat Vorrang vor beiden Profilen. Das Beispiel setzt die Schranke für Zweige auf 90 und für alles andere auf 100; um nur einige Metriken auf 100 zu halten, bleiben Sie bei standard und setzen diese selbst. Eine Einschränkung ergibt sich aus der Funktionsweise von Einstellungen: Ein Wert, der dem ausgelieferten Standard entspricht, lässt sich nicht von einem fehlenden Wert unterscheiden. Unter safety zählt deshalb ein Schwellenwert, der genau mit seinem Standardwert angegeben ist – etwa 80 für Zeilen –, weiterhin als 100.

{
  "fuciniCoverage.threshold.profile": "safety",
  "fuciniCoverage.threshold.branch": 90
}
The settings panel: the threshold profile above the grid of thresholds, showing the standard figuresScreenshot pending — add assets/img/threshold-profile.png (see SCREENSHOTS.md).
Switching the threshold profile to safety in the settings panel: the live preview asks for 100% everywhere; back on standard it asks for 80, 70, 80 and 75 and marks the rest as not gatedScreenshot pending — add assets/img/threshold-profiles.gif (see SCREENSHOTS.md).

Wenn Sie sich auf die alten Standardwerte verlassen haben, werden Sie nach dem Update auf 0.2026.82 nachsichtiger beurteilt, bis Sie safety auswählen. Eine Installation, die bereits zuvor lief, wird einmalig darauf hingewiesen, mit einer Schaltfläche Keep 100% (safety), die das Profil in Ihre Benutzereinstellungen schreibt; bei einem gemeinsam genutzten Projekt tragen Sie es zusätzlich in die Arbeitsbereichseinstellungen ein, damit alle gleich beurteilt werden. Configure Coverage Compliance & Thresholds... zeigt das Profil oberhalb des Schwellenwertrasters, und die Live-Vorschau beurteilt mit den tatsächlich geltenden Schranken. In jeder Karte und jedem Bericht zeigt eine Metrik, deren Schranke ausgeschaltet ist, ihren Wert mit einem neutralen Strich statt mit einem Häkchen oder einem Kreuz.

The status-bar card under the standard profile: two of four gates below threshold, and a neutral mark on the metrics that are not gatedScreenshot pending — add assets/img/statusbar-metrics.png (see SCREENSHOTS.md).

11a. Objektcode-Coverage

Jede andere Metrik hier wird am Quelltext gemessen: ein Werkzeug instrumentiert Ihren Code, der instrumentierte Build läuft, und die Zähler sagen, welche Anweisungen, Zweige oder Bedingungen ausgeführt wurden. Objektcode-Coverage misst etwas anderes — wie viel des gebauten Binärprogramms tatsächlich ausgeführt wurde, gezählt in Instruktionsbytes, durch Beobachtung des Instruktionsstroms statt durch Instrumentierung des Quelltexts. Das ist wichtig, weil ein Compiler Code erzeugt, für den keine Zeile Ihres Quelltexts steht: Array-Grenzprüfungen, switch-Sprungtabellen, Register-Spills, Stack-Probes, Aufrufe von Laufzeit-Hilfsroutinen für Division oder Gleitkomma auf Kernen ohne die Instruktion. Sie ist außerdem die einzige Metrik hier, die die Frage deckt das Assembler ab? beantwortet — handgeschriebener Assembler wird nie instrumentiert, und ein quellbasiertes Werkzeug erreicht ihn nicht. DO-178C sagt ausdrücklich, warum: Auf Stufe A, wo ein Compiler oder Linker Code erzeugt, der nicht direkt auf Quelltextanweisungen zurückführbar ist, verlangt Ziel 6.4.4.2b zusätzliche Verifikation genau dieses erzeugten Codes.

Sie subsumiert die Anweisungsüberdeckung — jede ausgeführte Instruktion stammt aus einer Anweisung, also impliziert 100% Objektcode-Coverage 100% Anweisungsüberdeckung. Umgekehrt gilt das nicht, und genau diese Asymmetrie ist der Sinn der Messung. Daraus folgt zweierlei. Sie hat kein Gewicht im zusammengesetzten Score, denn zwei Maße derselben Ausführungen zu mitteln zählt denselben Nachweis doppelt; stattdessen wird sie über fuciniCoverage.threshold.objectCode geprüft — eine Anforderung statt eines Gewichts, genau wie die Norm es verlangt. Und die Lücke ist das Ergebnis: Ein Lauf mit 100% Zeilenüberdeckung und weniger als 100% Objektcode-Coverage hat genau den vom Compiler erzeugten Code gefunden, für den Ihr Quelltext nicht steht; die Compliance-Karte sagt deshalb 312 Bytes nie ausgeführt, bei 100% Zeilenüberdeckung, statt es als «94%» zu verstecken. Der umgekehrte Fall — ein ganzes Binärprogramm gilt als ausgeführt, sein Quelltext nicht — ist ein Widerspruch und kein niedriger Wert: fast immer ein veraltetes Tracefile auf einer Seite einer Zusammenführung oder Modulnamen, die nie zu Dateipfaden passten. Das wird als Befund gemeldet.

Objektcode-Coverage setzt voraus, dass das Binärprogramm dort läuft, wo seine Instruktionen beobachtet werden können. Es gibt drei Wege, und sie unterscheiden sich enorm im Aufwand. Nur der dritte liefert Objektcode-Coverage; die ersten beiden stehen hier, weil sie ein verwandtes Problem lösen, das oft das eigentlich lohnende ist.

  1. Ein instrumentierter Build, der auf dem Target läuft. GCC-Cross-Compiler akzeptieren -fprofile-arcs -ftest-coverage, also funktioniert die Instrumentierung vom Arbeitsplatzrechner auch auf dem Target — nur hat ein Bare-Metal-System kein Dateisystem für die .gcda-Zähler und oft kein exit(), bei dem es sie schreiben könnte. Die Zähler liegen ohnehin im RAM, also besteht die Lösung darin, diesen Speicher auszulesen und die Dateien außerhalb des Targets zu rekonstruieren; embedded-gcov von NASA JPL (Apache-2.0) tut genau das, ohne Dateisystem, Betriebssystem oder Standard-C-Bibliothek. Das ergibt Anweisungs-, Zweig- und Funktionsüberdeckung eines Builds Ihres Cross-Compilers, für Ihren Befehlssatz, auf Ihrer Hardware — keine Objektcode-Coverage, und das gemessene Binärprogramm ist instrumentiert, also größer und langsamer als das ausgelieferte. Laden Sie das Ergebnis als LCOV, gcovr JSON, gcov JSON oder, bei einer Toolchain älter als GCC 9, als das Klartext-Listing .gcov.
  2. Ein Befehlssatzsimulator. Führen Sie das echte Target-Binärprogramm in einem Simulator aus und leiten Sie die Coverage aus den ausgeführten Adressen ab: keine Hardware, keine Instrumentierung, keine Sonde — und weil er Instruktionen beobachtet, kann er echte Objektcode-Coverage liefern. Die Grenze ist die Modelltreue: Ein Simulator bildet den Kern gut und die Peripherie weniger gut ab, also behandeln Sie Gesamtsystem-Ergebnisse mit Misstrauen, sofern er Ihr Silizium nicht genau modelliert.
  3. On-Chip-Trace und ein Debugger. Der zertifizierungstaugliche Weg und der einzige wirklich rückwirkungsfreie: Die Trace-Einheit des Kerns meldet den Instruktionsstrom an einen Debugger, der daraus Coverage macht. Nichts wird instrumentiert, die Codegröße ändert sich nicht und das Zeitverhalten bleibt unberührt — genau das macht das Ergebnis zu einem Nachweis über das tatsächlich ausgelieferte Binärprogramm. Prüfen Sie das Silizium, bevor Sie dafür Budget einplanen: Bei vielen Mikrocontrollerfamilien gibt es vollen Trace nur auf einer Emulations- oder Entwicklungsvariante mit großem Trace-Puffer und schnellem Trace-Port, während Seriengeräte eine reduzierte Trace-Einheit besitzen, deren Herstellerausweg eine Software-Trace ist, die den Code instrumentiert und Rechenzeit kostet — womit genau die Eigenschaft entfällt, derentwegen dieser Weg gewählt wurde.

Viele Embedded-Projekte messen Coverage, indem sie dieselben Quellen für den Entwicklungsrechner kompilieren und die Unit-Tests dort ausführen. Das ist schnell, braucht keine Hardware und ist für die meisten Teams die richtige Voreinstellung — aber man sollte sich klar machen, was dieser Nachweis eigentlich beschreibt: einen anderen Compiler, einen anderen Optimierer, einen anderen Befehlssatz und ein anderes Binärprogramm als das ausgelieferte. Für die meiste Software ist das ein akzeptabler und gut verstandener Kompromiss. Für Arbeiten, die nach IEC 61508, ISO 26262 oder DO-178C bewertet werden, ist dies der klassische Host-gegen-Target-Einwand, und die obigen Wege sind die klassischen Antworten darauf — der erste schließt ihn für Quell-Coverage, der dritte für Objektcode.

Derzeit ist der für Objektcode gelesene Export der von Lauterbach TRACE32's COVerage.EXPORT.ListModule mit metric="object"; laden Sie ihn wie jedes andere Tracefile. Die Metrik wird nur bei einer kostenpflichtigen Lizenz und während der Evaluierungsphase bewertet und geprüft. Eine Community-Installation bewertet sie nicht — wird aber informiert, wenn ein Tracefile sie enthält, denn ein Compliance-Urteil, das den stärksten Beweis in der Datei stillschweigend wegließe, wäre schlimmer als eines, das sagt, was es weggelassen hat.

12. Nicht-Code-Zeilen ausschließen

Ist excludeComments aktiviert (Standard), werden Anweisungen, die vollständig auf reinen Kommentar- oder Leerzeilen liegen, aus den Summen ausgeschlossen — dies neutralisiert auch eine bekannte Eigenheit von llvm-cov/gcov, bei der eine versprengte Trefferzahl auf einem Kommentar landet. Standardmarkierungen werden ebenfalls berücksichtigt:

x = risky();          // LCOV_EXCL_LINE
// LCOV_EXCL_START
debug_only_block();
// LCOV_EXCL_STOP

Auch Präprozessor-Direktiven zählen als kein Code, in C, C++, Objective-C, CUDA und C#: eine Zeile, die mit # beginnt — #define, #include, #if —, und die Zeilen, auf die ein abschließender Backslash sie fortsetzt. gcov rechnet jede Verwendung eines Makros der Zeile zu, in der es definiert ist; so galt ein Header, dessen einzige gemeldete Zeile #define CHANNEL_COUNT (33U) war, als zu 100% abgedeckt, weil eine Schleife in der .c-Datei bis dorthin lief, und einer, dessen Konstante niemand verwendete, als zu 0%. Ein solcher Header hat jetzt nichts mehr zu messen und wird nicht aufgeführt.

Setzen Sie excluded.includeInTotals auf true, um ausgeschlossene Zeilen dennoch mitzuzählen.

Eine Datei oder einen Ordner herauslassen, aus dem Baum

Klicken Sie mit der rechten Maustaste auf eine Datei oder einen Ordner in der Coverage-Ansicht und wählen Sie Exclude from Coverage — es steht auch unter den Pfadaktionen der Zeile — oder führen Sie Exclude This File from Coverage auf der geöffneten Datei aus: Der arbeitsbereichsrelative Pfad der Datei oder das /** des Ordners wandert in fuciniCoverage.ignore in den Einstellungen des Ordners, einmal, und das Neuladen nimmt ihn aus jeder Summe und jeder Seite heraus; das Muster steht dort, um wieder entfernt zu werden. In Visual Studio haben das Menü der Zeile und Tools → Coverage Studio dieselben zwei, die dieselbe Einstellung in dieselbe Datei schreiben.

Right-click a folder row in the Coverage view, Exclude from Coverage, and the tree redraws without it while the pattern appears in settings.jsonScreenshot pending — add assets/img/exclude-from-tree.gif (see SCREENSHOTS.md).
Exclude from Coverage auf einem Ordner: der Baum ohne ihn, das Muster in den Einstellungen.
Visual Studio: Exclude This File from Coverage on fees.ts, the tree without fees.ts, then .vscode/settings.json with the pattern src/fees.ts under fuciniCoverage.ignore
In Visual Studio: Exclude This File from Coverage auf fees.ts — der Baum ohne die Datei, das Muster in .vscode/settings.json.

Attribute und Namespaces, für .NET

Zwei Einstellungen lesen aus der Quelle, was der Bericht nicht sagen kann. ignore.attributes — standardmäßig ExcludeFromCodeCoverage — schließt die Klasse, Methode oder Eigenschaft unter einem Attribut aus, das sie nennt, wie LCOV_EXCL_START/STOP es täten, welches Werkzeug auch immer den Bericht geschrieben hat: Coverlet beachtet das Attribut, OpenCover, dotCover und ein konvertiertes lcov nicht, und nun stimmen alle überein. Namen mit oder ohne das Suffix Attribute, mit oder ohne Namespace; fügen Sie GeneratedCode, Obsolete oder Ihre eigenen hinzu. ignore.namespaces lässt jede Datei heraus, deren Namespace-Deklaration auf ein Präfix passt, * als Platzhalter — Acme.Generated, Acme.*.Migrations, *Tests —, und der Output-Bereich nennt die Dateien, die er herausgenommen hat. Beide werden in demselben Durchgang gelesen, der die Kommentarmarker liest, in beiden Editionen.

{
  "fuciniCoverage.ignore.attributes": ["ExcludeFromCodeCoverage", "GeneratedCode"],
  "fuciniCoverage.ignore.namespaces": ["Acme.Generated", "*.Migrations"]
}

Ausschließen aus dem Editor

Markieren Sie die Zeilen und nehmen Sie Exclude Selection from Coverage aus der Glühbirne, dem Kontextmenü des Editors oder der Befehlspalette — in Visual Studio die Glühbirne (Ctrl+.), das Kontextmenü des Codefensters, Tools → Coverage Studio oder Ctrl+Shift+U, X —, und der Ausschluss wird dorthin geschrieben, wo der Code ist: [ExcludeFromCodeCoverage] über einer C#-, VB- oder F#-Klasse, -Methode oder -Eigenschaft, mit dem kurzen Namen, wenn die Datei System.Diagnostics.CodeAnalysis bereits importiert, und voll qualifiziert, wenn nicht, sodass kein using hinzugefügt werden muss; LCOV_EXCL_LINE am Ende einer einzelnen Codezeile; LCOV_EXCL_START und LCOV_EXCL_STOP um mehrere, in der Einrückung der ersten Zeile — mit dem Kommentarzeichen der jeweiligen Sprache, //, #, ', -- oder ;. Ein Rückgängig-Schritt. Die Glühbirne bietet es auch auf einer Zeile an, die die Problems-Einträge als nicht abgedeckt markieren. Eine bereits markierte Zeile oder ein bereits attributiertes Element bleibt, wie es ist.

A selection in a C# method, the light bulb, Exclude from coverage, and the LCOV_EXCL_START and STOP lines appearing around itScreenshot pending — add assets/img/exclude-selection.gif (see SCREENSHOTS.md).
Exclude Selection from Coverage: die Marker um die Auswahl geschrieben, im Kommentarzeichen der Datei.
Visual Studio: four lines of an else-if branch in Quote.cs selected, Exclude Selection from Coverage writing LCOV_EXCL_START and LCOV_EXCL_STOP around them, then ExcludeFromCodeCoverage above a method
In Visual Studio: Exclude Selection from Coverage — die LCOV_EXCL-Marken um einen Zweig, dann [ExcludeFromCodeCoverage] über einer Methode.

Nur Zweige, und die Marker von gcovr

Ein defensives else, ein default:, zu dem kein Wert gelangt, der Arm, den ein Compiler für eine Exception hinzufügt: Die Zeile läuft und soll zählen, und nur ihr Zweig kann nicht genommen werden. LCOV_EXCL_BR_LINE und LCOV_EXCL_BR_START … LCOV_EXCL_BR_STOP nehmen die Zweige auf ihren Zeilen aus der Zählung und lassen die Zeilen darin. LCOV_EXCL_EXCEPTION_BR_LINE und sein Bereich nehmen noch weniger heraus — nur die Arme, zu denen eine Exception führt, wo der Bericht sagt, welche das sind, wie es gcovs JSON tut. Jeder Marker wird auch unter den Präfixen von gcovr gelesen: GCOVR_EXCL_LINE, GCOVR_EXCL_START, GCOVR_EXCL_BR_LINE, GCOV_EXCL_STOP und die übrigen bedeuten, was die LCOV_EXCL_-Marker bedeuten, sodass eine für gcovr geschriebene Quelle hier gleich gelesen wird, welches Werkzeug auch immer den Bericht erzeugt hat. Nicht gelesen: GCOVR_EXCL_FUNCTION — nichts auf dieser Zeile sagt, wo die Funktion endet.

if (handle == NULL) return E_FAIL;   // LCOV_EXCL_BR_LINE: the allocator never fails on target
  // LCOV_EXCL_BR_START generated state table
  switch (state) { /* … */ }
  // LCOV_EXCL_BR_STOP
LCOV_EXCL_BR_LINE on a line: the line still counted, its branch gone from the countScreenshot pending — add assets/img/branch-markers.png (see SCREENSHOTS.md).

Sagen, warum: begründete Ausschlüsse

Code aus der Zählung zu nehmen, ist eine Behauptung — „das lässt sich nicht testen“, „das ist eine Entwicklerhilfe“ —, und unter DO-178C, ISO 26262 oder IEC 61508 muss eine Behauptung, die die Zahl ändert, auf der ein Zertifikat beruht, niedergeschrieben und überprüfbar sein. Deshalb kann ein Ausschluss sagen, warum, und zwar dort, wo er geschrieben steht: der Text nach LCOV_EXCL_LINE oder LCOV_EXCL_START oder die Justification von [ExcludeFromCodeCoverage].

abort();                 // LCOV_EXCL_LINE: defensive, unreachable by construction
  // LCOV_EXCL_START debug dump, never built for the target

  [ExcludeFromCodeCoverage(Justification = "a developer aid")]
  public static void DebugDump(decimal amount) { /* … */ }

Die Begründungen werden bei jedem Laden gelesen, und das Log zählt sie. Export Coverage Report… schreibt die Liste — exclusions and their justifications, als Markdown oder CSV: die Datei, die Zeilen, wie der Ausschluss geschrieben wurde, und die Begründung oder none given. Eine Datei, in der nichts Messbares übrig bleibt, steht trotzdem in dieser Liste. Mit eingeschaltetem exclusions.requireReason ist ein Ausschluss ohne Begründung ein Befund: eine Warnung im Problems-Panel an seiner Zeile und ein Scheitern von Check Coverage Thresholds. Exclude Selection from Coverage fragt dann zuerst nach der Begründung und schreibt sie mit dem Marker oder als Justification des Attributs; wird die Frage abgebrochen oder leer gelassen, wird nichts ausgeschlossen.

An exclusion without a reason flagged as a warning at its line, and the exported list with none givenScreenshot pending — add assets/img/justified-exclusions.png (see SCREENSHOTS.md).
Visual Studio: an exclusion without a reason as a warning at its line, and the exported list with none givenScreenshot pending — add assets/img/vs-justified-exclusions.png (see SCREENSHOTS.md).
In Visual Studio: ein Ausschluss ohne Begründung als Warnung an seiner Zeile, und die exportierte Liste mit none given.

12a. Beschreibt diese Coverage noch diese Datei?

Coverage aus einer Tracedatei beschreibt den Quelltext so, wie er beim Testlauf war, und die meisten Formate sagen nicht, welche Fassung das war. Jede Datei im Coverage-Panel befindet sich daher in einem von drei Zuständen:

  • ✓ Verifiziert — die Tracedatei hält fest, was jede gemessene Zeile enthielt, und das stimmt weiterhin mit der Datei überein.
  • Nichts angezeigt — nicht widerlegt. Nichts widerspricht der Coverage, nichts bestätigt sie. Der Normalfall.
  • ⚠ Widerlegt — die Datei selbst widerlegt ihre Coverage. Die Zeile wird gedimmt, der Tooltip nennt den Grund.

Nur zwei Formate können das Häkchen verdienen, weil nur zwei überhaupt etwas über den gemessenen Quelltext festhalten: lcov mit --checksum (in geninfo standardmäßig aus; laut Dokumentation genau dafür gedacht, Coverage verschiedener Dateiversionen nicht zu vermischen) und GNATcoverage XML, das den Text jeder gemessenen Zeile mitliefert. Die lcov-Option einzuschalten lohnt sich.

Die Warnung braucht keins von beiden und funktioniert mit jedem Format: Abdeckung hinter dem Dateiende, eine benannte Funktion, die nicht mehr dort steht, wo der Bericht sie verortet, oder ausgeführte Zeilen, die in der Datei leer sind. Zeitstempel reichen allein nie — ein git checkout verändert jeden, ohne ein Byte zu ändern —, ein geänderter Zeitstempel ist also höchstens ein Grund, noch einmal hinzusehen. Die Prüfung läuft beim Laden der Abdeckung und erneut, sobald eine Datei gespeichert wird oder sich auf der Festplatte ändert, sodass die Markierung der Datei folgt: eine Bearbeitung, die dem Lauf widerspricht, setzt sie, ein Checkout, der die gemessene Version wiederherstellt, entfernt sie. Der Tooltip sagt genau, was das bewiesen hat. Setzen Sie staleWarning.enabled auf false, um all das abzuschalten.

12b. Nicht gemessen versus nicht abgedeckt

Eine Datei, die der Lauf nie erwähnt, ist nicht gemessen: Kein Test hat sie geladen, also hat kein Werkzeug eine Zeile für sie geschrieben. Das ist nicht dasselbe wie nicht abgedeckt — gemessen, mit null Treffern —, und die Erweiterung hat eine fehlende Datei nie mit 0% bewertet. Was sie bis 0.2026.69 nicht tat, war, die fehlenden überhaupt zu zeigen: Ein Modul ohne jeden Test erschien nie im Baum, in den Summen oder in der Schwellenwertprüfung, und ein Leser sah „92%“ für ein Projekt, dessen Dateien zur Hälfte nie ausgeführt worden waren.

Jetzt sagt das Statusleisten-Element je Datei bei geladenem Lauf nicht gemessen für eine Quelldatei von der eigenen Art des Laufs, die der Lauf nicht enthält — „von der Art des Laufs“ heißt, sie hat eine der Dateierweiterungen, die der Lauf gemessen hat, sodass die Header und Quellen eines C-Projekts Kandidaten sind und seine Python-Skripte nicht. Alles darüber hinaus ist opt-in über fuciniCoverage.unmeasured.mode:

  • off (Standard) — sonst ändert sich nichts.
  • list — die Coverage-Ansicht bekommt unten eine Gruppe Unmeasured (nicht gemessen), die jede solche Datei nennt, und jede Zeile öffnet sie; das Ladeergebnis zählt sie; Badges markieren sie mit ? im Explorer; und fuciniCoverage.threshold.unmeasuredFiles kann Check Coverage Thresholds fehlschlagen lassen, wenn es mehr sind als eine von Ihnen gesetzte Zahl. Keine Prozentzahl bewegt sich.
  • count — alles, was list tut, und jede nicht gemessene Datei zählt zusätzlich gegen den Lauf als nicht abgedeckte Datei ihrer eigenen Codezeilen, sodass Statusleiste, Schwellenwerte, Badges, Verlauf, jeder Export und die Test-Coverage-Ansicht die niedrigere Zahl zeigen. Die Datei wird überall, wo sie erscheint, als nicht gemessen gezeichnet, ihre Gutter-Balken sagen „nicht gemessen“ statt „nie gelaufen“, und die Abweichungsprüfung lässt sie in Ruhe — es gibt keine Messung, der ihr Inhalt widersprechen könnte.
{
  "fuciniCoverage.unmeasured.mode": "list",
  "fuciniCoverage.threshold.unmeasuredFiles": 0
}

Header-Dateien sind der bekannte Fehlalarm in C: Sie gehören zur Erweiterungsfamilie des Laufs, und keine Tracedatei wird je eine nennen, denn für sich allein kompiliert sie zu nichts. fuciniCoverage.unmeasured.exclude lässt deshalb standardmäßig **/*.h, **/*.hpp, **/*.hh, **/*.inl und **/*.d.ts aus, in derselben Glob-Syntax wie fuciniCoverage.ignore; fügen Sie eine Plattformportierung hinzu, die hier nicht gebaut wird, oder generierte Stubs, und sie fallen aus der Liste, der Zählung und dem Statusleisten-Zustand heraus. Eine Datei, die ignore nennt, gilt ebenfalls nie als nicht gemessen — sie wegzulassen war ja der Zweck. threshold.unmeasuredFiles ist standardmäßig -1, was nicht prüft; 0 schlägt fehl, sobald irgendeine Datei von der Art des Laufs nie von einem Test geladen wurde, und gilt nur, solange unmeasured.mode auf list oder count steht.

13. HTML-Berichte

  • Generate Full HTML Report — ein selbst gerenderter, mehrseitiger Bericht je Verzeichnis. Die Ausgabe erfolgt nach htmlReport.outputDir oder, falls nicht festgelegt, in den globalen Speicher der Erweiterung.
  • Open Annotated Source — eine annotierte Ansicht einer einzelnen Datei. Verweisen Sie mit externalHtmlReport.dir auf ein vorab erstelltes llvm-cov show --format=html-Verzeichnis, um dessen Seiten statt des integrierten Renderers zu verwenden.
  • Export Fucini JSON — das vollständige normalisierte Modell für eigene Tools.
  • Export Coverage Report... — der Lauf als CSV (pro Datei oder pro Funktion), Markdown-Zusammenfassung, LCOV-Tracefile, Cobertura-XML, SARIF oder eigenständiges SVG-Badge für Ihre README. Auch über die Schaltfläche neben Generate Full HTML Report in der Ansicht „Abgedeckte Dateien“ erreichbar. Alles außer den CSVs ist verlustbehaftet — MC/DC, Regionen und Instanziierungen haben in LCOV, Cobertura oder SARIF keinen Platz —, daher bleiben Fucini JSON und die CSVs die Formate, die jede Metrik tragen.
  • Copy Uncovered Lines — eine Markdown-Zusammenfassung jeder Lücke, bereit zum Einfügen in einen PR.

In Visual Studio. Die Gruppe Reports von Tools → Coverage Studio: Show Annotated Source öffnet das aktive Dokument als Seite im Dokumentbereich — jede Zeile in ihrer Farbe, die Befunde daneben — und scrollt in beiden Richtungen mit dem Editor; Open HTML Report schreibt den einseitigen Bericht nach htmlReport.outputDir (oder %LOCALAPPDATA%\Fucini\CoverageStudio\html-report) und öffnet den Browser; Generate Full HTML Report schreibt dort den Index je Ordner und die Seite je Datei; Export Coverage Report… bietet dieselben acht Formate an und fragt, wohin gespeichert werden soll; Generate Coverage Badge schreibt das Badge dorthin, wo badge.outputPath es sagt, mit badge.autoUpdate nach jedem Laden. Die annotierte Seite braucht WebView2, wie das Coverage-Fenster; die Berichte auf der Platte nicht.

Visual Studio: Show Annotated Source — the file as a page in the document well, beside the editorScreenshot pending — add assets/img/vs-annotated-source.png (see SCREENSHOTS.md).
In Visual Studio: Show Annotated Source — die Datei als Seite im Dokumentbereich, neben dem Editor.
Multi-page HTML report directory indexScreenshot pending — add assets/img/report.png (see SCREENSHOTS.md).
The report, Directory Coverage Summary: one row per folder, a column for every metric the run carriesScreenshot pending — add assets/img/report-directory-summary.png (see SCREENSHOTS.md).
The report, File Coverage Summary: one row per file, with Max CRAP where the report carries complexityScreenshot pending — add assets/img/report-file-summary.png (see SCREENSHOTS.md).
The report, Coverage Gaps: every function with uncovered branches or MC/DC conditions, named as writtenScreenshot pending — add assets/img/report-coverage-gaps.png (see SCREENSHOTS.md).
The report, MC/DC Expression Detail: conditions covered per decisionScreenshot pending — add assets/img/report-mcdc-detail.png (see SCREENSHOTS.md).
Export Coverage Report: CSV per file or per function, a Markdown summary, LCOV, Cobertura XML, SARIF, or an SVG badgeScreenshot pending — add assets/img/export-picker.png (see SCREENSHOTS.md).
The report’s annotated page for src/calc.c: per-line hit counts, a fully covered function, an uncovered else branch, a 1/2 partial branch, an MC/DC expansion and a never-called functionScreenshot pending — add assets/img/annotated-source.png (see SCREENSHOTS.md).

Kommentierter Quellcode vs. einfacher Quellcode

Open Annotated Source ersetzt den aktiven Tab durch eine farbcodierte Coverage-Webview für diese Datei, in derselben Spalte; Open Annotated Source to the Side tut dasselbe, jedoch in einer geteilten Ansicht, sodass Quelltext und kommentierte Ansicht nebeneinander stehen. Um stattdessen an Ort und Stelle hin- und herzuschalten — praktisch auf einem kleinen Bildschirm, auf dem eine Teilung jeden Bereich zu schmal macht — verwenden Sie Toggle Annotated Source: Dies wechselt den aktiven Tab zwischen beiden Ansichten und merkt sich, welche Sie gerade betrachten. Aus der kommentierten Ansicht heraus springt Show Source direkt zurück zum normalen Editor für diese Datei.

Welches HTML Sie tatsächlich sehen, hängt von externalHtmlReport.dir ab: Ist es gesetzt und existiert dort bereits eine zur aktiven Datei passende Seite (llvm-cov legt Seiten pro Datei als <Repo-Name>/<relativer-Pfad>.html an, sodass der Repo-Name-Ordner des Berichts nie konfiguriert werden muss), wird diese vom Toolchain generierte Seite anstelle des integrierten Renderers angezeigt — ihre lokalen Links/Stylesheets werden so umgeschrieben, dass sie innerhalb der Webview funktionieren, und sie enthält Details, die die integrierte Ansicht nicht wiedergibt (MC/DC-Erweiterungsansichten, Regionshervorhebung, Verzeichnis-Rollups). Keine passende Seite für diese Datei, oder die Einstellung leer gelassen? Dann wird stattdessen der integrierte Renderer verwendet. Die Erweiterung liest dieses Verzeichnis nur — sie schreibt niemals hinein.

Ein Coverage-Badge für die README

Generate Coverage Badge schreibt ein SVG im Stil von shields für den aktiven Lauf in den Arbeitsbereich — badge.outputPath, Standard coverage-badge.svg, relativ zum Arbeitsbereichsordner oder absolut, mit denselben Variablen wie jede andere Pfadeinstellung — und bietet an, es zu öffnen. Es ist eine einfache Datei in Ihrem Repository, also bettet eine README es ohne Dienst dahinter ein, ohne Umweg über shields.io, und es funktioniert auch in einem Repository ohne Netzanbindung:

![coverage](coverage-badge.svg)

coverage: 83%

badge.metric wählt, was das Badge zeigt: lines (beschriftet mit coverage), branches, mcdc oder weighted, dieselbe zusammengesetzte Bewertung, die die Statusleiste zeigt, beschriftet mit score. Ein Lauf ohne Daten für die gewählte Metrik bekommt ein graues n/a statt roter 0%. Die Farbe folgt Ihren eigenen colorScale.*-Stufen: lowColor unterhalb von lowThreshold, midColor bis highThreshold, highColor ab dort. Mit eingeschaltetem badge.autoUpdate wird das Badge nach jedem erfolgreichen Laden stillschweigend neu geschrieben, und der Ausgabekanal hält jeden Schreibvorgang als [FUCINI_BADGE] fest — standardmäßig aus, weil es bei jedem Laden in den Arbeitsbereich schreibt. Committen Sie das SVG mit dem Code, und das Bild auf der Repository-Seite folgt der Zahl im Editor.

{
  "fuciniCoverage.badge.outputPath": "docs/coverage-badge.svg",
  "fuciniCoverage.badge.metric": "weighted",
  "fuciniCoverage.badge.autoUpdate": true
}

14. Verlauf & Trends

Aktivieren Sie history.enabled, um Läufe lokal zu speichern (unter Beibehaltung von history.retention davon). Sie erhalten dann einen Trendpfeil (▲/▼) in der Statusleiste, das Trenddiagramm in der Coverage-Ansicht sowie zwei Vergleichsbefehle: Compare with Last Run und Compare Two History Runs, die jeweils ein Regressions-/Verbesserungs-Diff je Datei erzeugen.

In Visual Studio. Jedes Laden wird mit dem davor verglichen: ein Dreieck in der Randleiste an jeder Zeile, die zu laufen begonnen oder aufgehört hat (sinceLastRun.enabled), der Trend neben dem Wert in der Statusleiste und Compare with Last Run für die Dateien, deren Zahlen sich bewegt haben. Mit history.enabled werden die Läufe unter %LOCALAPPDATA%\Fucini\CoverageStudio\history aufbewahrt, history.retention davon, sodass der Vergleich einen Neustart überlebt, das Trenddiagramm etwas zu zeichnen hat und Compare Two History Runs… zwei beliebige davon auswählt.

Compare with Last Run: the run moved from 83.89% to 83.05%, calc.c lost 4.54 points, and the status bar carries the trendScreenshot pending — add assets/img/history-compare.png (see SCREENSHOTS.md).
Since last run: a red mark on the lines that ran in the previous run and not in this one, a green one on the lines that are newly coveredScreenshot pending — add assets/img/since-last-run.png (see SCREENSHOTS.md).

Das Trenddiagramm

Unter der Symbolleiste der Coverage-Ansicht, mit zwei gespeicherten Läufen oder mehr, die Zeilen-Coverage des Verlaufs als Linie, vom ältesten zum neuesten, die neuesten dreißig: ein Punkt je Lauf, der beim Überfahren sein Datum und seinen Wert nennt, und daneben der letzte Wert mit einem Pfeil für die Richtung seit dem ersten. Die senkrechte Skala ist der Bereich der Läufe selbst, sodass ein Team bei 92–94% die Bewegung sieht statt einer flachen Linie unter 100. Beide Editionen zeichnen es aus demselben Verlauf.

The trend chart under the Coverage view's toolbar: a line over a dozen runs, a dot per run, the last figure and an arrow upScreenshot pending — add assets/img/trend-chart.png (see SCREENSHOTS.md).
Der Trend: ein Punkt je gespeichertem Lauf, der letzte Wert daneben.
Visual Studio: the trend line under the Coverage window toolbar, the last figure 68.25%
In Visual Studio: der Trend unter der Symbolleiste des Coverage-Fensters, der letzte Wert 68.25%.

Coverage-Sitzungen

Ein Testlauf deckt selten alles ab, was eine Änderung berührt hat: Die Unit-Tests liefen hier, die Integrationssuite dort, ein Gang durch die Oberfläche mit eingeschalteter Coverage woanders. Start Coverage Session macht aus den folgenden Ladevorgängen eine Summe — jeder Lauf wird Zeile für Zeile als Vereinigung zum vorigen addiert, eine Zeile, die einer von ihnen ausgeführt hat, ist abgedeckt, und die Zähler addieren sich —, sodass Randleiste, Baum und Wert zeigen, was sie alle zusammen erreicht haben. Der Lauf auf dem Bildschirm, falls es einen gibt, ist der erste der Sitzung. Eine Leiste über dem Baum sagt, wie viele Läufe seit wann, und beendet die Sitzung; End Coverage Session tut dasselbe, und das nächste Laden steht wieder für sich. In Visual Studio startet ein Eintrag unter Tools → Coverage Studio die Sitzung und beendet sie, angehakt, wieder.

A coverage session: the unit test run loads, the session starts, the integration run loads on top, and the bar says two runs while the tree's numbers riseScreenshot pending — add assets/img/coverage-session.gif (see SCREENSHOTS.md).
Eine Sitzung aus zwei Läufen: der zweite zum ersten addiert, die Leiste über dem Baum zählt sie.
Visual Studio: the unit run loaded, Start Coverage Session, the integration run added, the bar saying 2 runs and lines at 68.25%, then the session ended
In Visual Studio: Start Coverage Session, und ein zweiter Lauf zum ersten addiert — die Leiste zählt zwei Läufe, die Zeilen steigen von 50.79% auf 68.25%.

Die CI-Baseline: Wo stehe ich gegenüber main?

Compare with Last Run beantwortet, was Ihre letzte Änderung bewirkt hat; vor einem Pull Request lautet die Frage, wo Sie gegenüber main stehen, und die Antwort liegt auf dem Build-Server. baseline.report nennt den Bericht, den der Build des main-Branches veröffentlicht, und jedes Laden wird dagegen gehalten: Die Karte der Statusleiste trägt das einzeilige Delta — vs CI baseline: 84.20% → 85.10% (+0.90%), 3 file(s) moved —, und Compare with CI Baseline listet die Dateien, die sich bewegt haben, Datei für Datei, in denselben Worten wie Compare with Last Run. In Visual Studio steht der Befehl unter Tools → Coverage Studio und ruft den Bericht ab oder liest ihn, wenn Sie danach fragen. Drei Arten, ihn zu nennen, in .vscode/settings.json:

  1. Eine URL, die die CI ausliefert. GitLab hält die Artefakte des letzten Jobs eines Branches unter einer stabilen Adresse bereit; das Token bleibt über ${env:…} in remote.headers aus der Einstellungsdatei heraus. Jenkins: https://jenkins.example.com/job/app/job/main/lastSuccessfulBuild/artifact/coverage/lcov.info. TeamCity: https://tc.example.com/repository/download/App_Main/.lastSuccessful/coverage/lcov.info mit Authorization: Bearer ${env:TC_TOKEN}. Die URL wird genau wie eine coverageFile.paths-URL abgerufen und zwischengespeichert (ETag, remote.refreshMinutes).
  2. Eine Datei, die die Pipeline auf eine Freigabe kopiert hat — ein absoluter Pfad wie \\build\drops\app\main\coverage.cobertura.xml.
  3. Ein heruntergeladenes Artefakt unter dem Ordner, etwa ci/main.lcov.info (nehmen Sie den Ordner in die .gitignore auf) — ein Pfad relativ zum Ordner.
{
  "fuciniCoverage.baseline.report": "https://gitlab.example.com/api/v4/projects/42/jobs/artifacts/main/raw/coverage/lcov.info?job=test",
  "fuciniCoverage.remote.headers": ["PRIVATE-TOKEN: ${env:GITLAB_TOKEN}"]
}

Jedes Format, das der Leser kennt, genügt. Ein Pfad, den die CI relativ zu ihrem Checkout geschrieben hat — src/Billing/Invoice.cs, wie Coverlet ihn auf dem Runner schreibt —, wird vor dem Diff unter diesen Ordner gelegt, sodass er auf die Datei trifft, die der lokale Lauf aufgelöst hat; ein absoluter Pfad von einem anderen Rechner passt auf nichts, lassen Sie die Pipeline also relative Pfade schreiben. Eine Baseline, die sich nicht abrufen oder lesen lässt, ist eine Zeile im Output-Bereich, nie ein fehlgeschlagenes Laden.

Compare with CI Baseline: the status bar's card with the vs CI baseline line, then the command listing the files that moved against main, regressions firstScreenshot pending — add assets/img/ci-baseline.gif (see SCREENSHOTS.md).
Die CI-Baseline: das Delta auf der Karte und die Dateien, die sich gegenüber main bewegt haben.
Visual Studio: baseline.report set to the unit suite report, then Compare with CI Baseline showing statements 50.79% to 68.25% and branches 30.43% to 50.00%, one file changed
In Visual Studio: Compare with CI Baseline — Anweisungen und Zweige gegen den Bericht der Unit-Tests, und die Datei, die sich änderte.

Ein Artefakt ist ein Zip, und auch das wird gelesen. GitHub und GitLab geben ein Artefakt als Archiv heraus, was auch immer hineingelegt wurde. Nennen Sie den Bericht darin nach einem #: Der Eintrag wird über seinen Pfad oder dessen Ende gefunden; ohne # ist es die einzige Datei des Archivs oder seine einzige Datei, die wie ein Bericht aussieht, und wo es mehrere gibt, nennt der Output-Bereich sie. Dasselbe gilt für ein Zip, das Sie heruntergeladen haben (ci/artifact.zip#lcov.info), und, in VS Code, für eine URL in coverageFile.paths. Das Token geht an den Server, für den es gesetzt wurde, und nicht weiter: Der Weiterleitung zu dem Speicher, in dem das Archiv liegt, wird ohne das Token gefolgt.

{
  "fuciniCoverage.baseline.report": "https://api.github.com/repos/acme/app/actions/artifacts/1234567/zip#coverage/lcov.info",
  "fuciniCoverage.remote.headers": ["Authorization: Bearer ${env:GITHUB_TOKEN}"]
  }

14a. Für KI-Agenten: die Coverage auf dem Bildschirm

Ein Agent, der Tests schreibt, kann sie ausführen und eine Prozentzahl lesen. Was er von sich aus nicht kann, ist fragen, was der Editor weiß: welche Zeilen dieser Funktion nie liefen, welche Seite welches Zweigs, welche Tests eine Zeile ausführen, ob der Diff, den er gerade geschrieben hat, abgedeckt ist. Sechs Werkzeuge beantworten genau das, in Worten, nach denen ein Agent handeln kann, aus dem geladenen Lauf — dieselben Ausschlüsse, dasselbe Remapping, dieselben Zahlen wie auf dem Bildschirm. So sprechen ein Agent, der die Lücken einer Funktion abdecken soll, und ein Reviewer, der auf die Randleiste schaut, über dieselben Zeilen.

WerkzeugWas es beantwortet
coverage_summaryDie Summen des Laufs je Metrik und die Dateien, die am weitesten von abgedeckt entfernt sind. Das Erste, wonach man fragt.
coverage_gapsWas in einer Datei, einer Funktion oder einem Zeilenbereich nie lief: die nicht abgedeckten Zeilen, die nicht genommenen Zweigarme, die MC/DC-Bedingungen ohne ihr Paar, die überlebenden Mutanten.
tests_for_lineWelche Tests eine Zeile ausgeführt haben, wo der Bericht es sagt — ein Lauf je Test.
patch_coverageDie Coverage eines Diffs — das Arbeitsverzeichnis gegen eine Ref oder ein übergebener Patch — und seine Zeilen, die nie liefen.
coverage_deltaWas sich seit dem Lauf davor bewegt hat: die Summen und die Dateien, die gewonnen oder verloren haben.
test_run_commandDer Befehl, der die Tests dieses Arbeitsbereichs mit eingeschalteter Coverage ausführt. Der Agent führt ihn aus; der Editor lädt den Bericht von selbst neu.

Der eigene Agent von VS Code hat sie als Werkzeuge, ohne dass etwas einzurichten wäre. Alle anderen Agenten — jeder Client, der MCP spricht, das Model Context Protocol — erreichen sie über einen Server, den der Editor betreibt, wenn mcp.enabled eingeschaltet ist, in VS Code wie in Visual Studio. Copy MCP Server Configuration legt den Eintrag für den Client in die Zwischenablage, so wie VS Code und Visual Studio ihn in einer mcp.json lesen; ein Client, der den äußeren Schlüssel mcpServers nennt, nimmt denselben Eintrag unter diesem Namen.

Copy MCP Server Configuration and its message, the token painted overScreenshot pending — add assets/img/mcp-config.png (see SCREENSHOTS.md).
Visual Studio: Copy MCP Server Configuration and its message; the token painted overScreenshot pending — add assets/img/vs-mcp-config.png (see SCREENSHOTS.md).
In Visual Studio: Copy MCP Server Configuration und seine Meldung; das Token übermalt.
{
  "servers": {
    "fucini-coverage": {
      "type": "http",
      "url": "http://127.0.0.1:39217/mcp",
      "headers": { "Authorization": "Bearer …" }
    }
  }
  }
  • Er ist aus, solange Sie ihn nicht einschalten, und er lauscht nur auf 127.0.0.1: Nichts außerhalb dieses Rechners erreicht ihn.
  • Ein Aufruf muss Ihr Token tragen, das einmal erzeugt und für Sie aufbewahrt wird; ohne das Token lautet die Antwort 401. Die kopierte Konfiguration enthält das Token: Halten Sie sie aus dem Repository heraus.
  • Ein Aufruf, den eine Webseite gesendet hat — er sagt es in seinem Origin —, wird abgewiesen, was auch immer er trägt.
  • Er liest den geladenen Lauf und schreibt nichts. Der Testlauf wird genannt, nicht gestartet: Der Agent führt den Befehl in seinem eigenen Terminal aus.

Der Port ist mcp.port, 39217, wenn nichts anderes gesetzt ist. Wo dieser belegt ist — ein zweites Fenster, die andere Edition daneben —, wird der nächste freie verwendet, und die kopierte Konfiguration nennt den, der funktioniert. Der Output-Bereich sagt, wo der Server lauscht ([FUCINI_MCP]) und warum er es nicht konnte ([FUCINI_MCP_001]). Was ein Plan nicht enthält — die Namen von Tests, MC/DC-Details —, zählen die Werkzeuge, ohne es auszuschreiben, wie es der Hover tut.

15. Befehlsreferenz

In Visual Studio. Jeder Befehl steht unter Tools → Coverage Studio, benannt wie in der Tabelle ohne das Präfix Fucini Coverage:; die Symbolleiste des Coverage-Fensters und das Kontextmenü einer Zeile haben die, die dorthin gehören, und das Kontextmenü des Codefensters hat die drei, die auf den Editor wirken: Run This Test with Coverage, Show Tests That Ran This Line und Exclude Selection from Coverage. Die mit Tasten sind Zwei-Tasten-Akkorde nach Ctrl+Shift+U: R lädt neu, N und P gehen zur nächsten und zur vorigen nicht abgedeckten Zeile, B zur nächsten teilweise getesteten Entscheidung, T listet die Tests, die die Zeile ausgeführt haben, X schließt die Auswahl aus — nicht VS Codes Alt+N, denn in Visual Studio öffnet Alt mit einem Buchstaben ein Menü. Ändern Sie sie unter Tools → Options → Keyboard, wo sie als Coverage Studio: … aufgeführt sind. Nicht in dieser Edition: Das Test-Coverage-Panel ist eine VS-Code-API — der Lauf steht stattdessen im Coverage-Fenster —, und der Projektmappen-Explorer kann keine Badges zeigen. Nur in dieser Edition: Run Native Project with Coverage, für ein C++-Startprojekt.

In Visual Studio: wo alles ist. Das Coverage-Fenster steht unter View → Other Windows → Coverage und an erster Stelle unter Tools → Coverage Studio, wo jeder Befehl dieser Edition liegt, in Gruppen: Laden und Neuladen, die Datei überwachen, die beiden Kopierbefehle und die Karten; Run Tests with Coverage, Run Native Project with Coverage und Collect Coverage in Test Explorer…; Next und Previous Uncovered und die teilweise getesteten Entscheidungen; Einfärbung, Trefferzahlen und die Gutter-Modi; die Coverage-Quelle einer Datei, die Tests, die eine Zeile ausgeführt haben, ein Test mit Coverage, die beiden Arten auszuschließen; Compare with Last Run, Compare Two History Runs…, Compare with CI Baseline, die Coverage-Sitzung und Check Coverage Thresholds; die Gruppe Reports — Show Annotated Source, Open HTML Report, Generate Full HTML Report, Export Coverage Report… und Generate Coverage Badge; dann Getting Started, die Compliance-Schwellen und Licence…. Die eigene Symbolleiste des Fensters hat die fünf, die man am häufigsten braucht: Load Coverage, Reload, Toggle Coverage Painting, Copy Coverage Summary und die Compliance-Schwellen; darunter die Perspektive, der Filter und die Sortierung sowie das Suchfeld; darunter der Trend. Lassen Sie den Zeiger auf einer Zeile des Baums ruhen und drücken Sie ihr ⋯ für das Zeilenmenü — die Datei öffnen, ihren Ordner öffnen, ihren Pfad kopieren, absolut oder relativ, mit beiden Arten von Schrägstrichen, sie aus der Coverage ausschließen. Rechts in der Statusleiste stehen der Wert des Laufs und der der geöffneten Datei, mit dem Trend seit dem letzten Lauf; Show Coverage Card und Show Coverage Card for This File öffnen die Karten dahinter, dieselben, die VS Code zeigt, wenn der Zeiger auf seinem Statusleistenelement ruht.

Visual Studio: Tools → Coverage Studio, open, with every command of the edition
In Visual Studio: Tools → Coverage Studio mit jedem Befehl dieser Edition.
Visual Studio: View → Other Windows, where the Coverage window is
In Visual Studio: View → Other Windows, wo das Coverage-Fenster liegt.
Visual Studio: the Coverage window's toolbar — Load Coverage, Reload, Toggle Coverage Painting, Copy Coverage Summary, compliance thresholds
In Visual Studio: die Symbolleiste des Coverage-Fensters — Load Coverage, Reload, Toggle Coverage Painting, Copy Coverage Summary und die Compliance-Schwellen.
Visual Studio: a row's menu in the Coverage window — Open, Open Containing Folder, and the four Copy Path entries
In Visual Studio: das ⋯-Menü einer Zeile — Datei öffnen, ihren Ordner öffnen, ihren Pfad in vier Formen kopieren.
Visual Studio: the status bar's two items, the run's score and the open file's
In Visual Studio: die zwei Einträge der Statusleiste, der Wert des Laufs und der der offenen Datei.
Visual Studio: the run's coverage card, opened by Show Coverage Card
In Visual Studio: die Coverage-Karte des Laufs, aus Show Coverage Card.
Visual Studio: the open file's coverage card, opened by Show Coverage Card for This File
In Visual Studio: die Karte der offenen Datei, aus Show Coverage Card for This File.
The status-bar hover cards for the run and the file, then the Coverage view toolbar: Pick Coverage File, Load Coverage, Export Coverage Report and Generate Full HTML Report, ending on the generated reportScreenshot pending — add assets/img/statusbar-and-toolbar.gif (see SCREENSHOTS.md).
In VS Code: die Hover-Karten der Statusleiste für Lauf und Datei, dann die Symbolleiste der Coverage-Ansicht, zuletzt der erzeugte Bericht.
The status-bar menu: select a coverage file, run tests with coverage, reload, open the HTML report, choose the gutter modeScreenshot pending — add assets/img/statusbar-menu.png (see SCREENSHOTS.md).
In VS Code: das Statusleisten-Menü — Coverage-Datei wählen, Tests mit Coverage ausführen, neu laden, Bericht öffnen, Gutter-Modus wählen.
Show Worst-Covered Functions: every function of the run, lowest coverage first, with its CRAP score where the report carries complexityScreenshot pending — add assets/img/worst-functions.png (see SCREENSHOTS.md).
In VS Code: Show Worst-Covered Functions, geringste Abdeckung zuerst, mit dem CRAP-Wert, wo der Bericht Komplexität enthält.
BefehlFunktion
Load CoverageAbdeckung für den Arbeitsbereich finden und laden. Standardmäßig Alt+Shift+R (Ctrl+Alt+R unter macOS).
Pick Coverage FileTracedateien auswählen – eine, mehrere oder jedes Mal eine weitere; Auswahlen summieren sich, werden zusammengeführt und in coverageFile.paths geschrieben, sodass sie ab dann von selbst laden.
Show Loaded Coverage FilesDie Tracedateien des aktiven Laufs auflisten. Die Abdeckungsansicht listet sie ebenfalls, jede mit einer Entladen-Schaltfläche und einer Auswählen-Schaltfläche daneben.
Toggle Tracefile WatchTracedatei(en) auf Änderungen überwachen und automatisch neu laden.
Run Tests with CoverageDen Test-Runner erkennen, ihn mit Abdeckung in einer Terminal-Aufgabe ausführen, das Geschriebene laden und anbieten, den Pfad in die Einstellungen aufzunehmen.
Run This Test with CoverageDer Test unter dem Cursor — die Methode, die Klasse oder der describe-Block, oder die Datei —, ausgeführt mit dem darauf eingeengten Rezept und dann geladen wie jeder Lauf. Auch im Kontextmenü des Editors.
Show Tests That Ran This LineWo der Bericht sagt, welche Tests was ausgeführt haben, die Tests auflisten, die die Zeile unter dem Cursor ausgeführt haben, die fleißigsten zuerst, und den gewählten dort öffnen, wo er geschrieben steht.
Run Tests Affected by My Changes…Die Tests auflisten, die eine Zeile ausgeführt haben, die das Arbeitsverzeichnis gegenüber testImpact.baseRef ändert, den gewählten öffnen oder nur diese ausführen, wo die Berichte aus einem Lauf je Test stammen.
Show Minimal Test Set…Die wenigsten Tests, die noch jede Zeile ausführen, die die Suite ausführt, dann die Tests, die keine eigene Zeile hinzufügen.
Run App with Coverage…Die .NET-App des Ordners unter dotnet-coverage starten und, wenn sie sich schließt, laden, was Sie durchlaufen haben.
Run Mutation Tests HereDie Funktion, in der der Cursor steht — oder die Auswahl, oder die Datei —, mit Stryker.NET, StrykerJS oder PIT mutieren und den Bericht neben der Coverage auf dem Bildschirm laden.
Exclude This File from Coverage / Exclude from CoverageDie geöffnete Datei — oder, auf einer Zeile der Coverage-Ansicht, die Datei oder das /** des Ordners — in fuciniCoverage.ignore in den Einstellungen des Ordners eintragen, einmal.
Exclude Selection from CoverageDen Ausschluss dorthin schreiben, wo der Code ist: [ExcludeFromCodeCoverage] über einem .NET-Element, LCOV_EXCL_LINE auf einer Zeile, LCOV_EXCL_START/STOP um mehrere, im Kommentarzeichen der Datei. Auch über die Glühbirne und das Kontextmenü des Editors.
Start Coverage Session / End Coverage SessionSolange eine Sitzung läuft, wird jedes Laden als Vereinigung zum vorigen addiert; eine Leiste über dem Baum zählt die Läufe und beendet sie.
Next / Previous UncoveredZwischen nicht abgedeckten Regionen springen. Standardmäßig Alt+N / Alt+P (Ctrl+Alt+N / Ctrl+Alt+P unter macOS).
Choose Editor Gutter Mode...Aus, Balken nur auf nicht abgedeckten Zeilen, rot-bernstein-grüne Balken oder eine Heatmap der Trefferzahlen im Gutter des Editors.
Cycle Editor Gutter ModeEinen Schritt weiter durch off, uncovered, coverage und heatmap — Alt+G oder die Modus-Schaltfläche in der Statusleiste.
Choose Coverage Source for This File...Wenn mehr als ein geladener Bericht die offene Datei misst, wählen, aus welchem ihre Zahlen stammen, für die Datei, ihren Ordner oder ein Muster — schreibt eine coverageFile.sources-Regel.
Clear Coverage Source for This File...Die coverageFile.sources-Regeln entfernen, die für die offene Datei gelten.
Toggle Inline Hit CountsDie ×N-Ausführungszähler hinter jeder Zeile anzeigen oder ausblenden — schaltet hitCounts.inline um.
Show in Test Coverage ViewDen aktiven Lauf in VS Codes eigenes Test-Coverage-Panel veröffentlichen (auch bei ausgeschaltetem testCoverage.publish) und es öffnen.
Suggest Path Remap RuleDie pathRemap-Regel ableiten, die die unzugeordneten Dateien des aktiven Laufs dem Arbeitsbereich zuordnen würde, und anbieten, sie hinzuzufügen.
What Community IncludesJede Obergrenze und jede zurückgehaltene Funktion der kostenlosen Stufe in einer Liste, mit dem verbrauchten Anteil jeder Obergrenze.
Open HTML ReportDen erzeugten statischen Bericht öffnen.
Generate Full HTML ReportDen mehrseitigen Bericht erzeugen.
Open Annotated Source / …to the SideAnnotierte Coverage-Ansicht für eine Datei.
Toggle Annotated SourceZwischen Quelltext und annotierter Ansicht wechseln. Standardmäßig Alt+A (Ctrl+Alt+A unter macOS).
Show Worst-Covered Files / Folders / FunctionsQuick Pick, aufsteigend nach dem schlechtesten Wert.
Copy Uncovered LinesMarkdown-Zusammenfassung jedes nicht abgedeckten Bereichs.
Compare Two History Runs / with Last RunRegressions-Diff je Datei — zwei Läufe aus dem Verlauf oder der Lauf auf dem Bildschirm gegen den, den er ersetzt hat.
Compare with CI BaselineDer geladene Lauf gegen den Bericht, den baseline.report nennt — der des main-Branches aus der CI, eine URL oder ein heruntergeladenes Artefakt —, Datei für Datei.
Show Indirect Coverage Changes…Die Zeilen, deren Coverage sich bewegt hat, obwohl niemand sie bearbeitet hat, gegen die CI-Baseline oder den Lauf davor, je Datei.
Check Coverage ThresholdsDie Compliance-Prüfungen auswerten.
Export Fucini JSONDen aktuellen Lauf als Fucini JSON exportieren.
Export Coverage Report...Ein Format wählen — CSV, Markdown, LCOV, Cobertura-XML, SARIF oder ein SVG-Badge — und ein Ziel.
Generate Coverage BadgeDas SVG-Badge für den aktiven Lauf nach badge.outputPath schreiben, mit badge.metric als angezeigtem Wert, und anbieten, es zu öffnen.
Copy MCP Server ConfigurationWas ein MCP-Client braucht, um nach der Coverage auf dem Bildschirm zu fragen — die Adresse des Servers und Ihr Token —, in die Zwischenablage legen; ist der Server aus, anbieten, ihn einzuschalten.
Show Status Bar MenuDas Schnellaktionsmenü öffnen.
Browse for External HTML Report / Full Report Output Dir…Die Berichtsverzeichnisse über einen Auswahldialog festlegen.

16. Einstellungsreferenz

Die vollständige, kategorisierte Einstellungstabelle — jede Option mit ihrem Standardwert — finden Sie auf der Seite Features & Settings. Alle Schlüssel beginnen mit dem Präfix fuciniCoverage..

Erwähnenswert: fuciniCoverage.language legt die eigene Laufzeit-UI dieser Erweiterung (Statusleiste, Benachrichtigungen, Tooltips, Webviews) unabhängig von der Display Language von VS Code auf eine bestimmte Sprache fest — Standard ist auto, mit Bundles für alle 18 unterstützten Sprachen. Es ändert nicht die Einträge der Befehlspalette oder die Beschriftungen der Einstellungs-UI, die VS Code weiterhin aus seiner eigenen Display Language bezieht.

In Visual Studio. Dieselben fuciniCoverage.*-Schlüssel, gelesen aus bis zu vier Dateien, wobei die spätere gewinnt: VS Codes eigene Benutzereinstellungen, wenn VS Code auf dem Rechner ist — gelesen, nie geschrieben, damit Ihre Farben und Schwellen mitkommen; %APPDATA%\Fucini\CoverageStudio\settings.json, die Benutzereinstellungen dieser Edition; .vscode\settings.json im Ordner oder neben der Projektmappe, sodass ein für VS Code eingerichtetes Repository für Visual Studio eingerichtet ist; und fucini-coverage.json im Stammordner der Projektmappe, für ein Team, das lieber keinen .vscode-Ordner in einem .NET-Repository hält — die VS-Code-Edition liest sie auch. Das Zahnrad in der Symbolleiste des Coverage-Fensters öffnet ein Einstellungsfenster, das die Benutzerdatei oder die vorhandene Datei des Ordners schreibt, wie seine Auswahl Write changes to sagt, und die Kommentare einer Datei, die es bearbeitet, erhält. fuciniCoverage.language funktioniert dort genauso; die Menüs folgen Visual Studios eigener Sprache.

17. Fehlercodes

Diagnosemeldungen gehen an den Ausgabekanal Fucini Coverage (View → Output → Fucini Coverage), jede mit einem stabilen FUCINI_*-Code.

In Visual Studio. Dieselben Codes gehen in das Fucini Coverage-Fenster der Ausgabe (View → Output) und werden in %LOCALAPPDATA%\Fucini\CoverageStudio\coverage-studio.log aufbewahrt, für die Frage, die nach dem Schließen der IDE kommt. Drei, die vorkommen: Nichts ist markiert, obwohl das Fenster sagt, dass Dateien geladen wurden — der Randleistenmodus ist off, wählen Sie Show Coverage in Editor; FUCINI_REMAP_001 und eine Informationsleiste — der Bericht nennt Pfade, die es hier nicht gibt, und das Fenster schlägt die pathRemap-Regel vor; das Coverage-Fenster sagt, es brauche WebView2 — installieren Sie die Microsoft Edge WebView2 Runtime, die Markierungen im Editor brauchen sie nicht.

CodeBedeutung
FUCINI_PARSE_001Nicht unterstütztes/unbekanntes Coverage-Format — kein Parser passte zur Datei.
FUCINI_PARSE_010Die lcov-Datei enthielt keine SF-Einträge.
FUCINI_PARSE_020llvm-cov-JSON ungültig, data[] fehlt oder enthielt keine Dateien.
FUCINI_PARSE_030Cobertura-Wurzelelement <coverage> fehlt oder XML ungültig.
FUCINI_PARSE_040JaCoCo-Wurzelelement <report> fehlt oder keine Quelldateien.
FUCINI_PARSE_050Istanbul/SimpleCov-JSON ungültig oder enthielt keine Dateien.
FUCINI_PARSE_060SimpleCov-JSON ungültig oder ohne files-Array auf oberster Ebene.
FUCINI_PARSE_070Go-Profil ohne mode:-Kopfzeile oder ohne Abdeckungsblöcke.
FUCINI_PARSE_080Clover-Wurzelelement <coverage> oder <project> fehlt, oder es enthält keine Dateien.
FUCINI_PARSE_090OpenCover-Wurzelelement <CoverageSession> fehlt, oder es enthält keine Dateien.
FUCINI_PARSE_100coverage.py-JSON ungültig oder ohne files-Objekt auf oberster Ebene.
FUCINI_PARSE_110gcov/gcovr-JSON ungültig oder ohne files-Array auf oberster Ebene.
FUCINI_PARSE_120GNATcoverage-XML ohne <source>-Element oder eine index.xml, deren xi:includes nie aufgelöst wurden — laden Sie stattdessen die *.xml-Dateien je Quelldatei.
FUCINI_PARSE_130BullseyeCoverage-Wurzelelement <BullseyeCoverage> fehlt oder enthält keine <src>-Elemente.
FUCINI_PARSE_140Visual-Studio-Wurzelelement <CoverageDSPriv> fehlt, keine <SourceFileNames>-Tabelle zum Auflösen der Zeilenzeilen, oder keine Zeilendaten enthalten.
FUCINI_PARSE_150Xcode-Coverage-JSON ungültig oder ohne targets-Array auf oberster Ebene.
FUCINI_PARSE_160SonarQube-Wurzelelement <coverage> fehlt oder enthält keine <file>-Elemente.
FUCINI_PARSE_170Coveralls-JSON ungültig oder ohne source_files-Array auf oberster Ebene.
FUCINI_LOADEin Ladevorgang wurde über seine Fortschrittsbenachrichtigung abgebrochen; der vorherige Lauf, falls vorhanden, bleibt geladen.
FUCINI_REMOTE_001Eine coverageFile.paths-URL konnte nicht abgerufen werden, mit dem Grund; stattdessen wird die zuletzt heruntergeladene Kopie geladen. Einfache [FUCINI_REMOTE]-Zeilen halten jeden Download und jede Prüfung ohne Änderung (304) fest.
FUCINI_REMOTE_002Eine coverageFile.paths-URL hat innerhalb von 30 Sekunden keine vollständige Antwort geliefert — meist ein Proxy oder VPN, der die Verbindung annimmt und dann schweigt; stattdessen wird die zuletzt heruntergeladene Kopie geladen.
FUCINI_REMOTE_003Eine coverageFile.paths-URL hat mit einer HTML-Seite statt einer Tracefile geantwortet — höchstwahrscheinlich eine Anmeldeseite. Die Seite wird nicht zwischengespeichert, stattdessen wird die zuletzt heruntergeladene Kopie geladen; prüfen Sie das Token in remote.headers.
FUCINI_REMAP_002Für die Pfade, die ein Ladevorgang unzugeordnet ließ, wurde eine pathRemap-Regel vorgeschlagen, mit der Zahl der Pfade, die sie erklärt — oder es konnte keine abgeleitet werden, oder die abgeleitete Regel steht bereits in der Einstellung und hat sie nicht aufgelöst.
FUCINI_REMAP_003Die vorgeschlagene Regel wurde von Apply Suggested Remap an fuciniCoverage.pathRemap angehängt, und die Coverage wird neu geladen.
FUCINI_GITDIFF_001Die Git-Erweiterung ist nicht verfügbar; die Diff-Abdeckung wird übersprungen und der gesamte Lauf angezeigt.
FUCINI_GITDIFF_002gitDiff.baseRef beginnt mit -, womit keine Git-Referenz beginnen kann (Git würde es als Option lesen); die Diff-Abdeckung wird übersprungen und der gesamte Lauf angezeigt.
FUCINI_IGNOREWie viele Dateien fuciniCoverage.ignore aus dem Lauf herausgehalten hat, und welche.
FUCINI_UNMEASURED_001Die Dateien von der Art des Laufs, die kein Test geladen hat, eine je Zeile.
FUCINI_UNMEASURED_002Mehr als 5.000 Arbeitsbereichsdateien passten auf eine der Erweiterungen des Laufs; nur die ersten 5.000 wurden für die Liste der nicht gemessenen Dateien berücksichtigt.
FUCINI_UNMEASURED_003Im Modus count werden einige nicht gemessene Dateien aufgeführt, aber nicht gezählt: Die Lesegrenze (2.000 Dateien oder 50 MB je Ladevorgang) wurde erreicht.
FUCINI_UNMEASURED_004Eine nicht gemessene Datei konnte nicht gelesen werden; sie wird aufgeführt, aber nicht gezählt.
FUCINI_TESTCOVERAGEWie viele Dateien in VS Codes Test-Coverage-Ansicht veröffentlicht wurden.
FUCINI_BADGEDas Badge wurde geschrieben, mit Pfad, Beschriftung und Wert.
FUCINI_BADGE_001Das Badge konnte nicht geschrieben werden, mit dem Grund.
FUCINI_WORKSPACEEin Ordner wurde zum Arbeitsbereich hinzugefügt oder daraus entfernt; die Coverage wird erneut erkannt.
FUCINI_VARIABLESWas jedes ${command:…} in den Pfadeinstellungen geantwortet hat oder warum es wie geschrieben stehen blieb: Der Befehl ist fehlgeschlagen, hat nichts Brauchbares geliefert, oder der Arbeitsbereich ist nicht vertrauenswürdig.
FUCINI_WATCHWas der Watcher tut: die überwachten Pfade, eine konfigurierte Datei, die erschienen ist, eine in watch.reloadAfterTasks genannte Aufgabe, die endete (mit ihrem Exit-Code) und ein Neuladen auslöste, oder ein Pfad unter files.watcherExclude, der stattdessen abgefragt wird.

18. Datenschutz

Telemetrie wird über die window-bezogene Einstellung telemetry.enabled gesteuert. Standardmäßig ist sie aus. Die tägliche Zusammenfassung und die Entfernungsmeldung setzen zusätzlich voraus, dass VS Codes globales telemetry.telemetryLevel Telemetrie erlaubt; der Installations-Ping und einige kleine Ereignisse werden unabhängig davon gesendet, ebenso der Eintrag im Nutzungsregister einer Installation im Testzeitraum oder auf der kostenlosen Community-Stufe. Auf Community tauscht Unlock Full Features diese Telemetrie gegen jede Pro-Funktion, MC/DC eingeschlossen, für 30 Tage, einmal pro Gerät — schalten Sie sie wieder aus, gilt der Standardumfang von Community; eine bezahlte Lizenz ist in beiden Fällen unberührt. Was gesendet wird, steht in der Datenschutzerklärung.

Zwei Dinge sollten Sie kennen, weil Sie etwas mit ihnen tun können. Das erste ist Ihre Nutzungsregister-ID: In der Testphase und auf Community zeigt die Erweiterung sie unter Show License / Activation und am Ende von What Community Includes an, wo das Auswählen der Zeile sie kopiert und die Datenschutzerklärung öffnet. Das Register kennt Ihr Gerät über einen Hash und über sonst nichts, deshalb ist diese ID der einzige Weg, zu erfragen, was es zu Ihnen enthält, es löschen zu lassen oder ihm zu widersprechen — nennen Sie sie, und wir finden Ihre Zeile; ohne sie können wir es nicht. Das zweite ist der Installationseintrag: eine Zeile, geschrieben, wenn eine Installation zum ersten Mal meldet, und aufbewahrt statt nach 90 Tagen gelöscht, mit der Installationskennung, dem Tag, dem Ort, zu dem ihre Adresse aufgelöst wurde, den Versionen und dem Betriebssystem — nicht der Adresse und nichts über Ihren Code. Nur dadurch können wir sagen, wie viele Installationen es über die Jahre gab. Beides ist in der Datenschutzerklärung vollständig beschrieben, und beides wird auf Ihre Bitte hin gelöscht.

The bottom of What Community Includes: the ways to lift the caps, and How these are counted — the row that copies your usage ledger ID and opens the privacy policy
Das Ende von What Community Includes: wie die Obergrenzen gezählt werden und die Zeile, die Ihnen Ihre Nutzungsregister-ID liefert.

19. Evaluierung & Aktivierung

Fucini Coverage Studio wird als Evaluierungs-Vorabversion ausgeliefert. Beim ersten Start werden Sie gebeten, der Evaluierung zuzustimmen, und die Testphase beginnt — während einer 14-tägigen Testphase steht jede Funktion zur Verfügung, gerechnet ab der ersten Nutzung auf dieser Installation. Es gibt kein festes Datum, nach dem irgendetwas aufhört.

Ab Version 2.2026.2 beginnt die Testphase einer neuen Installation, sobald die Erweiterung den Lizenzserver einmal erreicht hat; bis dahin läuft sie auf der Community-Stufe und sagt das auch. In einem Entwicklungscontainer oder einem Codespace beginnt keine Testphase – ein Abonnementcode, ein Schlüssel oder der 7-Tage-Pass schaltet dort den vollen Umfang frei.

Wenn die Testphase endet, wird nichts gesperrt: Die Erweiterung fällt auf die kostenlose Community-Stufe zurück. Um den vollen Umfang zurückzubekommen, aktivieren Sie — die Aktivierung verbindet sich mit dem Lizenzserver und wendet den zurückgegebenen Schlüssel automatisch an, ohne E-Mail und ohne einen Schlüssel, den Sie von Hand übertragen müssten:

Show License / Activation: the trial state, and the buttons to enter a subscription code, see the plans or request a licenceScreenshot pending — add assets/img/licence-dialog.png (see SCREENSHOTS.md).
  1. Führen Sie Fucini Coverage: Show License / Activation aus (nach Ablauf der Testphase bzw. des Schlüssels auch über die Statusleiste erreichbar) und klicken Sie auf Request License… (oder Request Renewed Key…, wenn Sie bereits aktiviert haben).
  2. Bestätigen Sie die Anfrage. Der Schlüssel wird automatisch ausgestellt, und Ihre Kontaktdaten aus einer früheren Anfrage werden wiederverwendet statt erneut abgefragt.
  3. Das war's. Der Aktivierungsschlüssel wird erzeugt und automatisch in fuciniCoverage.license.key geschrieben. Die Statusleiste wechselt kurz darauf von der Testphase zu einer aktivierten Lizenz.

Der manuelle Weg in einem Bild: Öffnen Sie das Lizenzpanel, wählen Sie Enter Key, fügen Sie den Schlüssel aus Ihrer E-Mail ein – und das Banner springt auf „Activated“.

Activating by hand: the licence panel, the activation dialog, Enter Key, the pasted key, and the banner turning to ActivatedScreenshot pending — add assets/img/activate-key.gif (see SCREENSHOTS.md).

Sollte die automatisierte Anfrage einmal fehlschlagen (keine Verbindung, Serverproblem): Führen Sie Fucini Coverage: Copy Activation Request Code aus, senden Sie den Code über die Kontaktseite oder an info@fucini.consulting, und fügen Sie den zurückerhaltenen FCK1.…-Schlüssel mit Fucini Coverage: Enter Activation Key ein (oder direkt in die settings.json):

{ "fuciniCoverage.license.key": "FCK1.…den gesamten Schlüssel einfügen…" }

Der Einstellungsname lautet fuciniCoverage.license.key (Bereich User/Global). Der Schlüssel ist an Ihr Gerät und Ihren Betriebssystem-Benutzer gebunden, kann ein Ablaufdatum haben und kann einzelne Funktionen aktivieren oder einschränken sowie die Zahl der Coverage-Ladevorgänge pro Tag begrenzen. Erscheint die Meldung „invalid for this machine“, fordern Sie aus dieser Installation einen neuen Schlüssel an — ein für ein anderes Gerät ausgestellter Schlüssel wird hier nie gültig.

In Visual Studio. In dieser Edition gibt es keine kostenlose Stufe: Ohne Abonnement wird nichts gelesen. Mit einem Abonnement entscheidet der Plan dort, was er in VS Code entscheidet — eine Funktion, die der Plan nicht enthält, wird zurückgehalten, und ihr Befehl sagt das, statt zu laufen. Auch die älteste Version, die der Lizenzserver noch unterstützt, gilt dort: Ein älterer Build meldet das einmal am Tag, mit dem Datum, an dem er aufhört zu arbeiten, und arbeitet bis dahin weiter. Offline zu sein hält einen Build nie an.

Die kostenlose Community-Stufe: ein Wochenkontingent

Community hört nie auf, Coverage anzuzeigen. Die Gutter-Markierungen, das Übersichtslineal, Hover, CodeLens, die Coverage-Ansicht, der Watch-Modus, Diff-Coverage und der Verlauf werden überhaupt nicht gezählt, und das Laden eines Tracefiles per Befehl ist lediglich auf 25 am Tag begrenzt. Gemessen wird die Ausgabe: je fünf pro Woche für das Öffnen des HTML-Berichts, das Exportieren, den Vergleich zweier Läufe, die Prüfung der Schwellenwerte und die Anzeige des annotierten Quelltexts an Ort und Stelle.

Eine Woche gehört Ihnen, nicht dem Kalender: Sie beginnt mit der ersten Nutzung und endet sieben Tage später. Ist ein Kontingent aufgebraucht, nennt die Meldung die Aktion und den Tag, an dem es wieder verfügbar ist, und nach dieser einen Meldung weist nur noch die Statusleiste darauf hin. Fucini Coverage: What Community Includes listet jedes Kontingent auf, mit dem, was verbraucht ist, und dem Zeitpunkt der Zurücksetzung, noch bevor Sie je eines ausschöpfen.

The weekly allowance: five uses of Open HTML Report across three days, a sixth refused with the day the count resets, and the week ending seven days after the first use; gutters, hovers, CodeLens and the Coverage view are never countedScreenshot pending — add assets/img/weekly-allowance.png (see SCREENSHOTS.md).
The message at a Community limit: Checking coverage thresholds, all 5 used, the day it resets, and the buttons Subscribe, 7-Day Pass and What Community IncludesScreenshot pending — add assets/img/community-limit-prompt.png (see SCREENSHOTS.md).
What Community Includes: each allowance with how much is used and the day it resets, then the features that are not includedScreenshot pending — add assets/img/community-includes-weekly.png (see SCREENSHOTS.md).

Drei Details gehören zu den kostenpflichtigen Plänen, während ihre Befunde kostenlos bleiben: Community markiert jede Zeile mit überlebenden Mutanten und sagt, wie viele es sind, aber nicht, was jeder Mutant geändert hat; es sagt, wie viele Tests eine Zeile ausgeführt haben, aber nicht deren Namen; und es zeigt den Max CRAP eines Laufs, aber nicht die Rangliste Riskiest Methods.

A mutant hover in Community: 2 mutants survived and 2 more detected on the line; what each mutant changed is part of the paid plansScreenshot pending — add assets/img/mutant-hover-community.png (see SCREENSHOTS.md).

Wenn Sie Community bereits genutzt haben, als das Wochenkontingent kam (0.2026.83), bleiben Ihre bisherigen Limits 30 Tage lang bestehen; Sie werden einmal darüber informiert, mit Datum. Die Zähler liegen auf Ihrem Rechner – im eigenen Speicher von VS Code und in ~/.fucini-coverage/, sodass ein neues VS-Code-Profil dieselbe Woche fortsetzt – und werden nirgendwohin gesendet.

Der 7-Tage-Pass

Noch nicht bereit für ein Abo? Ein 7-Tage-Pass ist alles aus Pro für eine Woche, einmal bezahlt: Nichts verlängert sich, und es gibt nichts zu kündigen. Kaufen Sie ihn auf der Preisseite (die Meldung an einem Community-Limit hat eine Schaltfläche dafür), und der Aktivierungscode kommt per E-Mail.

The 7-day pass on the pricing page: everything in Pro for one week, paid once, with the Get a 7-day pass buttonScreenshot pending — add assets/img/pricing-week-pass.png (see SCREENSHOTS.md).
  1. Führen Sie Fucini Coverage: Enter Subscription Code aus – den Befehl gibt es in der Community-Edition ebenso wie in Pro.
  2. Wählen Sie Pro und fügen Sie den Code FCB1-… aus der E-Mail ein.
  3. Das war's. Der Schlüssel wird für Sie ausgestellt und angewendet und funktioniert offline. Die Woche läuft ab der Zahlung, aktivieren Sie also gleich beim Kauf. Ist sie vorbei, kehrt die Erweiterung von selbst zu Community zurück und zeigt weiterhin Coverage an.
Enter Subscription Code, step 1: choose Pro from the list of plansScreenshot pending — add assets/img/pass-step-plan.png (see SCREENSHOTS.md).
Enter Subscription Code, step 2: paste the FCB1 code from the purchase email and press EnterScreenshot pending — add assets/img/pass-step-code.png (see SCREENSHOTS.md).

In Visual Studio. Derselbe Code aktiviert Fucini Coverage Studio für Visual Studio, 2022 und 2026: Öffnen Sie Tools → Coverage Studio → Licence…, fügen Sie den Code ein, wählen Sie den Plan, für den er gilt, und drücken Sie Activate. Das Coverage-Fenster zeigt dann Activated über dem Baum; mit dem Pfeil aufgeklappt zeigt die Zeile das Datum, bis zu dem der Schlüssel gilt, und eine Schaltfläche zu Ihrem Konto. Ein Rechner ist ein Platz: Aktivieren Sie VS Code oder Visual Studio, und der andere Editor auf demselben Rechner folgt von selbst — Visual Studio liest den Schlüssel von VS Code und VS Code den von Visual Studio —, sodass nichts zweimal eingegeben und kein zweiter Platz belegt wird. Beide halten einen Schlüssel auf dieselbe Weise am Leben: Pro Plus, Business und Enterprise melden sich zweimal täglich, und ein Pro-Schlüssel wird in der Woche vor seinem Ablauf erneuert.

Visual Studio: the Coverage window says no subscription covers this machine, and the Licence dialog takes the subscription code
Visual Studio: the Coverage window after an activation — Activated, valid until a date, and a button to the account

Auf einen neuen Rechner umziehen und Plätze verwalten

Ein Schlüssel ist an einen Rechner gebunden, ein neuer Rechner braucht also einen neuen — und Ihr Abonnement bezahlt nur so viele Rechner, wie es nennt. Geben Sie den alten selbst frei: melden Sie sich unter Abonnement verwalten an, suchen Sie den nicht mehr genutzten Platz, wählen Sie Free up und aktivieren Sie den neuen Rechner mit demselben Code. Beim Kauf von Pro wird Ihnen kein Passwort zugeschickt — Ihr Konto existiert, es hat nur noch keines. Nutzen Sie daher beim ersten Mal Passwort setzen oder zurücksetzen mit der Adresse, mit der Sie abonniert haben.

Bei Business und Enterprise laden Sie jede Kollegin und jeden Kollegen von derselben Seite aus per E-Mail ein. Jede Person erhält einen Aktivierungscode, der nur ihr gehört, und sobald sie ihn nutzt, erscheint ihre Adresse an ihrem Platz — verlässt jemand das Team, sehen Sie, welcher Platz seiner war, und geben ihn für die nächste Person frei. Eine Einladung belegt einen Platz ab dem Versand und verfällt nach 14 Tagen ungenutzt; ziehen Sie sie zurück, um den Platz sofort wiederzubekommen.

Vorabversionen testen

Neues erreicht fucini.software, bevor es den Marketplace erreicht, und Sie können darum bitten, es angeboten zu bekommen. Öffnen Sie die Coverage-Ansicht, klappen Sie den Lizenzbereich auf und drücken Sie Vorabversionen testen… — oder setzen Sie fuciniCoverage.update.preRelease. Von da an prüft die Erweiterung hier einen eigenen Vorab-Feed zusätzlich zum gewöhnlichen und bietet an, was neuer ist.

The licence panel in the Coverage view, expanded: a Pro licence valid until 2027-03-19, and the button labelled Test pre-release buildsScreenshot pending — add assets/img/licence-prerelease.png (see SCREENSHOTS.md).

Vorabversionen sind getestet, aber es sind die Builds, bei denen wir am wenigsten sicher sind — Sie würden sich freiwillig melden, zu finden, was wir übersehen haben. Mit dem Beitritt erfahren wir, dass diese Installation im Kanal ist, damit wir wissen, wie viele Menschen testen, und sagen können, was sich geändert hat; treten Sie aus, bringt Sie die nächste stabile Version auf den gewohnten Weg zurück. Es gibt nicht immer eine Vorabversion, und beizutreten, wenn es keine gibt, kostet nichts: Die Erweiterung findet einen leeren Feed, sagt nichts dazu und bietet weiter stabile Versionen an, bis eine veröffentlicht wird.

The same panel once the install has joined: an update bar offering 0.2026.84 while 0.2026.83 is running, the button now reading Leave the pre-release channel, and a line saying the install is on the channelScreenshot pending — add assets/img/licence-prerelease-joined.png (see SCREENSHOTS.md).

20. Kontakt & Lizenz

Fragen, Fehlerberichte oder alternative Lizenzbedingungen — siehe die Kontaktseite oder schreiben Sie an info@fucini.consulting. Lizenziert unter MIT mit einer Bedingung zur Namensnennung in den Release Notes; siehe auch den Notice.

21. Auf der Kommandozeile

Der Reader läuft auch ohne Editor: npm install -g fucini-coverage, kostenlos, auf Windows, Linux, WSL und macOS. fucini-coverage check coverage/lcov.info --lines 80 ist das Gate, an dem eine Pipeline fehlschlägt; summary, export, report, badge und compare tun, was die gleichnamigen Befehle der Editoren tun, und mcp stellt die sechs Werkzeuge des Abschnitts oben einem Agenten auf einem Server bereit. Er liest fucini-coverage.json, die Einstellungsdatei, die die Visual-Studio-Edition liest, sodass die Schwellenwerte einmal gesetzt werden. fucini-coverage help <command> erklärt jeden; die vollständige Seite ist fucini-coverage auf npm.

The command line on the demo: --help, summary, check with two gates passing, export as Markdown, compare against a baseline, badge, report and the MCP server's helpScreenshot pending — add assets/img/cli-demo.gif (see SCREENSHOTS.md).