VOLLEDIGE GIDS

Gebruikershandleiding

Van je eerste tracefile tot compliance-gating volgens veiligheidsnormen — alles wat Fucini Coverage Studio kan, en precies hoe je het aanstuurt.

Download de VSIX

1. Inleiding

Fucini Coverage Studio maakt van de coverage-tracefiles die je build al produceert volwaardige coverage in de editor — in VS Code en in Visual Studio. Het leest vijfentwintig formaten, normaliseert ze naar één canoniek Fucini-model, voegt meerdere runs deterministisch samen en toont het in de editor zelf — gutters, CodeLens, hover en een Covered Files-weergave — zodat er geen aparte viewer is waarvoor je je editor moet verlaten. De twee edities delen één lezer: hetzelfde rapport geeft in beide dezelfde cijfers, tot op het cijfer. Deze handleiding is geschreven vanuit VS Code; waar Visual Studio verschilt, zegt een In Visual Studio-kader hoe.

Het is ontworpen met functionele-veiligheidsworkflows in gedachten: MC/DC-coverage, coverage van regio's en C++-instantiaties, een veiligheidsgewogen samengestelde score, en een instelbaar COMPLIANT / NON-COMPLIANT-oordeel afgestemd op de denkwijzen van IEC 61508, ISO 26262 en DO-178C.

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. Installatie & vereisten

  • VS Code ≥ 1.88 — de minimale versie die deze extensie ondersteunt — of Visual Studio 2022 of 2026, Community, Professional of Enterprise (zie het kader hieronder).
  • Een coverage-tracefile die je project al produceert (zie §4).

Installeer via de Marketplace, of via een .vsix-bestand via Extensions → ⋯ → Install from VSIX…. De extensie activeert bij het opstarten en voegt een Coverage-pictogram toe aan de activiteitenbalk.

In Visual Studio. Hetzelfde product verschijnt als een tweede extensie, Fucini Coverage Studio voor Visual Studio, voor Visual Studio 2022 en 2026 — Community, Professional en Enterprise. Het gebruikt de eigen code coverage van Visual Studio niet: in Visual Studio 2022 is dat een Enterprise-functie, dus op Community en Professional is dit de enige coverage die de IDE laat zien. Installeer de .vsix door hem te openen — de VSIX Installer vraagt welke Visual Studio — of via Extensions → Manage Extensions; de extensie laadt wanneer een solution of een map opent. Het Coverage-venster heeft de Microsoft Edge WebView2 Runtime nodig, die Windows 11 en Visual Studio 2026 al meebrengen; de markeringen in de editor werken zonder.

3. Snel starten

Wil je zien hoe het werkt voordat je je eigen project aansluit? Download het demoproject (~6 KB — een klein C-project met een kant-en-klare lcov.info):

  1. Pak het ergens uit en open vervolgens coverage-studio-demo.code-workspace in VS Code (File → Open Workspace from File…).
  2. Installeer Fucini Coverage Studio als je dat nog niet hebt gedaan (zie §2 hierboven).
  3. De eigen .vscode/settings.json van de workspace verwijst al naar de meegeleverde coverage/lcov.info, dus gutters en de weergave Covered Files verschijnen zodra de extensie wordt geactiveerd — geen Load Coverage-stap nodig.
  4. Wil je het tracefile zelf opnieuw genereren (bijv. met een andere compiler)? Voer scripts/gen-coverage.sh uit (of .ps1 op Windows) — zie de eigen README.md van de workspace voor de beschikbare compilerdoelen.

In Visual Studio. Open een solution, of een map (File → Open → Folder, zo open je een CMake-project) — de demo hierboven opent als map, en zijn .vscode/settings.json wordt daar ook gelezen. Een rapport op de plek die de instellingen noemen wordt vanzelf geladen en het Fucini Coverage-paneel van het Output-venster zegt welke bestanden; anders Tools → Coverage Studio → Load Coverage File…, eenmalig — het wordt onthouden. Open een bronbestand en kies Show Coverage in Editor: rood is een regel die nooit liep, amber een beslissing die maar één kant op ging, en Ctrl+Shift+U, N springt naar de volgende ongedekte regel. View → Other Windows → Coverage is de boom met de cijfers van elk bestand en één score over alles, die de statusbalk toont voor de run en voor het bestand waarin je zit. Tools → Coverage Studio → Getting Started opent deze stappen als een pagina met een knop voor elk; de eerste keer opent hij vanzelf.

  1. Genereer een coverage-tracefile met je normale testworkflow.
  2. Opdrachtenpalet (Ctrl+Shift+P) → Fucini Coverage: Load Coverage. Met watch.enabled ingeschakeld (de standaard) wordt een overeenkomend bestand automatisch geladen.
  3. Open een bronbestand met coverage: de statusbalk toont zijn percentage, de weergave Coverage vult zich, een regel aanwijzen toont zijn treffercount, en de run verschijnt in het native paneel Test Coverage. Balken op ongedekte regels, een heatmap van trefferaantallen en inline ×N-aantallen zijn op één instelling afstand (editorGutter.mode, hitCounts.inline).
Covered (green) and uncovered (red) gutters in the editorScreenshot pending — add assets/img/gutters.png (see SCREENSHOTS.md).

4. Tracefiles genereren

Elk van de volgende wordt automatisch gedetecteerd bij het laden:

Volledige kant-en-klare recepten per compiler — waaronder Swift, Rust, Go, Python, .NET, PHP en meer — vind je op de pagina Coverage-recepten: 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 is de rijkste invoer — naast regels, branches en functies bevat het ook regio's, MC/DC en C++-template-instantiaties.

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
FormaatTypisch bestandExtra metrieken
LCOVlcov.inforegels, takken, functies
llvm-cov JSONcoverage.json+ regio’s, MC/DC, instantiaties
Cobertura XMLcoverage.xmlregels, takken
JaCoCo XMLjacoco.xmlregels, takken, functies
Istanbul / nyccoverage-final.jsonstatements, takken, functies
SimpleCov.resultset.jsonregels
Clover XMLclover.xmlregels, takken, functies
OpenCover XMLcoverage.opencover.xmlregels, takken, functies
coverage.py JSONcoverage.jsonregels, takken
gcov / gcovr JSONcoverage.jsonregels, takken, functies
Go coverage profilecoverage.outregels
SonarQube genericcoverage.xmlregels, takken
GNATcoverage XML (Ada)*.xmlregels, takken, MC/DC
BullseyeCoverage XMLcoverage.xmlregels, conditie/decisie
Visual Studio*.coveragexmlregels, takken
Coveralls JSONcoveralls.jsonregels, takken
Xcode xccov JSONcoverage.jsonfuncties en bestandstotalen — geen data per regel
gcov plain text*.gcovregels, takken, functieaanroepen
VectorCASTcoverage.xmlregels, takken, MC/DC-paren, functies, functieaanroepen
Testwell CTC++*.txtregels, conditie/decisie
Lauterbach TRACE32*.xmlstatements, decisies, condities, MC/DC, functies, aanroepen, objectcode
EMMA XML (Java)coverage.xmlregels
UCIS / Aldec UCDB*.xmlstatements, beslissingstakken
NCover XMLCoverage.xmlregels, functies
dotCover DetailedXMLdotCover.xmlregels, functies
PIT (mutation)mutations.xmlmutatiescore — geen dekking
Stryker (mutation)mutation-report.jsonmutatiescore — geen dekking

Een native C++-project, gemeten vanuit Visual Studio

In Visual Studio. De eigen coverage van Visual Studio voor een C++-project was alleen voor Enterprise, en de gratis OpenCppCoverage-plugin die het gat vulde is uit de lucht. Tools → Coverage Studio → Run Native Project with Coverage neemt het startproject — een .vcxproj —, vraagt MSBuild waarheen het bouwt en met welke toolset, en meet het op een van twee manieren. Op de ClangCL-toolset, met LLVM's llvm-profdata en llvm-cov op de machine (het onderdeel C++ Clang tools for Windows van Visual Studio brengt ze mee), bouwt het het project opnieuw naar coverage\native\ met -fprofile-instr-generate -fcoverage-mapping, via een props-bestand dat MSBuild als eerste moet importeren — aan het project verandert niets —, draait het programma met LLVM_PROFILE_FILE gezet, voegt het profiel samen en exporteert coverage\native\lcov.info, exact tot op de regio. Op elke andere toolset, met OpenCppCoverage geïnstalleerd, bouwt het het project zoals het is — een Debug-build heeft de PDB's — en draait het onder OpenCppCoverage, dat coverage\native\opencppcoverage.xml schrijft. Elk commando gaat naar het Fucini Coverage-paneel, en het rapport wordt geladen en onthouden zoals dat van een testrun. Een project dat niet gemeten kan worden, krijgt te horen waarom en wat er te installeren valt. MSBuild 17.8 (Visual Studio 2022 17.8) of nieuwer, voor de vraag die het stelt.

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 op een C++-project — de build, de run, en de editor die zich vult.

5. Laden & detectie

Standaard scant de extensie vanaf de root van de workspace. Stuur dit nauwkeuriger met twee instellingen:

{
  "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"
  ]
}
  • Elk item in paths is relatief ten opzichte van defaultLocation (of de workspace-root indien niet ingesteld).
  • Een item met * wordt recursief doorzocht; een kale bestandsnaam komt alleen rechtstreeks in de basismap overeen.
  • Wanneer paths leeg is, zoekt de extensie eerst naar coverage.json, dan naar lcov.info, en laadt wat het eerst vindt.
  • Pick Coverage File gebruikt de bestanden die je kiest in plaats van deze paden — elke keuze komt erbij en alle worden samengevoegd — totdat je ze ontlaadt of deze instellingen wijzigt.
  • Variabelen — elke padinstelling breidt ${workspaceFolder}, ${workspaceFolderBasename}, ${userHome}, ${env:NAME}, ${command:id} en ${config:section.key} uit. Een variabele die de extensie niet kent, blijft staan zoals geschreven, zodat een typfout in het detectielog verschijnt als het pad waarnaar is gezocht in plaats van te verdwijnen. ${command:id} voert dat commando eerst uit — alleen in een vertrouwde werkruimte en maximaal vijf seconden — zodat ${command:cmake.buildDirectory} de gekozen CMake-kit volgt.
  • URL-items — een http(s)://-item wordt bij elke lading naar de opslag van de extensie opgehaald en van daaruit geladen; de Coverage-weergave noemt de URL. Elke ophaalactie is conditioneel (ETag / Last-Modified), dus een ongewijzigd artefact downloadt niets, en wanneer het ophalen mislukt, wordt in plaats daarvan de laatst gedownloade kopie geladen, met de reden in de uitvoer. remote.headers voegt Name: value-headers toe met uitgebreide variabelen, remote.refreshMinutes haalt op een timer opnieuw op, en een #lcov.info-fragment noemt het formaat wanneer de URL zelf niet op een bestandsnaam eindigt.
  • Ignore-globs — fuciniCoverage.ignore laat hele bestanden (meegeleverd, gegenereerd, van derden) bij het laden uit de run vallen, zodat elke weergave, poort en export zonder ze telt; het laadresultaat zegt hoeveel er zijn weggelaten en de uitvoer noemt ze. Patronen komen overeen met het werkruimte-relatieve en het absolute pad, en een patroon zonder / komt overeen met een map- of bestandsnaam op elke diepte, net als .gitignore.
  • Multi-root-werkruimten — elke map wordt op haar eigen voorwaarden gedetecteerd: defaultLocation, paths, pathRemap, ignore, watch.* en remote.* worden per map gelezen, zodat de eigen .vscode/settings.json van een map of haar item in het .code-workspace geldt, en ${workspaceFolder} in een item de eigen map van dat item betekent. De tracefiles van elke map worden tot één run samengevoegd, de Coverage-weergave groepeert de bestanden per map, en een map die aan de werkruimte wordt toegevoegd of eruit wordt verwijderd, laadt de dekking vanzelf opnieuw.
  • Opnieuw laden na een taak — watch.reloadAfterTasks noemt taken (een label uit tasks.json, of source: name zoals de lijst Run Task het toont) waarvan het einde de dekking opnieuw laadt, of watch.enabled nu aanstaat of niet — voor builds die de watcher niet kan volgen. Een absoluut item in paths buiten de werkruimte wordt ook gepeild, zodat een bestand dat daar verschijnt wordt geladen.
  • Voortgang die je kunt annuleren — een lading van tien of meer tracefiles, of van 8 MB of meer, draait onder een voortgangsmelding met een knop Annuleren die het bestand noemt dat wordt gelezen en de fase; een kleinere laat alleen de statusbalk draaien. Annuleren laat de vorige run geladen en zegt dat.

Sinds 1.2026.6 mag een absoluut item ook een jokerteken bevatten: ${workspaceFolder}/build/coverage-merged/*.lcov.info laadt elk zo’n bestand in die map, en ** staat voor elke diepte. De mappen vóór het eerste jokerteken zijn waar het kijkt, en ze worden bewaakt, zodat een rapport dat een build daar schrijft vanzelf wordt geladen. De Visual Studio-editie leest zo’n item op dezelfde manier, en sinds 1.2026.5 wordt een relatief jokerteken ook daar op elke diepte gezocht, zoals hier altijd al het geval was.

Als er geen paths is geconfigureerd, wordt de eerste van de bekende rapportnamen geladen die onder de basismap wordt gevonden. Eerst de vier waarnaar altijd al werd gezocht – coverage.json, lcov.info, coverage.out, clover.xml – daarna, sinds 0.2026.83, jacoco.xml, coverage.xml, cobertura.xml, coverage.cobertura.xml, coverage.opencover.xml en coverage-final.json, en vervolgens de plaatsen waar standaardconfiguraties naartoe schrijven: coverage/ (nyc, Jest, vitest, PHPUnit, SimpleCov), target/site/jacoco/jacoco.xml (Maven), build/reports/jacoco/test/jacocoTestReport.xml (Gradle) en TestResults/*/coverage.cobertura.xml (dotnet test). Zo toont een Java- of .NET-project zijn dekking meteen bij het eerste openen, zoals een lcov-project dat altijd al deed.

Sinds 1.2026.3 heeft een .NET-solution nog minder nodig: de map TestResults/<run>/ van elk testproject hoort bij de bekende plaatsen, niet alleen die van de werkruimtemap zelf, en de <user>_<machine>_<date>.cobertura.xml van Microsofts collector wordt naast Coverlets coverage.cobertura.xml gevonden — een solution waarvan de tests in de Test Explorer van Visual Studio zijn gedraaid, toont dus haar dekking bij het eerste openen, elke run-map wordt geladen, en de samenvoeging houdt per bestand het woord van de nieuwste run. En fuciniCoverage.ignore.generated, standaard aan, laat designer- en gegenereerde bestanden — *.Designer.cs, *.g.cs, *.generated.cs, *.razor.g.cs, AssemblyInfo, globale usings, Migrations/ en obj/ — buiten elk totaal, elke pagina en elke export voordat ignore wordt toegepast, zodat een gegenereerde tabel die niemand test de solution niet haar gate kost.

In Visual Studio: dekking na elke testrun. Draai uw tests zoals altijd. Tools → Coverage Studio → Collect Coverage in Test Explorer… zet één .runsettings met Microsofts Cobertura-collector naast de solution. Visual Studio pikt hem op wanneer Tools → Options → Test → Auto detect runsettings files aan staat; anders selecteert u hem eenmalig onder Test → Configure Run Settings. Vanaf dan schrijft elke run een rapport onder het testproject, en de bewaking van de solution laadt het zodra het verschijnt, samengevoegd met wat de instellingen verder noemen — vanuit de Test Explorer, een terminal of een script, om het even. Niets haakt in op de Test Explorer, dus Visual Studio 2026 en Microsoft.Testing.Platform werken zoals ze zijn. Run Tests with Coverage is het commando uit VS Code: het herkent dotnet test, vitest, jest, pytest, go, cargo, maven, gradle, phpunit en ctest, draait de tests met dekking aan in het Output-venster en laadt wat ze hebben geschreven; een testproject zonder coverlet.collector wordt gedraaid met de collector die de test-SDK meelevert, en testRun.skipWhenTestsFail houdt de laatste goede dekking op het scherm wanneer een run rood eindigt.

Een CI-artefact achter een token, elk kwartier opnieuw gecontroleerd — het token blijft in de omgeving, nooit in 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).

Een herlaadbeurt is met opzet stil — een dialoog na elke build is een vraag met één antwoord. Wat niet stil is, is het Coverage-pictogram: zolang de weergave niet voor u staat, draagt het het aantal tracefiles dat opnieuw is gelezen, en de tooltip noemt ze bij naam. Open de weergave en de teller is 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).

Bestanden die nooit mogen meetellen, wat de tracefile er ook over zegt:

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

Opnieuw laden wanneer de testtaak eindigt, voor een build die de bestandswatcher niet kan volgen — een run die een gesymlinkte uitvoerboom vervangt, een rapport op een netwerkshare, een dekkingsstap die zijn bestand nabewerkt:

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

6. Runs samenvoegen

Elke bestaande paths-vermelding wordt geladen en samengevoegd tot één run. Het samenvoegen is deterministisch — het resultaat hangt niet af van de laadvolgorde — en een bestand dat door meer dan één tracefile is gemeten neemt zijn cijfers van het tracefile met de nieuwste mtime op schijf: de eigen herhaalde run van een module vervangt wat een bredere, oudere run erover zei, in plaats van eraan toe te voegen. De dekkingsweergave laat zien wat dat heeft gedaan: elke bestandsrij noemt het tracefile waaruit haar cijfers komen, de badge is omrand waar die cijfers een ouder rapport hebben overstemd, elke tracefile-rij boven de boom telt hoeveel van haar bestanden zijn overstemd of andere hebben overstemd, en een klik op een tracefile-rij licht haar bestanden in de boom op tot ze opnieuw wordt aangeklikt (coverageView.mergedMarks schakelt de omranding en de markering uit).

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).

Een samengevoegde run kan meer bevatten dan de zes klassieke metrieken, elk afkomstig uit het rapport dat ze meet: functieaanroepen, objectcode en een mutatiescore naast regels, functies, regio’s, takken, MC/DC en instantiaties. De Coverage-weergave toont een kolom voor elke metriek die de run bevat – en geen voor een metriek die ontbreekt – gesorteerd op het gewicht dat elke metriek in uw score heeft, de zwaarste eerst, bij elke breedte — wat niet past schuift opzij in plaats van te verdwijnen. Sleep de weergave naar het onderste paneel en ze wordt een tabel. De kaarten in de statusbalk, het HTML-rapport en de CSV- en Markdown-exports volgen dezelfde regel: wat een rapport bevat, wordt getoond; wat het niet bevat, wordt weggelaten in plaats van als nul afgedrukt.

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: het Coverage-venster over een map met elf projecten — ingeklapt tot één rij per project met zijn balk, dan uitgeklapt, dan een bestand dat eruit is geopend.

Uit welk rapport een bestand komt

Wanneer meerdere geladen rapporten hetzelfde bestand meten, wint het nieuwste het in zijn geheel — terecht wanneer de eigen herhaalde run van een module vervangt wat een oudere, bredere run zei. Onterecht wanneer de rapporten dezelfde code met opzet meten: dan springt de editor bij elke build tussen hen heen en weer, en vertelt elk maar een deel van het verhaal. coverageFile.sources zegt wat er in plaats daarvan moet gebeuren, per bestand. Drie situaties vragen erom:

  • Eén rapport is het betere. De coverage.json van llvm-cov bevat MC/DC, een gcov.info van GCC uit dezelfde build alleen regels en branches: kies coverage.json, en houd de andere voor de paar bestanden die alleen GCC bouwt.
  • Meerdere testsuites van één build. Unittests, integratietests en hardware-in-the-loop schrijven elk een rapport; elk op zich mist regels die de andere uitvoerden. Combineren, union: een regel is gedekt waar een willekeurig rapport hem uitvoerde, en de aantallen worden opgeteld.
  • Eén codebase, twee compilers. Dezelfde bronnen, gebouwd door clang en door GCC, nemen verschillende paden door toolchainspecifieke code — hier een intrinsic, daar een draagbare fallback — en elk rapport zegt dat de andere helft nooit liep. Combineren, agree: een regel is alleen gedekt waar elk rapport dat hem meet hem uitvoerde, en de regels waarover de rapporten het oneens zijn, worden blauwgroen gemarkeerd. Dat is de vraag die een controle over compilers heen stelt: wat heeft elke build die ik lever werkelijk uitgevoerd?

De regels schrijf je zelden met de hand. Klik met de rechtermuisknop op een bestand in de dekkingsweergave en kies Choose Coverage Source... (of voer Choose Coverage Source for This File... uit op het open bestand): de lijst toont elk rapport dat het bestand meet, elk met zijn eigen regels, branches en MC/DC, en daarna Combine them — agree en Combine them — union; kies er een en geef aan of die geldt voor het bestand, de map ervan of een patroon. Clear Coverage Source for This File... haalt de regel weer weg. In de instellingen is elke regel een glob over de bestanden, een glob over het rapport (een patroon zonder / komt overeen met de bestandsnaam van het rapport, {a,b} noemt er meerdere) en, om te combineren, "combine": "agree" of "union". De eerste regel waarvan de bestanden overeenkomen en waarvan het rapport het bestand meet, beslist; een bestand dat maar één rapport meet, wordt daar nooit van afgenomen. Branches, MC/DC en regio's van een gecombineerd bestand komen uit het rapport dat daar het rijkst aan is. coverageFile.mergeStrategy: "order" beslist over de bestanden waarvoor geen regel geldt op volgorde van coverageFile.paths in plaats van op tijd.

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

Wat je ziet: de rij van het bestand in de dekkingsweergave noemt het rapport waar de cijfers vandaan komen, of, gecombineerd, elk rapport en de modus met ≠ n voor de betwiste regels. De gutter en de Annotated Source markeren die regels blauwgroen en zeggen welk rapport ze hoe vaak uitvoerde. De hoverkaart van de statusbalk noemt de bron van het open bestand en, voor de hele run, de geldende regels en hoe over de andere bestanden is beslist. samples/c-cross-check in de demo is het geval met twee compilers, klaar om te openen. Visual Studio doet dit allemaal ook: Choose Coverage Source... op een rij van de dekkingsweergave, en Choose en Clear Coverage Source for This File... onder Tools > Coverage Studio.

Bronnen kiezen en combineren hoort bij de betaalde edities. In Community wint het nieuwste rapport elk bestand, zoals zonder regel, en van een regel in de instellingen wordt gemeld dat hij niet wordt gebruikt, in plaats van dat hij stilzwijgend wordt genegeerd.

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... op bits.c vanuit de dekkingsweergave — het rapport van clang, dat van GCC, of beide gecombineerd.
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: van agree naar union in twee klikken — de betwiste regels blijven blauwgroen, de cijfers veranderen.
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: hetzelfde vanuit het rijmenu van de dekkingsweergave — de rapporten, dan hoe ver de regel reikt, dan het opnieuw geladen bestand.
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 en GCC gecombineerd met agree — de rij zegt ≠ 4, en de vier regels die maar één build uitvoerde, zijn blauwgroen.
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
Hetzelfde bestand gecombineerd met union: elke regel die een van beide builds uitvoerde, is gedekt, zodat bits.c 100% van zijn regels haalt — en de regels waarover de builds het oneens zijn, blijven blauwgroen.
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
De Annotated Source noemt de combinatie onder de titel, en elke blauwgroene rij hoe vaak elk rapport haar uitvoerde.
The status bar's hover card for bits.c, ending with the coverage source: both reports, combined by agree, disagreeing on four lines
De hoverkaart van het bestand in de statusbalk zegt waar de cijfers vandaan komen; de kaart van de run telt de bestanden waarover elke regel besliste.
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... vanuit een rij van de dekkingsweergave — dezelfde rapporten en dezelfde twee manieren om ze te combineren; de statusbalk noemt de combinatie.

7. Pad-remapping

CI legt vaak absolute paden van de build-machine vast die niet op je werkstation bestaan. Herschrijf ze met geordende regels:

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

Regels worden op volgorde toegepast; de eerste overeenkomst wint per prefix. Gebruik dit om verschillen tussen Windows/Unix-scheidingstekens op te lossen of een containerpad naar je checkout te mappen.

Je hoeft de regel zelden zelf te schrijven. Het meest voorkomende ‘het is geladen maar er licht niets op’ is een tracefile waarvan de paden uit een container of een CI-checkout komen (/build/src/a.c, /home/runner/work/repo/repo/src/a.c, C:\agent\_work\1\s\src\a.c) terwijl de werkruimte src/a.c heeft. Wanneer een lading bestanden zonder overeenkomst achterlaat, zoekt de extensie de bestandsnamen op in de werkruimte, leidt de prefixregel af die de meeste ervan verklaart, logt die als [FUCINI_REMAP_002], en biedt het laadresultaat Apply Suggested Remap aan — één klik voegt de regel toe aan fuciniCoverage.pathRemap en laadt opnieuw. Suggest Path Remap Rule voert dezelfde analyse op aanvraag uit vanuit het palet. Zonder de klik wordt er niets geschreven.

Een to mag ${workspaceRoot} gebruiken, dat staat voor de werkruimtemap waarin de tracefile zich bevindt; in een multi-root-werkruimte probeert het eerst die map, daarna elke andere map die het bestand blijkt te hebben. De regels zelf worden per map gelezen, zodat elke root van een multi-root-werkruimte haar eigen regels kan hebben.

8. Coverage in de editor

  • Gutters & liniaal — standaard toont de eigen gutter van de editor alleen bevindingen: MC/DC-balken, driehoeken sinds de vorige run, stippen op bewerkte regels. editorGutter.mode voegt balken op alleen ongedekte regels of een heatmap van trefferaantallen toe (hieronder); de kleurgecodeerde weergave van een heel bestand is de Annotated Source.
  • Functie-CodeLens — coverage % boven elke functie; klik om naar de eerste ongedekte regel te springen. In- of uitschakelen met codeLens.enabled.
  • Branch- & MC/DC-hover — beweeg over een beslissingsregel voor per-tak genomen/niet-genomen aantallen en een per-conditie vectortabel. Schakel een gekleurde margebalk in met mcdcGutter.enabled.
  • Waarschuwingen voor dode code — functies met meetbare regels en nul coverage worden gemarkeerd in het Problems-paneel (deadCode.enabled).
  • Next / Previous Uncovered — spring tussen gaten.
  • Statusbalk — een run-breed item $(dashboard) NN% en een item per bestand, beide kleurgecodeerd op basis van de samengestelde score; beweeg erover voor een volledige metrics-tabel.
  • Badges in de Verkenner — dekkingsbadges per bestand en per map, met de uitsplitsing per metriek bij aanwijzen. Standaard uit: zet ze aan met explorerBadges.enabled.
  • Sinds de vorige run — een rode driehoek op elke regel die in de vorige run werd uitgevoerd en in deze niet, een groene voor het omgekeerde, met de overzichtsliniaal en de raakaantallen bij aanwijzen.
  • Bewerkte buffers — elke markering, hover en CodeLens beweegt mee met de tekst terwijl je bewerkt, en verdwijnt van een herschreven regel, waar een grijs puntje zegt waarom.
  • Inline trefferaantallen — hitCounts.inline schrijft ×12 achter elke regel waarop een statement begint, ×0 inbegrepen: het getal dat altijd al bij aanwijzen te zien was, zonder aan te wijzen. Toggle Inline Hit Counts schakelt het om; het statusbalkmenu biedt het aan als Tonen of Verbergen, wat van toepassing is.
  • Problems-items per regel — problems.perLine zet een Information-diagnose, met een kronkellijn in de editor, op elk aaneengesloten blok regels dat nooit liep in een open document (een dode functie van veertig regels is één item, niet veertig) en, als uncoveredAndPartial, op elke regel waarvan een tak nooit is genomen. De items volgen hun regels terwijl je bewerkt en verdwijnen wanneer het document sluit; het item per bestand achter problems.enabled is ongewijzigd.
  • Regelkleur — lineHighlight legt een doorschijnende kleur achter de regels zelf voor wat de gutter markeert (uncovered, of heatmap ook voor de uitgevoerde regels). Een eigen instelling, zodat de gutter schoon kan blijven terwijl de gaten gekleurd worden, of andersom.
  • Overzichtsliniaal — overviewRuler beslist over het streepje in de schuifbalk los van de gutter: follow (met de balken mee, zoals eerder), uncovered (altijd, dus de gutter kan uit terwijl de schuifbalk de gaten in het bestand nog steeds in kaart brengt) of off.
  • Welk tracefile een regel dekte — met meerdere samengevoegde rapporten eindigt de tooltip met het trefferaantal met Gedekt door: en elk rapport dat die regel dekte, inclusief de suitenaam uit TN: in lcov; een klik op een tracefile-rij in het Coverage-paneel licht de regels op die het bijdroeg, in elke open editor.
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).

Guttermodi in de editor

editorGutter.mode bepaalt wat de eigen gutter van de editor over dekking toont, bovenop de bevindingen die hij altijd toont. off (de standaard) is alleen die. uncovered zet een balk op elke regel die nooit liep en een amberkleurige op elke regel met een tak die nooit is genomen, en niets op gedekte regels, zodat een groene muur de drie rode niet verbergt. coverage voegt een groene balk toe op elke gedekte regel, zodat het hele bestand rood, amber en groen leest in de kleuren van de kleurschaal. heatmap voegt in plaats daarvan een warme tint toe op elke uitgevoerde regel, heter naarmate hij vaker liep — hij toont hoe vaak een regel liep, niet of hij gedekt is, dus een bestand op 100% is daar geel tot bruin, nooit groen. Choose Editor Gutter Mode... kiest er een vanuit het palet of het statusbalkmenu; de modusknop rechts in de statusbalk, of Alt+G, gaat met één druk naar de volgende (statusBar.showModeToggle verbergt de knop). Beide schrijven de instelling. Het voorbeeld zet de balken op ongedekte regels en de inline aantallen samen aan:

{
  "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: de modus coverage — groen waar een regel volledig liep, amber waar een tak nooit werd genomen, rood waar niets liep. Het statusbalkitem van het bestand noemt het rapport waar de cijfers vandaan komen; de modusknop ernaast zegt Coverage.
Alt+G pressed four times: heatmap, off, uncovered and back to coverage
In VS Code: vier keer Alt+G — heatmap, off, uncovered en terug naar 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) op Quote.cs.

De heatmap is relatief ten opzichte van het bestand. De tint van een regel vergelijkt de teller ervan met de heetste regel van hetzelfde bestand, op een logaritmische schaal, in vijf stappen – zodat een lusinhoud die duizend keer is uitgevoerd en een functie die twee keer is uitgevoerd allebei zichtbaar zijn, in plaats van dat de ene de andere overstemt, en een bestand waarin alles precies één keer is uitgevoerd gelijkmatig warm is in plaats van gelijkmatig flets. In een donker thema loopt het kleurverloop van gedempt olijfgroen naar fel oranje, in een licht thema van lichtgeel naar bruin: in beide gevallen betekent meer kleur meer uitvoeringen, en rood blijft voorbehouden aan regels die nooit zijn uitgevoerd. lineHighlight: "heatmap" legt dezelfde tinten als een waas achter de code, en hitCounts.inline schrijft de exacte teller achter de regel.

{
  "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).

De kleuren zijn van jou. colorScale.lowColor, midColor en highColor bepalen het rood, amber en groen van de gutter, de achtergrondkleuren en elk percentage; heatmap.colors en heatmap.colorsDark bevatten de vijf tinten van de heatmap voor een licht en een donker thema, van de regel die het minst liep tot die het meest liep. De instellingenpagina toont het resultaat voordat er iets is opgeslagen: onder Colour scale blijft een voorbeeld in beeld terwijl de rijen voorbij scrollen — het kleurverloop met zijn twee draaipunten, een paar percentages in hun kleuren, en een kleine lichte en een kleine donkere editor, gekleurd in de modus coverage en in de heatmap — en het wordt opnieuw getekend zodra een kleur is gekozen.

{
  "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: twee kleuren ingetypt op de instellingenpagina — het voorbeeld wordt elke keer opnieuw getekend.
Visual Studio: the same settings page and the same colour preview
In Visual Studio: dezelfde pagina, hetzelfde voorbeeld.

Het deel van een regel dat nooit is uitgevoerd

Een regel is gedekt of niet, en de waarheid ligt er vaak tussenin: return x > hi ? hi : x; is uitgevoerd, de hi-arm ervan nooit. Met lineHighlight ingeschakeld wordt het nooit uitgevoerde deel van een uitgevoerde regel in de editor gekleurd, voor elk formaat dat kolombereiken bevat (llvm-cov, Istanbul, Go, dotnet-coverage) – dezelfde stukken die de geannoteerde broncode markeert. Alleen op regels die zijn uitgevoerd: een regel die nooit is uitgevoerd, is al in zijn geheel gemarkeerd. Een C++-template geldt als uitgevoerd waar een willekeurige instantiatie het heeft uitgevoerd; wat elke instantiatie afzonderlijk deed, is wat de instantiatiemetriek rapporteert.

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).

Welke tests deze regel hebben uitgevoerd

Sommige rapporten zeggen niet alleen dat een regel is uitgevoerd, maar ook welke tests dat deden: coverage.py, geschreven met coverage json --show-contexts en dynamic_context = test_function in .coveragerc, OpenCover, verzameld met -coverbytest, en een lcov-tracefile geschreven met één sectie per test (TN:), waarvan de secties worden opgeteld tot één record met een test per regel. Beweeg de muis over het begin van een regel, waar de hitteller staat, en de tests worden genoemd — ingekort tot klasse en methode, de eerste vijf bij naam en de rest als aantal; de CodeLens van de functie zegt hoeveel tests haar hebben uitgevoerd. Show Tests That Ran This Line — de Command Palette, het contextmenu van de editor, in Visual Studio Tools → Coverage Studio of Ctrl+Shift+U, T — somt ze op, de drukste eerst, en opent de test die je kiest waar hij in de werkruimte geschreven staat. Een dotnet test-run kan niet zeggen welke test wat uitvoerde; zet testRun.perTest aan en Run Tests with Coverage somt de testklassen op en draait ze één voor één, elk rapport gelabeld met zijn klasse, zodat de hover, de lens en het commando ook voor .NET antwoord geven. De informatie wordt per bestand bewaard en overleeft dus het samenvoegen met een rapport dat niets over tests weet.

{
  "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: de lijst, de drukste eerst, en de test geopend waar hij geschreven staat.
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 op regel 62 van Quote.cs — de test die hem uitvoerde, en Go to Test die hem opent.

Geslaagd of gefaald, op de markeringen

Een gedekte regel ziet er hetzelfde uit, of zijn test nu slaagde of niet. Waar het rapport zegt welke tests een regel uitvoerden en het resultatenbestand van de runner zegt hoe ze afliepen, krijgt een regel die door een falende test is uitgevoerd een rode balk aan het begin en een streep in de overzichtsliniaal; de hover noemt de falende tests, en Show Tests That Ran This Line schrijft failed naast elk ervan. Als een test rood is, kijk je in de code waar hij doorheen ging. De resultaten worden bij elke lading gelezen uit de map van elk rapport — elke .trx, en de namen waaronder JUnit-resultaten worden geschreven (TEST-*.xml, junit*.xml, test-results*.xml) — en uit testResults.paths, als paden of globs relatief aan de map. Run Tests with Coverage vraagt dotnet test om een test-results.trx naast het rapport, zodat er niets hoeft te worden ingesteld wanneer testRun.perTest aan staat. testResults.enabled zet het lezen uit.

{
  "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: een rode test — de rode balk op de regels die hij uitvoerde, de hover die hem noemt, en Show Tests That Ran This Line dat er failed naast schrijft.

De tests die door een wijziging worden geraakt

Een volledige run beantwoordt traag wat Run Tests Affected by My Changes… meteen beantwoordt: welke van alle tests gingen door de code die ik net heb bewerkt? Aan git wordt de diff van de working tree tegenover testImpact.baseRef gevraagd — standaard HEAD, dus wat nog niet is gecommit; origin/main voor alles wat de branch wijzigt — en de tests die een gewijzigde regel uitvoerden, worden opgesomd, de test die het meeste van de wijziging uitvoerde eerst. Een test kiezen opent hem. Waar de rapporten uit een run per test komen (testRun.perTest), draait het eerste item alleen die tests, elke klasse naar haar eigen rapport, zodat de rapporten van alle andere klassen blijven staan en de totalen die van de hele suite blijven. Een test die alleen regels onder een invoeging of een verwijdering uitvoerde, staat er ook bij: zijn rapport zou anders de verkeerde regels noemen.

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: een bewerking, Run Tests Affected by My Changes…, de lijst met vooraan de test die het grootste deel van de wijziging uitvoerde, en de run van alleen die tests.

De minste tests die nog elke regel uitvoeren

Show Minimal Test Set… beantwoordt twee vragen uit dezelfde regels per test: welke paar tests nog elke regel zouden uitvoeren die de suite uitvoert — voor de snelle run vóór een commit — en welke tests geen regel uitvoeren die een andere niet al uitvoert. De gekozen tests komen eerst, elk met de regels die hij toevoegt en de regels die alleen hij uitvoert; dan de rest, elk met de aantekening dat hij niets toevoegt. Er wordt gretig gekozen — de test die het meest uitvoert, dan de test die daar het meest aan toevoegt — dus de keuze ligt dicht bij de kleinste set en is elke keer dezelfde. Overbodig naar regels is niet overbodig naar wat een test controleert: een test die geen regel toevoegt, kan nog steeds de enige zijn die een waarde controleert die deze regels opleveren. De lijst zegt waar je moet kijken wanneer een suite wordt uitgedund, nooit wat je moet verwijderen.

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… — de gekozen tests, dan de tests die niets toevoegen.

Deze test draaien, met dekking

Zet de cursor in een test en voer Run This Test with Coverage uit — de Command Palette, het contextmenu van de editor, in Visual Studio Tools → Coverage Studio of Ctrl+Shift+U, R — en alleen die test draait met dekking aan: de testmethode waarin de cursor staat, of de testklasse of het describe-blok wanneer hij tussen methoden staat, of het bestand wanneer hij boven elke klasse staat. Wat onder de cursor staat wordt uit de tekst gelezen, dus het werkt voor C#, VB en F# ([Fact], [Test], [TestMethod] en dergelijke), JavaScript en TypeScript (it, test, describe) en Python (def test_…), welke taaldienst er ook geïnstalleerd is. Het recept van de map wordt ertoe versmald — dotnet test --filter "FullyQualifiedName~…", jest of vitest <file> -t "…", een pytest-node-id — en wat het schreef wordt geladen als elke run; een runner die niet te versmallen is, zegt dat, en Run Tests with Coverage draait ze allemaal.

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: één test, één run, de geteste klasse licht op.
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 een [Fact] — de run in de lijst Tracefiles, de regels boven de methoden zeggen dat één test de code uitvoerde.

Go en Rust. In een Go-bestand draait de func TestXxx onder de cursor (of Fuzz…, Example…) in zijn eentje, in zijn eigen package en op zijn exacte naam — go test ./pkg/calc -run "^TestTotal$" — en buiten een test draait het package van het bestand. In een Rust-bestand draait de #[test]-functie op haar pad in de crate met --exact; met de cursor in een mod en in geen enkele test draaien de tests van die module; een integratietest onder tests/ draait in zijn eigen binary (--test api). Een runner krijgt alleen bestanden van zijn eigen taal: een TypeScript-bestand in een Go-map krijgt een zin, geen lege run.

Dekking na elke keer opslaan

Met testRun.onSave aan draait het opslaan van een bronbestand even na het opslaan de tests die het dekken, met dekking, en de gutter volgt. Voor een .NET-solution wordt het project van het opgeslagen bestand gevonden via de .csproj-graaf en worden alleen de testprojecten die ernaar verwijzen — rechtstreeks, of via andere projecten — gedraaid, één dotnet test <project> elk; elke andere runner draait zijn hele recept; een bestand dat van geen project is en door geen rapport wordt gemeten, draait niets. Meerdere keren achter elkaar opslaan is één run, en een run die al bezig is, wordt niet onderbroken. De rest gaat zoals Run Tests with Coverage het doet: de terminal, het Output-paneel, het geladen rapport. Standaard uit — het is een gewoonte om te kiezen, geen standaard om te ontdekken.

{
  "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).
Dekking na elke keer opslaan: bewerken, opslaan, en even later volgt de gutter.
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 aan — Quote.cs opgeslagen, de tests draaien vanzelf, de regel boven de methode verandert.

De app zelf, met dekking

Een testrun zegt wat de tests bereiken. Wat een mens bereikt — door de schermen klikken vóór een release, de stappen van een klant naspelen — is ook dekking, en Run App with Coverage… verzamelt die. De .NET-app van de map — een Exe, een WinExe, een web- of workerproject, nooit een testproject; een keuze waar er meerdere zijn — wordt gestart onder dotnet-coverage van Microsoft in een eigen console, zodat je in een console-app kunt typen, en draait tot je hem sluit. Wat je hebt doorlopen, wordt dan geladen als elke run, en in een coverage-sessie wordt het opgeteld bij wat de tests uitvoerden. Hoe de app eindigde, wordt de run niet aangerekend. De tool moet één keer worden geïnstalleerd: 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… — de console-app, een paar keer invoer, afgesloten, en de dekking ervan geladen.

Mutanten, en waar ze zitten

Een mutatietool – PIT voor Java, Stryker voor JavaScript, C# en Scala, Mull voor C en C++ – verandert uw code op kleine punten en voert de tests uit tegen elke wijziging. Een wijziging die geen enkele test opmerkt, is een overlevende mutant: de code is uitgevoerd, en niets heeft gecontroleerd wat die deed. De mutatiescore zegt hoeveel er zijn gevangen; sinds 0.2026.83 zegt de editor waar de andere zitten. Een regel met een mutant krijgt een notitie erachter (⚑ 2 mutants survived), de gewijzigde tekst is onderstreept wanneer het rapport aangeeft welke tekst dat was (Stryker en Mull doen dat), de overzichtsliniaal krijgt een streep, en de hover toont wat er is gewijzigd, hoeveel tests de code hebben uitgevoerd en, voor de gevangen mutanten, welke test ze heeft gevangen.

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).

Overleefd betekent dat tests de gewijzigde code hebben uitgevoerd en allemaal zijn geslaagd. Ongetest (in het rapport no coverage) betekent dat geen enkele test die code uitvoert, zodat niets het had kunnen opmerken. Gevangen mutanten worden in de hover geteld en nooit gemarkeerd, en mutanten die nooit een eerlijke test waren – een mutant die niet zou compileren – vallen buiten de score. De geannoteerde broncode heeft een rij onder elke dergelijke regel en een knop Next Mutant (U), en de HTML-rapporten hebben een sectie Surviving Mutants met een koppeling naar de regel. Er hoeft niets te worden ingeschakeld, en een project zonder mutatierapport merkt er niets van.

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).

Zou een test het merken? Een mutatierun bij de cursor

De mutatierun van een project duurt een uur; die van één functie een minuut. Run Mutation Tests Here draait die minuut: de functie waarin de cursor staat — of de geselecteerde regels, of het bestand — is wat de mutatierunner van de map moet muteren, en zijn rapport wordt geladen naast de dekking op het scherm, waar de overlevende mutanten worden gemarkeerd. Voor C# is dat Stryker.NET (dotnet tool install --global dotnet-stryker), dat het tekenbereik krijgt en het testproject dat naar het project van het bestand verwijst; voor JavaScript en TypeScript StrykerJS, dat de regels krijgt; voor Java PIT met Maven, dat de klasse krijgt. Hoe de runner eindigde, wordt de run niet aangerekend: een score onder zijn drempel is een exitcode, en toch een rapport. Een runner die niets schreef, wordt gemeld, met wat hij geïnstalleerd nodig heeft.

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 op één functie, en de overlevende mutanten gemarkeerd.

De eigen Test Coverage-weergave van VS Code

Met testCoverage.publish aan (de standaard) gaat elke geladen run ook naar de native Test Coverage-weergave van de editor — het dekkingspaneel van de Test Explorer, de percentages per bestand die hij in de Verkenner zet, en de eigen schakelaar Show Inline Coverage van de editor — als regels, takken en functies, met de details op aanvraag geladen, uit welke tracefile ze ook komen en zonder dat er een testadapter aan te pas komt. Show in Test Coverage View publiceert de actieve run en opent het paneel, wat de instelling ook zegt; het statusbalkmenu biedt het aan achter quickActions.showTestCoverage. Uit verschijnt er helemaal geen Fucini Coverage-item in de Test Explorer. Als een tracebestand zijn tests benoemt (de TN:-secties van lcov), verschijnt elke test onder Fucini Coverage in de Test Explorer en kan de weergave de dekking van een bestand per test filteren.

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).

Ongedekte regels in het Problems-paneel

Standaard uit omdat het van nature luidruchtig is, en altijd alleen voor de documenten die open zijn — een run van tweeduizend bestanden kan het paneel niet overspoelen. Onafhankelijk van problems.enabled, dat het bij één item per bestand houdt:

{
  "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

Beperk decoraties tot regels die zijn gewijzigd ten opzichte van een git-basisref — ideaal om precies te controleren wat een PR wel of niet heeft gedekt:

{
  "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. Dezelfde twee instellingen, gelezen uit dezelfde bestanden: de extensie voert zelf git diff <baseRef> uit voor elk bestand van de run en beperkt de run tot de regels die uw branch heeft gewijzigd — in de gutter, in het Coverage-venster en in de gates. Het Output-paneel zegt wat git antwoordde wanneer het niets antwoordt.

Een gate op nieuwe code

threshold.newCode is een eigen gate, naast die op de hele run: het minimale percentage van de meetbare regels die tegenover gitDiff.baseRef zijn gewijzigd, dat moet hebben gelopen. Een project dat in totaal op 62% staat, kan toch eisen dat wat vandaag wordt geschreven, getest is. Er wordt bij elke lading geteld op de hele run, die op het scherm blijft — gitDiff.enabled is het andere: de gewijzigde regels in de plaats van de run. Check Coverage Thresholds en de compliance-items in het Problems-paneel melden in een eigen zin dat de gate faalt: New code 72.00% < 80% (18 of 25 line(s) changed against origin/main ran). Een wijziging zonder meetbare regel — commentaar, een README — laat niets falen.

{
  "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 dat de gate voor nieuwe code laat falen, naast een run die zijn eigen gates haalt.

Nieuwe code per tag, per auteur, per datum

Nieuwe code is standaard de regels die de working tree wijzigt tegenover gitDiff.baseRef — een branch, een commit of een tag: "v1.4.0" is alles sinds die release. Twee instellingen vragen wat een ref niet kan. gitDiff.author neemt een deel van de naam van een auteur, en nieuwe code is dan de regels die git aan die auteur toeschrijft; gitDiff.since neemt een dag, en het zijn de regels die op die dag of later voor het laatst zijn gewijzigd, via welke branch ze ook binnenkwamen; beide samen: de regels van die auteur sinds die dag. Ze worden afgelezen uit git blame, bestand voor bestand — wat een grote run bij elke lading zal voelen — en nemen de plaats van de diff in voor diff-coverage en voor de gate hierboven. Een regel die nog niet is gecommit, telt hoe dan ook mee.

{
  "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).

Indirecte wijzigingen: wat verschoof terwijl niemand eraan kwam

Een diff zegt welke regels zijn gewijzigd; twee runs zeggen welke regels niet meer lopen of juist zijn gaan lopen. De regels die een blik waard zijn, zijn die waar de twee het oneens zijn: code die niemand bewerkte en die niet meer loopt, omdat een test is verwijderd, een tak eerder in de uitvoering nu vroeg terugkeert, een fixture is veranderd. Een review van de diff kan ze niet zien — ze liggen er per definitie buiten. Show Indirect Coverage Changes… somt ze per bestand op, het bestand dat het meest verloor eerst, en opent het bestand dat je kiest op zijn eerste regel van die soort. De run wordt tegen de CI-baseline gehouden waar baseline.report er een noemt — daarop wordt een pull request beoordeeld — en anders tegen de run ervoor; de regels die de working tree wijzigt tegenover gitDiff.baseRef, en alles onder een plek waar die wijziging de regels van het bestand verschuift, blijven buiten beschouwing.

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… — een bestand dat regels verloor die niemand heeft bewerkt, nadat tussen twee runs een test was verwijderd.

10. De samengestelde score

In plaats van zes getallen te rapporteren, vouwt de extensie ze samen tot één Gewogen Harmonisch Gemiddelde (WHM). Voor metrics met percentages pᵢ en gewichten wᵢ:

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

Een harmonisch gemiddelde wordt gedomineerd door zijn kleinste term, zodat een zwakke metric niet kan worden gemaskeerd door een perfecte — precies de eigenschap die je van een veiligheidspoort wilt. Standaardgewichten:

MetriekGewichtOnderbouwing
MC/DC4IEC 61508 SIL 3–4 / ISO 26262 ASIL C–D / DO-178C DAL A–B.
Takken2IEC 61508 SIL 2+ / ISO 26262 ASIL B+.
Condities3Tussen takken en MC/DC (DO-178C, ISO 26262).
Regio’s1.5Paden binnen een statement (bijv. gedeeltelijke kortsluitevaluatie).
Regels1IEC 61508 SIL 1+ / ISO 26262 ASIL A+.
Functies1Poort voor dode code.
Instantiaties0.5Dekking van C++-templates; de smalste scope.
Functieaanroepen1Aanroeplocaties die zijn uitgevoerd (gcov, VectorCAST, Testwell CTC++, TRACE32).
Objectcode0Uit, tenzij u er een gewicht aan geeft: het omvat de statementdekking al.
Mutatiescore0Uit, tenzij u er een gewicht aan geeft: het is geen dekking.

Zet een gewicht op 0 om die metric uit de score te laten vallen. Metrics die niet in de gegevens aanwezig zijn (bijv. MC/DC in een gewone lcov-run) worden gewoon weggelaten.

Objectcode en de mutatiescore wegen 0 totdat u anders beslist (whmWeights.objectCode, whmWeights.mutation). Objectcodedekking omvat de statementdekking, dus wie beide weegt, telt hetzelfde bewijs dubbel; een mutatiescore is helemaal geen dekking – een testsuite kan elke regel uitvoeren en niets detecteren. Beide hebben wel een eigen kolom en een eigen drempel.

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).

Conditiedekking

a && b is één beslissing – twee takken – en twee condities met vier uitkomsten. Een testsuite kan beide takken nemen en b toch nooit onwaar zien: de takdekking is volledig en de conditiedekking is drie van de vier. Dat niveau ligt in DO-178C en ISO 26262 tussen takdekking en MC/DC, en sinds 0.2026.83 is het een eigen metriek in plaats van verwerkt in de takken: een rij in de kaarten van de statusbalk, een kolom in de Coverage-weergave, de rapporten en de exports, een gewicht van 3 in de score (whmWeights.conditions) en een poort (threshold.conditions; zonder poort onder het profiel standard, 100 onder 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).

Gelezen uit condition-probes van BullseyeCoverage, een cond-export van TRACE32 en GCC 14, gebouwd met -fcondition-coverage. Een rapport dat condities niet van beslissingen onderscheidt, heeft geen dergelijke rij, kolom of gewicht. Als u Bullseye of TRACE32 gebruikt: condities telden voorheen als takken, dus uw takpercentage verandert met deze release, en met het nieuwe gewicht ook uw samengestelde score; stel whmWeights.conditions in op 0 voor de score zoals die was.

GCC 14, regel voor regel. -fcondition-coverage laat gcov zeggen welke uitkomst van welke conditie ontbreekt — conditie 1 nooit waar, conditie 0 geen van beide uitkomsten — en elke conditie wordt op haar regel gemarkeerd en in de hover genoemd, uit de JSON van gcov en uit zijn tekstlisting (condition outcomes covered 3/6). De metriek staat waar de andere staan: threshold.conditions is de gate ervoor en blijft onbeoordeeld waar een run zo’n cijfer niet heeft, Copy Coverage Summary heeft een kolom Conditions, badge.metric accepteert conditions, en het zoekvak accepteert conditions < 80. Het branchcijfer van een functie laat de uitkomsten van haar condities weg, zoals dat van het bestand en dat van de run.

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).

Complexiteit en CRAP

Sommige rapporten bevatten de cyclomatische complexiteit van elke functie: OpenCover (het formaat dat Coverlet schrijft), JaCoCo, Clover en Cobertura. Waar dat zo is, berekent de extensie een CRAP-score – Change Risk Anti-Patterns – voor de functie, op basis van die complexiteit en van de dekking die ze zelf heeft gemeten:

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

Een eenvoudige, volledig geteste functie scoort haar eigen complexiteit en niets meer; een complexe, nauwelijks geteste functie scoort in de honderden. In het C#-voorbeeld van het demoproject heeft Price() complexiteit 22 en is ongeveer 37% van de regels gedekt, wat 142,2 oplevert, terwijl Shipping() complexiteit 12 heeft en volledig gedekt is, wat 12 oplevert. De gebruikelijke grens is 30: een functie die daarop of daarboven uitkomt, staat in het HTML-rapport onder Riskiest Methods, de slechtste eerst.

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).

De complexiteit en de score staan in de CodeLens van de functie en naast de functie in de geannoteerde broncode. Max CRAP is de hoogste score van alle functies in een bestand – de slechtste, geen gemiddelde – en is een kolom in de Coverage-weergave, het HTML-rapport en de CSV- en Markdown-exports. Het is informatie: er is geen drempel voor en het heeft geen gewicht in de samengestelde score. Rapporten zonder complexiteit (lcov, gcov, Istanbul, coverage.py) hebben geen CRAP, en ook geen lege kolom.

Sinds 0.2026.83 hebben C en C++ hem ook. llvm-cov rapporteert geen complexiteit, dus wordt die geteld uit de takgegevens die het rapport al bevat: de condities die in het eigen bestand van de functie zijn geschreven, plus één – de definitie van McCabe, en wat de tools op broncodeniveau voor .NET en Java tellen. Condities die uit een macro uit een ander bestand komen – elke assert bijvoorbeeld – worden niet meegeteld.

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, en welke bestanden worden getoond

Onder de boom van de Coverage-weergave somt Risk hotspots de functies op waar complexe code weinig dekking treft, de ergste eerst, en elke opent haar bestand bij de functie. Een functie komt in aanmerking op CRAP-score — hotspots.crapThreshold, standaard 30, het getal dat de auteurs van de metriek voorstelden — of op cyclomatische complexiteit alleen, hotspots.complexityThreshold, standaard uit; alleen rapporten die complexiteit bevatten (OpenCover, Cobertura van Coverlet, JaCoCo, llvm-cov) hebben er. Community ziet het aantal en de slechtste score; de gerangschikte lijst is Pro. Naast de sortering zegt een tweede dropdown welke bestanden de boom toont — alle, bestanden met gaten, ongeteste bestanden, of de bestanden die sinds de vorige run zijn gewijzigd; mappen volgen hun bestanden en houden hun eigen getallen. Beide zitten ook in Visual Studio, in het Coverage-venster.

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: het Coverage-venster, met het filter naast de sortering en de Risk hotspots onder de boom.

Namespaces, klassen en methoden

Voor een .NET-rapport dat zijn klassen noemt — Cobertura en Coverlets coverage.cobertura.xml, OpenCover — tekent een derde dropdown, Folders / Namespaces, dezelfde run als namespaces, klassen en methoden: het cijfer van een namespace is dat van zijn klassen opgeteld, dat van een klasse dat van haar methoden, precies zoals dat van een map dat van haar bestanden is, met dezelfde sortering en hetzelfde filter. Een methoderij opent het bestand bij de methode; een klasse die in geen namespace is gedeclareerd staat onder (no namespace). De keuze wordt naar coverageView.perspective geschreven; een run zonder klassenamen heeft geen dropdown en toont zijn mappen. In Visual Studio heeft het Coverage-venster dezelfde 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).
Dezelfde run per namespace, klasse en methode.
Visual Studio: the Coverage window with the dropdown on Namespaces, the Pricing namespace open on Customer and its methods
In Visual Studio: het Coverage-venster per namespace, klasse en methode.

Onder de knoppen en dropdowns een zoekvak. Een woord houdt de rijen waarvan de naam of het pad het bevat — elk getypt woord moet erin staan; een vergelijking houdt de rijen waarvan het cijfer eraan voldoet — < 80% op de score, lines >= 90, branches = 0, functions != 100, mcdc < 50 — en invoice < 80 wil beide. Methoderijen van het namespace-perspectief en de risk hotspots worden met de bestanden mee doorzocht, zodat een functie wordt gevonden waar de run haar heeft. De boom wordt gefilterd terwijl je typt, in de pagina, zonder hertekenen; een map met een treffer klapt ervoor open en weer dicht wanneer het vak leeg raakt; Esc wist het. Hetzelfde vak, dezelfde grammatica, 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).
Zoeken in de boom: een naam, dan lines < 80.

De boom volgt de editor

Het bestand waar je naar kijkt, is gemarkeerd in de Coverage-weergave, de mappen erboven worden geopend en de rij ervan wordt in beeld gescrold — de boom hoeft niet meer te worden doorzocht naar het bestand dat al open is. Verder houdt de boom zijn scrollpositie, en er wordt niets opnieuw getekend. coverageView.followActiveEditor, standaard aan, zet het uit voor wie de boom liever laat waar hij hem heeft neergezet.

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: wisselen van document, en de gemarkeerde rij van het Coverage-venster die meegaat.

11. Compliance-gating

Het COMPLIANT / NON-COMPLIANT-oordeel (getoond in de geannoteerde bronweergave, het HTML-rapport en beide statusbalk-hovers) wordt bepaald door per-metric drempelwaarden en een modus:

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 wanneer…
strict (default)elke afzonderlijk bewaakte metriek haalt haar eigen drempel — geen compromissen.
whmde enkele gewogen samengestelde score haalt threshold.weighted.
bothzowel de gewogen poort ALS de strikte poort per metriek worden gehaald.
eitherde gewogen poort OF de strikte poort per metriek wordt gehaald (soepelst).

Een drempel van 0 schakelt die poort uit, en een metriek die het rapport niet bevat, wordt nooit beoordeeld. Waar een drempel die u niet hebt ingesteld voor staat, wordt bepaald door het profiel hieronder. Voer Fucini Coverage: Check Coverage Thresholds uit om op aanvraag te evalueren.

In Visual Studio. Tools → Coverage Studio → Check Coverage Thresholds beoordeelt de run tegen dezelfde threshold.*-sleutels en zegt dat in de statusbalk en het Output-paneel; met compliance.diagnostics, problems.enabled, problems.perLine of deadCode.enabled staan de bevindingen in de Error List naast die van de compiler zelf — één item per bestand onder een gate, één per ongedekt bereik, één per functie die nooit draaide — en elk opent zijn bestand bij de regel.

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, met de bevindingen in de Error List.

Drempelprofielen

threshold.profile bepaalt waar een drempel die u niet hebt ingesteld voor staat. standard, de standaard sinds 0.2026.82, is waaraan een gewoon project zonder veiligheidseisen redelijkerwijs kan worden gehouden. safety zet elke poort op 100 – wat een safety case vraagt, en precies wat tot en met 0.2026.81 werd geleverd.

Metriekstandardsafety
Regels80100
Functies80100
Regio’s75100
Takken70100
Samengestelde score75100
MC/DC, instantiaties, functieaanroepen, objectcodegeen poort100
Conditiesgeen poort100
Mutatiescoregeen poortgeen poort

Een drempel die u wél hebt ingesteld, gaat boven beide profielen. Het voorbeeld zet de poort voor takken op 90 en voor al het andere op 100; wilt u slechts enkele metrieken op 100 houden, blijf dan op standard en stel die zelf in. Eén kanttekening volgt uit de manier waarop instellingen werken: een waarde die gelijk is aan de meegeleverde standaard is niet te onderscheiden van helemaal geen waarde, dus onder safety telt een drempel die precies op zijn standaardwaarde is gezet – bijvoorbeeld 80 voor regels – nog steeds 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).

Als u op de oude standaardwaarden vertrouwde, wordt u na het bijwerken naar 0.2026.82 milder beoordeeld totdat u safety kiest. Een installatie die al eerder draaide, krijgt dit één keer te horen, met een knop Keep 100% (safety) die het profiel in uw gebruikersinstellingen schrijft; zet het bij een gedeeld project ook in de werkruimte-instellingen, zodat iedereen op dezelfde manier wordt beoordeeld. Configure Coverage Compliance & Thresholds... toont het profiel boven het drempelraster, en de livevoorbeeldweergave beoordeelt met de poorten die werkelijk van kracht zijn. In elke kaart en elk rapport toont een metriek waarvan de poort uit staat haar waarde met een neutraal streepje in plaats van een vinkje of een kruisje.

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. Objectcode-dekking

Elke andere metriek hier wordt aan de bron gemeten: een tool instrumenteert je code, de geïnstrumenteerde build draait, en de tellers zeggen welke statements, takken of condities zijn uitgevoerd. Objectcode-dekking meet iets anders — hoeveel van de gebouwde binary daadwerkelijk heeft gedraaid, geteld in instructiebytes, door de instructiestroom te observeren in plaats van de bron te instrumenteren. Dat is van belang omdat een compiler code uitstoot die door geen enkele regel van je bron wordt verantwoord: array-grenscontroles, switch-sprongtabellen, registerspills, stack probes, aanroepen naar runtime-hulproutines voor deling of drijvende komma op cores die de instructie missen. Het is ook de enige metriek hier die de vraag dekt dit assembly? beantwoordt — handgeschreven assembly wordt nooit geïnstrumenteerd en een brongebaseerd hulpmiddel komt er niet bij. DO-178C is expliciet over het waarom: op niveau A, waar een compiler of linker code genereert die niet rechtstreeks naar bronstatements te herleiden is, vereist doelstelling 6.4.4.2b aanvullende verificatie van precies die gegenereerde code.

Het omvat statementdekking — elke uitgevoerde instructie kwam uit een statement, dus 100% objectdekking impliceert 100% statementdekking. Omgekeerd geldt dat niet, en juist die asymmetrie is de reden om het te meten. Daar volgen twee dingen uit. Het krijgt geen gewicht in de samengestelde score, want twee maten van dezelfde uitvoeringen middelen telt hetzelfde bewijs dubbel; in plaats daarvan wordt het bewaakt via fuciniCoverage.threshold.objectCode — een eis in plaats van een gewicht, precies zoals de norm het vraagt. En het gat is het resultaat: een run met 100% regeldekking en minder dan 100% objectdekking heeft precies de door de compiler gegenereerde code gevonden die je bron niet verantwoordt, dus de compliance-kaart zegt 312 bytes nooit uitgevoerd, bij 100% regeldekking in plaats van dat als «94%» weg te moffelen. Het omgekeerde — een hele binary die als uitgevoerd wordt gemeld terwijl de bron dat niet was — is een tegenspraak en geen lage score: vrijwel altijd een verouderd tracebestand aan één kant van een merge, of modulenamen die nooit met bestandspaden overeenkwamen. Dat wordt als bevinding gemeld.

Objectcode-dekking vereist dat de binary draait op een plek waar zijn instructies waarneembaar zijn. Er zijn drie routes en ze verschillen enorm in kosten. Alleen de derde levert objectcode-dekking op; de eerste twee staan erbij omdat ze een verwant probleem oplossen dat vaak het probleem is dat werkelijk opgelost moet worden.

  1. Een geïnstrumenteerde build die op het target draait. GCC-crosscompilers accepteren -fprofile-arcs -ftest-coverage, dus de instrumentatie die op een werkstation werkt, werkt ook op het target — alleen heeft een bare-metal systeem geen bestandssysteem om de .gcda-tellers naar te schrijven, en vaak geen exit() om dat op te doen. De tellers staan hoe dan ook in RAM, dus de oplossing is dat geheugen te dumpen en de bestanden buiten het target op te bouwen; embedded-gcov van NASA JPL (Apache-2.0) doet precies dat, zonder bestandssysteem, besturingssysteem of standaard C-bibliotheek. Dit levert statement-, tak- en functiedekking op van een build gemaakt door jouw crosscompiler, voor jouw instructieset, op jouw hardware — geen objectcode-dekking, en de gemeten binary is geïnstrumenteerd, dus groter en trager dan degene die je uitlevert. Laad het resultaat als LCOV, gcovr JSON, gcov JSON of, op een toolchain ouder dan GCC 9, als het platte-tekstlisting .gcov.
  2. Een instructieset-simulator. Draai de echte target-binary in een simulator en leid de dekking af uit de uitgevoerde adressen: geen hardware, geen instrumentatie, geen probe, en omdat hij instructies waarneemt kan hij echte objectcode-dekking opleveren. De beperking is getrouwheid — een simulator modelleert de core goed en de randapparatuur minder goed, dus behandel resultaten op systeemniveau met argwaan tenzij hij jouw silicium nauwkeurig modelleert.
  3. On-chip trace en een debugger. De certificeringswaardige route, en de enige werkelijk niet-intrusieve: de trace-eenheid van de core rapporteert de instructiestroom aan een debugger, die er dekking van maakt. Er wordt niets geïnstrumenteerd, de codegrootte verandert niet en de timing blijft ongemoeid — en juist dat maakt het resultaat bewijs over de binary die je daadwerkelijk uitlevert. Controleer het silicium voordat je hier budget voor vrijmaakt: bij veel microcontrollerfamilies is volledige trace alleen beschikbaar op een emulatie- of ontwikkelvariant met een grote tracebuffer en een snelle tracepoort, terwijl productie-onderdelen een afgeslankte trace-eenheid hebben waarvoor de fabrikant als terugvaloptie een softwaretrace biedt die de code instrumenteert en CPU-tijd kost — precies de eigenschap weg waarvoor de route was gekozen.

Veel embedded projecten meten dekking door dezelfde bronnen te compileren voor de ontwikkelmachine en de unittests daar te draaien. Het is snel, vereist geen hardware, en is voor de meeste teams de juiste standaard — maar het is de moeite waard duidelijk te zijn over wat dat bewijs beschrijft: een andere compiler, een andere optimalisator, een andere instructieset en een andere binary dan degene die wordt uitgeleverd. Voor de meeste software is dat een aanvaardbare en goed begrepen afweging. Voor werk dat wordt beoordeeld tegen IEC 61508, ISO 26262 of DO-178C is dit het standaard host-versus-target bezwaar, en de routes hierboven zijn de standaardantwoorden erop — de eerste sluit het voor brondekking, de derde voor objectcode.

Vandaag is de export die voor objectcode wordt gelezen die van Lauterbach TRACE32's COVerage.EXPORT.ListModule met metric="object"; laad die zoals elk ander tracebestand. De metriek wordt gescoord en bewaakt op een betaalde licentie en tijdens de evaluatieperiode. Een Community-installatie scoort hem niet — maar krijgt wel te horen wanneer een tracebestand hem bevat, want een compliance-oordeel dat stilzwijgend het sterkste bewijs in het bestand weglaat, zou erger zijn dan een dat zegt wat het heeft weggelaten.

12. Niet-coderegels uitsluiten

Met excludeComments ingeschakeld (de standaard) worden statements die volledig op regels met alleen commentaar of lege regels vallen, uitgesloten van de totalen — dit neutraliseert ook een bekende eigenaardigheid van llvm-cov/gcov waarbij een verdwaalde treffercount op commentaar terechtkomt. Standaardmarkeringen worden ook gerespecteerd:

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

Ook preprocessordirectieven tellen niet als code, in C, C++, Objective-C, CUDA en C#: een regel die met # begint — #define, #include, #if — en de regels waarop een backslash aan het eind hem voortzet. gcov rekent elk gebruik van een macro toe aan de regel waarop die is gedefinieerd, dus een header waarvan de enige gerapporteerde regel #define CHANNEL_COUNT (33U) was, leek 100% gedekt omdat een lus in het .c-bestand tot daar liep, en een header waarvan niets de constante gebruikte, leek 0% gedekt. Zo'n header heeft nu niets te meten en wordt niet vermeld.

Zet excluded.includeInTotals op true om uitgesloten regels toch mee te tellen.

Een bestand of een map weglaten, vanuit de boom

Rechtsklik op een bestand of een map in de Coverage-weergave en kies Exclude from Coverage — het staat ook tussen de padacties van de rij — of voer Exclude This File from Coverage uit op het geopende bestand: het pad van het bestand relatief aan de werkruimte, of de /** van de map, gaat in fuciniCoverage.ignore in de instellingen van de map, eenmalig, en het herladen haalt het uit elk totaal en elke pagina; het patroon staat daar om er weer uit te halen. In Visual Studio hebben het menu van de rij en Tools → Coverage Studio dezelfde twee, die dezelfde instelling in hetzelfde bestand schrijven.

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 op een map: de boom zonder haar, het patroon in de instellingen.
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 op fees.ts — de boom zonder het bestand, het patroon in .vscode/settings.json.

Attributen en namespaces, voor .NET

Twee instellingen lezen uit de broncode wat het rapport niet kan zeggen. ignore.attributes — standaard ExcludeFromCodeCoverage — sluit de klasse, methode of property onder een attribuut dat het noemt uit, zoals LCOV_EXCL_START/STOP dat zouden doen, welk gereedschap het rapport ook schreef: Coverlet respecteert het attribuut, OpenCover, dotCover en een geconverteerde lcov niet, en nu zijn ze het allemaal eens. Namen met of zonder het achtervoegsel Attribute, met of zonder namespace; voeg GeneratedCode, Obsolete of je eigen toe. ignore.namespaces laat elk bestand weg waarvan de namespace-declaratie op een prefix past, * als jokerteken — Acme.Generated, Acme.*.Migrations, *Tests — en het Output-paneel noemt de bestanden die het wegnam. Beide worden gelezen in dezelfde doorgang die de commentaarmarkeringen leest, in beide edities.

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

Uitsluiten vanuit de editor

Selecteer de regels en kies Exclude Selection from Coverage uit het lampje, het contextmenu van de editor of de Command Palette — in Visual Studio het lampje (Ctrl+.), het rechtsklikmenu van het codevenster, Tools → Coverage Studio of Ctrl+Shift+U, X — en de uitsluiting wordt geschreven waar de code staat: [ExcludeFromCodeCoverage] boven een C#-, VB- of F#-klasse, -methode of -property, met de korte naam wanneer het bestand System.Diagnostics.CodeAnalysis al importeert en volledig gekwalificeerd wanneer niet, zodat er geen using hoeft te worden toegevoegd; LCOV_EXCL_LINE aan het eind van één regel code; LCOV_EXCL_START en LCOV_EXCL_STOP rond meerdere, op de inspringing van de eerste regel — met het eigen commentaarteken van de taal, //, #, ', -- of ;. Eén ongedaan-stap. Het lampje biedt het ook aan op een regel die de Problems-items als ongedekt markeren. Een regel die al gemarkeerd is, of een lid dat al een attribuut heeft, blijft zoals hij is.

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: de markeringen rond de selectie geschreven, in het eigen commentaarteken van het bestand.
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 — de LCOV_EXCL-markeringen rond een tak, daarna [ExcludeFromCodeCoverage] boven een methode.

Alleen takken, en de markeringen van gcovr

Een defensieve else, een default: waar geen waarde komt, de arm die een compiler voor een exception toevoegt: de regel loopt en hoort mee te tellen, en alleen zijn tak kan niet worden genomen. LCOV_EXCL_BR_LINE en LCOV_EXCL_BR_START … LCOV_EXCL_BR_STOP halen de takken op hun regels uit de telling en laten de regels erin. LCOV_EXCL_EXCEPTION_BR_LINE en zijn regio halen nog minder weg — alleen de armen waar een exception naartoe leidt, waar het rapport zegt welke dat zijn, zoals de JSON van gcov doet. Elke markering wordt ook onder de prefixen van gcovr gelezen: GCOVR_EXCL_LINE, GCOVR_EXCL_START, GCOVR_EXCL_BR_LINE, GCOV_EXCL_STOP en de rest betekenen wat de LCOV_EXCL_-markeringen betekenen, zodat een bron die voor gcovr is geschreven hier hetzelfde wordt gelezen, welke tool het rapport ook maakte. Niet gelezen: GCOVR_EXCL_FUNCTION — niets op die regel zegt waar de functie eindigt.

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).

Zeggen waarom: onderbouwde uitsluitingen

Code uit de telling halen is een bewering — “dit kan niet worden getest”, “dit is een hulpmiddel voor ontwikkelaars” — en onder DO-178C, ISO 26262 of IEC 61508 moet een bewering die het cijfer verandert waarop een certificaat rust, zijn opgeschreven en te reviewen zijn. Daarom kan een uitsluiting zeggen waarom, op de plek waar ze geschreven staat: de tekst na LCOV_EXCL_LINE of LCOV_EXCL_START, of de Justification van [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) { /* … */ }

De redenen worden bij elke lading gelezen en het log telt ze. Export Coverage Report… schrijft de lijst — exclusions and their justifications, als Markdown of CSV: het bestand, de regels, hoe de uitsluiting is geschreven, en de onderbouwing of none given. Een bestand waarin niets meetbaars overblijft, staat toch in die lijst. Met exclusions.requireReason aan is een uitsluiting die geen reden geeft een bevinding: een waarschuwing in het Problems-paneel op haar regel, en een falen van Check Coverage Thresholds. Exclude Selection from Coverage vraagt dan eerst om de reden en schrijft die bij de markering of als de Justification van het attribuut; wordt de vraag weggeklikt of leeg gelaten, dan wordt er niets uitgesloten.

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: een uitsluiting zonder reden als waarschuwing op haar regel, en de geëxporteerde lijst met none given.

12a. Beschrijft deze dekking dit bestand nog?

Dekking uit een tracebestand beschrijft de broncode zoals die was toen de tests draaiden, en de meeste formaten zeggen niet welke versie dat was. Elk bestand in het Dekking-paneel bevindt zich daarom in een van drie toestanden:

  • ✓ Geverifieerd — het tracebestand legt vast wat elke gemeten regel bevatte, en dat komt nog steeds overeen met het bestand.
  • Geen markering — niet weerlegd. Niets spreekt de dekking tegen en niets bevestigt haar. Dit is de gewone toestand.
  • ⚠ Weerlegd — het bestand zelf weerlegt zijn dekking. De regel wordt gedimd en de tooltip zegt wat er gevonden is.

Slechts twee formaten kunnen het vinkje verdienen, omdat er maar twee iets vastleggen over de broncode die ze maten: lcov geschreven met --checksum (standaard uit in geninfo; het gedocumenteerde doel is juist te voorkomen dat dekking van twee versies van een bestand wordt samengevoegd) en GNATcoverage XML, dat de tekst van elke gemeten regel meestuurt. Die lcov-optie aanzetten is de moeite waard.

De waarschuwing heeft geen van beide nodig en werkt met elk formaat: dekking vastgelegd voorbij het einde van het bestand, een benoemde functie die niet meer staat waar het rapport haar plaatst, of uitgevoerde regels die in het bestand leeg zijn. Tijdstempels zijn op zichzelf nooit genoeg — een git checkout verplaatst ze allemaal zonder een byte te veranderen — dus een verplaatste tijdstempel is hooguit een reden om nog eens te kijken. De controle draait bij het laden van dekking en opnieuw telkens wanneer een bestand wordt opgeslagen of op schijf verandert, zodat de markering het bestand volgt: een bewerking die de run tegenspreekt zet haar, een checkout die de gemeten versie terugzet haalt haar weg. De tooltip zegt precies wat het bewees. Zet staleWarning.enabled op false om dit alles uit te schakelen.

12b. Ongemeten tegenover ongedekt

Een bestand dat de run nergens noemt, is ongemeten: geen test heeft het geladen, dus geen tool heeft er een regel voor geschreven. Dat is niet hetzelfde als ongedekt — gemeten, met nul treffers — en de extensie heeft een afwezig bestand nooit als 0% gescoord. Wat ze tot 0.2026.69 niet deed, was de afwezige bestanden überhaupt tonen: een module zonder enige test verscheen nooit in de boom, de totalen of de drempelcontrole, en een lezer zag ‘92%’ voor een project waarvan de helft van de bestanden nooit was uitgeoefend.

Nu zegt, met een run geladen, het statusbalkitem per bestand not measured voor een bronbestand van de eigen soort van de run dat niet in de run zit — ‘van de soort van de run’ betekent dat het een van de bestandsextensies heeft die de run heeft gemeten, zodat de headers en bronnen van een C-project kandidaat zijn en zijn Python-scripts niet. Alles daarbuiten is opt-in via fuciniCoverage.unmeasured.mode:

  • off (standaard) — er verandert verder niets.
  • list — de Coverage-weergave krijgt onderaan een groep Unmeasured die elk zo’n bestand noemt, en elke rij opent het; het laadresultaat telt ze; badges markeren ze met ? in de Verkenner; en fuciniCoverage.threshold.unmeasuredFiles kan Check Coverage Thresholds laten falen wanneer het er meer zijn dan een aantal dat je instelt. Geen enkel percentage verschuift.
  • count — alles wat list doet, en elk ongemeten bestand telt bovendien tegen de run als een ongedekt bestand ter grootte van zijn eigen coderegels, zodat de statusbalk, de drempels, de badges, de geschiedenis, elke export en de Test Coverage-weergave het lagere getal tonen. Het bestand wordt overal waar het verschijnt als ongemeten getekend, zijn gutterbalken zeggen ‘not measured’ in plaats van ‘never ran’, en de afwijkingscontrole laat het met rust — er is geen meting die zijn inhoud kan tegenspreken.
{
  "fuciniCoverage.unmeasured.mode": "list",
  "fuciniCoverage.threshold.unmeasuredFiles": 0
}

Headerbestanden zijn de bekende valse positieven in C: ze hebben de extensiefamilie van de run en geen enkele tracefile zal er ooit een noemen, omdat een header op zichzelf tot niets compileert. fuciniCoverage.unmeasured.exclude laat daarom standaard **/*.h, **/*.hpp, **/*.hh, **/*.inl en **/*.d.ts weg, in dezelfde glob-syntaxis als fuciniCoverage.ignore; voeg een platformport toe die hier niet wordt gebouwd, of gegenereerde stubs, en ze vallen uit de lijst, de telling en de statusbalktoestand. Een bestand dat ignore noemt, wordt ook nooit ongemeten genoemd — het weglaten was juist de bedoeling. threshold.unmeasuredFiles staat standaard op -1, wat niet controleert; 0 faalt zodra enig bestand van de soort van de run nooit door een test is geladen, en het geldt alleen zolang unmeasured.mode op list of count staat.

13. HTML-rapporten

  • Generate Full HTML Report — een zelf-gerenderd, meerpagina's rapport per map. Uitvoer gaat naar htmlReport.outputDir, of de globale opslag van de extensie indien niet ingesteld.
  • Open Annotated Source — een geannoteerde weergave van één bestand. Wijs externalHtmlReport.dir naar een vooraf gebouwde map van llvm-cov show --format=html om die pagina's te gebruiken in plaats van de ingebouwde renderer.
  • Export Fucini JSON — het volledige genormaliseerde model voor je eigen tooling.
  • Export Coverage Report... — de uitvoering als CSV (per bestand of per functie), een Markdown-samenvatting, een LCOV-tracebestand, Cobertura-XML, SARIF, of een zelfstandige SVG-badge voor je README. Ook bereikbaar via de knop naast Generate Full HTML Report in de weergave Covered Files. Alles behalve de CSV's verliest informatie — MC/DC, regio's en instantiaties passen niet in LCOV, Cobertura of SARIF — dus Fucini JSON en de CSV's blijven de formaten die elke metriek dragen.
  • Copy Uncovered Lines — een Markdown-samenvatting van elk gat, klaar om in een PR te plakken.

In Visual Studio. De groep Reports van Tools → Coverage Studio: Show Annotated Source opent het actieve document als een pagina in het documentvenster — elke regel in zijn kleur, de bevindingen ernaast — die in beide richtingen met de editor meescrolt; Open HTML Report schrijft het rapport van één pagina naar htmlReport.outputDir (of %LOCALAPPDATA%\Fucini\CoverageStudio\html-report) en opent de browser; Generate Full HTML Report schrijft daar de index per map en de pagina per bestand; Export Coverage Report… biedt dezelfde acht formaten en vraagt waar op te slaan; Generate Coverage Badge schrijft de badge waar badge.outputPath zegt, na elke lading met badge.autoUpdate. De geannoteerde pagina heeft WebView2 nodig, zoals het Coverage-venster; de rapporten op schijf niet.

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 — het bestand als pagina in het documentvenster, naast de 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).

Geannoteerde broncode versus gewone broncode

Open Annotated Source vervangt het actieve tabblad door een kleurgecodeerde coverage-webview voor dat bestand, in dezelfde kolom; Open Annotated Source to the Side doet hetzelfde, maar in een gesplitst venster, zodat bron en geannoteerde weergave naast elkaar staan. Om in plaats daarvan ter plekke heen en weer te schakelen — handig op een klein scherm waar een splitsing elk paneel te smal maakt — gebruik je Toggle Annotated Source: dit wisselt het actieve tabblad tussen de twee, waarbij onthouden wordt welke je op dat moment bekijkt. Vanuit de geannoteerde weergave zelf brengt Show Source je direct terug naar de gewone editor voor dat bestand.

Welke HTML je daadwerkelijk te zien krijgt, hangt af van externalHtmlReport.dir: als deze is ingesteld en er al een pagina bestaat die overeenkomt met het actieve bestand (llvm-cov legt per-bestandspagina's aan als <repo-naam>/<relatief-pad>.html, dus de eigen repo-naammap van het rapport hoeft nooit geconfigureerd te worden), wordt die door de toolchain gegenereerde pagina getoond in plaats van de ingebouwde renderer — de lokale links/stylesheet worden herschreven zodat ze binnen de webview werken, en de pagina bevat details die de ingebouwde weergave niet reproduceert (MC/DC-uitklapweergaven, regiomarkering, mapoverzichten). Geen overeenkomende pagina voor dat bestand, of de instelling leeg gelaten? Dan wordt de ingebouwde renderer gebruikt. De extensie leest deze map alleen — ze schrijft er nooit in.

Een dekkingsbadge voor de README

Generate Coverage Badge schrijft een SVG in shields-stijl voor de actieve run naar de werkruimte — badge.outputPath, standaard coverage-badge.svg, relatief aan de werkruimtemap of absoluut, met dezelfde variabelen als elke andere padinstelling — en biedt aan hem te openen. Het is een gewoon bestand in je repository, dus een README sluit hem in zonder dienst erachter, zonder omweg via shields.io, en het werkt ook in een repository zonder internetverbinding:

![coverage](coverage-badge.svg)

coverage: 83%

badge.metric kiest wat de badge toont: lines (met het label coverage), branches, mcdc of weighted, dezelfde samengestelde score die de statusbalk toont, met het label score. Een run zonder gegevens voor de gekozen metriek krijgt een grijze n/a in plaats van een rode 0%. De kleur volgt je eigen colorScale.*-niveaus: lowColor onder lowThreshold, midColor tot highThreshold, highColor vanaf daar. Met badge.autoUpdate aan wordt de badge na elke geslaagde lading stilzwijgend opnieuw geschreven, en het uitvoerkanaal legt elke schrijfactie vast als [FUCINI_BADGE] — standaard uit omdat het bij elke lading in de werkruimte schrijft. Commit de SVG samen met de code en het plaatje op de repositorypagina volgt het getal in de editor.

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

14. Geschiedenis & trends

Schakel history.enabled in om runs lokaal te bewaren (met behoud van history.retention ervan). Je krijgt dan een trendpijl (▲/▼) in de statusbalk, de trendgrafiek in de Coverage-weergave en twee vergelijkingsopdrachten: Compare with Last Run en Compare Two History Runs, die elk een regressie/verbeterings-diff per bestand opleveren.

In Visual Studio. Elke lading wordt vergeleken met de vorige: een driehoek in de gutter op elke regel die begon of ophield te draaien (sinceLastRun.enabled), de trend naast de score in de statusbalk, en Compare with Last Run voor de bestanden waarvan de getallen bewogen. Met history.enabled worden de runs bewaard onder %LOCALAPPDATA%\Fucini\CoverageStudio\history, history.retention ervan, zodat de vergelijking een herstart overleeft, de trendgrafiek iets te tekenen heeft en Compare Two History Runs… er twee naar keuze uitpikt.

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).

De trendgrafiek

Onder de werkbalk van de Coverage-weergave, met twee of meer bewaarde runs, de regeldekking van de geschiedenis als een lijn, van oudste naar nieuwste, de nieuwste dertig: een stip per run die bij hover zijn datum en cijfer zegt, en het laatste cijfer ernaast met een pijl voor de richting sinds de eerste. De verticale schaal is het eigen bereik van de runs, zodat een team op 92–94% de beweging ziet in plaats van een vlakke lijn onder 100. Beide edities tekenen hem uit dezelfde geschiedenis.

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).
De trend: een stip per bewaarde run, het laatste cijfer ernaast.
Visual Studio: the trend line under the Coverage window toolbar, the last figure 68.25%
In Visual Studio: de trend onder de werkbalk van het Coverage-venster, het laatste cijfer 68.25%.

Coverage-sessies

Eén testrun dekt zelden alles wat een wijziging raakte: de unittests liepen hier, de integratiesuite daar, een rondgang door de UI met dekking aan ergens anders. Start Coverage Session maakt van de ladingen die volgen één som — elke run wordt regel voor regel als unie bij de vorige opgeteld, een regel die een van hen uitvoerde is gedekt en de tellers tellen op — zodat de gutter, de boom en de score tonen wat ze samen bereikten. De run op het scherm, als die er is, is de eerste van de sessie. Een balk boven de boom zegt hoeveel runs sinds wanneer en beëindigt de sessie; End Coverage Session doet hetzelfde, en de volgende lading staat weer op zichzelf. In Visual Studio start één item onder Tools → Coverage Studio de sessie en beëindigt het haar, aangevinkt.

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).
Een sessie van twee runs: de tweede bij de eerste opgeteld, de balk boven de boom die ze telt.
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, en een tweede run bij de eerste opgeteld — de balk telt twee runs, de regels stijgen van 50.79% naar 68.25%.

De CI-baseline: waar sta ik tegenover main?

Compare with Last Run beantwoordt wat je laatste wijziging deed; vóór een pull request is de vraag waar je staat tegenover main, en het antwoord staat op de buildserver. baseline.report noemt het rapport dat de build van de main-branch publiceert, en elke lading wordt ertegen gehouden: de kaart van de statusbalk draagt de delta van één regel — vs CI baseline: 84.20% → 85.10% (+0.90%), 3 file(s) moved — en Compare with CI Baseline somt de bestanden op die bewogen, bestand voor bestand, in dezelfde woorden als Compare with Last Run. In Visual Studio staat het commando onder Tools → Coverage Studio en haalt of leest het het rapport wanneer je erom vraagt. Drie manieren om het te noemen, in .vscode/settings.json:

  1. Een URL die de CI serveert. GitLab houdt de laatste job-artefacten van een branch op een stabiel adres; het token blijft uit het instellingenbestand via ${env:…} in remote.headers. 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 met Authorization: Bearer ${env:TC_TOKEN}. De URL wordt precies zo opgehaald en gecachet als een coverageFile.paths-URL (ETag, remote.refreshMinutes).
  2. Een bestand dat de pipeline naar een share kopieerde — een absoluut pad zoals \\build\drops\app\main\coverage.cobertura.xml.
  3. Een gedownload artefact onder de map, zeg ci/main.lcov.info (zet de map in .gitignore) — een pad relatief aan de map.
{
  "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}"]
}

Elk formaat dat de lezer kent, voldoet. Een pad dat de CI relatief aan zijn checkout schreef — src/Billing/Invoice.cs, zoals Coverlet het op de runner schrijft — wordt vóór de diff onder deze map geplaatst, zodat het het bestand treft dat de lokale run heeft opgelost; een absoluut pad van een andere machine past nergens op, dus laat de pipeline relatieve paden schrijven. Een baseline die niet opgehaald of gelezen kan worden, is een regel in het Output-paneel, nooit een mislukte lading.

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).
De CI-baseline: de delta op de kaart, en de bestanden die tegenover main bewogen.
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 — statements en takken tegenover het rapport van de unittests, en het bestand dat veranderde.

Een artefact is een zip, en ook die wordt gelezen. GitHub en GitLab leveren een artefact als archief, wat er ook in is gestopt. Noem het rapport erin na een #: het bestand wordt gevonden op zijn pad of op het eind daarvan; zonder # is het het enige bestand van het archief, of het enige bestand erin dat op een rapport lijkt, en waar er meerdere zijn, noemt het Output-paneel ze. Hetzelfde geldt voor een zip die je hebt gedownload (ci/artifact.zip#lcov.info) en, in VS Code, voor een URL in coverageFile.paths. Het token gaat naar de server waarvoor het is ingesteld en niet verder: de omleiding naar de opslag waar het archief staat, wordt zonder token gevolgd.

{
  "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. Voor AI-agents: de dekking op het scherm

Een agent die tests schrijft, kan ze draaien en een percentage lezen. Wat hij uit zichzelf niet kan, is vragen wat de editor weet: welke regels van deze functie nooit liepen, welke kant van welke tak, welke tests een regel uitvoeren, of de diff die hij net schreef gedekt is. Zes tools beantwoorden precies dat, in woorden waar een agent iets mee kan, uit de run die geladen is — dezelfde uitsluitingen, dezelfde remapping, dezelfde cijfers als op het scherm. Zo hebben een agent die de gaten van een functie moet dekken en een reviewer die naar de gutter kijkt, het over dezelfde regels.

ToolWat het beantwoordt
coverage_summaryDe totalen van de run per metriek, en de bestanden die het verst van gedekt af zijn. Het eerste om te vragen.
coverage_gapsWat nooit liep in een bestand, een functie of een bereik van regels: de ongedekte regels, de niet-genomen takarmen, de MC/DC-condities zonder hun paar, de mutanten die overleefden.
tests_for_lineWelke tests een regel uitvoerden, waar het rapport dat zegt — een run per test.
patch_coverageDe dekking van een diff — de working tree tegenover een ref, of een aangeleverde patch — en de regels ervan die nooit liepen.
coverage_deltaWat er verschoof sinds de run ervoor: de totalen, en de bestanden die wonnen of verloren.
test_run_commandDe opdracht die de tests van deze werkruimte draait met dekking aan. De agent voert die uit; de editor herlaadt het rapport vanzelf.

De eigen agent van VS Code heeft ze als tools zonder dat er iets hoeft te worden ingesteld. Alle andere agents — elke client die MCP spreekt, het Model Context Protocol — komen erbij via een server die de editor draait wanneer mcp.enabled aan staat, in VS Code net als in Visual Studio. Copy MCP Server Configuration zet het item voor de client op het klembord, zoals VS Code en Visual Studio het lezen in een mcp.json; een client die de buitenste sleutel mcpServers noemt, neemt hetzelfde item onder die naam.

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 en zijn melding; het token weggelakt.
{
  "servers": {
    "fucini-coverage": {
      "type": "http",
      "url": "http://127.0.0.1:39217/mcp",
      "headers": { "Authorization": "Bearer …" }
    }
  }
  }
  • Hij staat uit tenzij je hem aanzet, en hij luistert alleen op 127.0.0.1: niets van buiten deze machine komt erbij.
  • Een aanroep moet je token dragen, dat één keer wordt gemaakt en voor je wordt bewaard; zonder token is het antwoord 401. De gekopieerde configuratie bevat het token: houd haar buiten de repository.
  • Een aanroep die door een webpagina is verstuurd — dat staat in zijn Origin — wordt geweigerd, wat hij ook draagt.
  • Hij leest de run die geladen is en schrijft niets. De testrun wordt genoemd, niet gestart: de agent voert de opdracht uit in zijn eigen terminal.

De poort is mcp.port, 39217 tenzij anders ingesteld. Waar die bezet is — een tweede venster, de andere editie ernaast — wordt de eerstvolgende vrije gebruikt, en de gekopieerde configuratie noemt de poort die werkt. Het Output-paneel zegt waar de server luistert ([FUCINI_MCP]) en waarom dat niet lukte ([FUCINI_MCP_001]). Wat een plan niet omvat — de namen van tests, MC/DC-details — tellen de tools zonder het uit te schrijven, zoals de hover doet.

15. Opdrachtreferentie

In Visual Studio. Elk commando staat onder Tools → Coverage Studio, genoemd zoals in de tabel zonder het voorvoegsel Fucini Coverage:; de werkbalk van het Coverage-venster en het rechtsklikmenu op een rij hebben de commando's die daar thuishoren, en het rechtsklikmenu van het codevenster heeft de drie die op de editor werken: Run This Test with Coverage, Show Tests That Ran This Line en Exclude Selection from Coverage. Die met toetsen zijn tweetoetsakkoorden na Ctrl+Shift+U: R herlaadt, N en P gaan naar de volgende en de vorige ongedekte regel, B naar de volgende deels geteste beslissing, T somt de tests op die de regel uitvoerden, X sluit de selectie uit — niet VS Code's Alt+N, want in Visual Studio opent Alt met een letter een menu. Wijzig ze onder Tools → Options → Keyboard, waar ze staan als Coverage Studio: …. Niet in deze editie: het Test Coverage-paneel is een VS Code-API — de run staat in plaats daarvan in het Coverage-venster — en Solution Explorer kan geen badges tonen. Alleen in deze editie: Run Native Project with Coverage, voor een C++-startproject.

In Visual Studio: waar alles zit. Het Coverage-venster staat onder View → Other Windows → Coverage, en als eerste onder Tools → Coverage Studio, waar elk commando van deze editie staat, in groepen: laden en herladen, het bestand volgen, de twee kopieeropdrachten en de kaarten; Run Tests with Coverage, Run Native Project with Coverage en Collect Coverage in Test Explorer…; Next en Previous Uncovered en de deels geteste beslissingen; inkleuring, hit counts en de gutter-modi; de coverage-bron van een bestand, de tests die een regel uitvoerden, één test met dekking, de twee manieren om uit te sluiten; Compare with Last Run, Compare Two History Runs…, Compare with CI Baseline, de coverage-sessie en Check Coverage Thresholds; de groep Reports — Show Annotated Source, Open HTML Report, Generate Full HTML Report, Export Coverage Report… en Generate Coverage Badge; dan Getting Started, de compliance-drempels en Licence…. De eigen werkbalk van het venster heeft de vijf die u het vaakst gebruikt: Load Coverage, Reload, Toggle Coverage Painting, Copy Coverage Summary en de compliance-drempels; daaronder het perspectief, het filter en de sortering, en het zoekvak; daaronder de trend. Laat de aanwijzer op een rij van de boom rusten en druk op de ⋯ ervan voor het rijmenu — het bestand openen, de map openen, het pad kopiëren, absoluut of relatief, met beide soorten schuine strepen, het uitsluiten van dekking. Rechts in de statusbalk staan de score van de run en die van het geopende bestand, met de trend sinds de vorige run; Show Coverage Card en Show Coverage Card for This File openen de kaarten erachter, dezelfde kaarten die VS Code toont wanneer de aanwijzer op zijn statusbalkitem rust.

Visual Studio: Tools → Coverage Studio, open, with every command of the edition
In Visual Studio: Tools → Coverage Studio, met elke opdracht van deze editie.
Visual Studio: View → Other Windows, where the Coverage window is
In Visual Studio: View → Other Windows, waar het Coverage-venster staat.
Visual Studio: the Coverage window's toolbar — Load Coverage, Reload, Toggle Coverage Painting, Copy Coverage Summary, compliance thresholds
In Visual Studio: de werkbalk van het Coverage-venster — Load Coverage, Reload, Toggle Coverage Painting, Copy Coverage Summary en de nalevingsdrempels.
Visual Studio: a row's menu in the Coverage window — Open, Open Containing Folder, and the four Copy Path entries
In Visual Studio: het ⋯-menu van een rij — het bestand openen, de map openen, het pad in vier vormen kopiëren.
Visual Studio: the status bar's two items, the run's score and the open file's
In Visual Studio: de twee items in de statusbalk, de score van de run en die van het geopende bestand.
Visual Studio: the run's coverage card, opened by Show Coverage Card
In Visual Studio: de dekkingskaart van de run, via Show Coverage Card.
Visual Studio: the open file's coverage card, opened by Show Coverage Card for This File
In Visual Studio: de kaart van het geopende bestand, via 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: de zweefkaarten in de statusbalk voor de run en het bestand, daarna de werkbalk van de Coverage-weergave, eindigend bij het gegenereerde rapport.
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: het statusbalkmenu — een dekkingsbestand kiezen, tests met dekking draaien, herladen, het rapport openen, de gutter-modus kiezen.
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, laagste dekking eerst, met de CRAP-score waar het rapport complexiteit bevat.
OpdrachtWat het doet
Load CoverageDekking voor de werkruimte vinden en laden. Standaard Alt+Shift+R (Ctrl+Alt+R op macOS).
Pick Coverage FileKies tracebestanden — één, meerdere, of telkens een extra; keuzes tellen op, worden samengevoegd en naar coverageFile.paths geschreven, zodat ze voortaan vanzelf laden.
Show Loaded Coverage FilesToon de tracebestanden in de actieve run. De Dekkingsweergave toont ze ook, elk met een verwijderknop en een kiesknop ernaast.
Toggle Tracefile WatchTracebestand(en) bewaken op wijzigingen en automatisch herladen.
Run Tests with CoverageHerken de testrunner, draai hem met dekking aan in een terminaltaak, laad wat hij schrijft en bied aan het pad aan de instellingen toe te voegen.
Run This Test with CoverageDe test onder de cursor — de methode, de klasse of het describe-blok, of het bestand — gedraaid met het recept daartoe versmald, en dan geladen als elke run. Ook in het contextmenu van de editor.
Show Tests That Ran This LineWaar het rapport zegt welke tests wat uitvoerden, de tests opsommen die de regel onder de cursor uitvoerden, de drukste eerst, en de gekozen test openen waar hij geschreven staat.
Run Tests Affected by My Changes…De tests opsommen die een regel uitvoerden die de working tree wijzigt tegenover testImpact.baseRef, de gekozen test openen, of alleen die tests draaien waar de rapporten uit een run per test komen.
Show Minimal Test Set…De minste tests die nog elke regel uitvoeren die de suite uitvoert, dan de tests die geen eigen regel toevoegen.
Run App with Coverage…De .NET-app van de map starten onder dotnet-coverage, en wanneer hij sluit laden wat je hebt doorlopen.
Run Mutation Tests HereDe functie waarin de cursor staat — of de selectie, of het bestand — muteren met Stryker.NET, StrykerJS of PIT, en het rapport laden naast de dekking op het scherm.
Exclude This File from Coverage / Exclude from CoverageHet geopende bestand — of, op een rij van de Coverage-weergave, het bestand of de /** van de map — in fuciniCoverage.ignore in de instellingen van de map zetten, eenmalig.
Exclude Selection from CoverageDe uitsluiting schrijven waar de code staat: [ExcludeFromCodeCoverage] boven een .NET-lid, LCOV_EXCL_LINE op één regel, LCOV_EXCL_START/STOP rond meerdere, in het eigen commentaarteken van het bestand. Ook via het lampje en het contextmenu van de editor.
Start Coverage Session / End Coverage SessionZolang een sessie loopt, wordt elke lading als unie bij de vorige opgeteld; een balk boven de boom telt de runs en beëindigt haar.
Next / Previous UncoveredSpringen tussen niet-gedekte regio’s. Standaard Alt+N / Alt+P (Ctrl+Alt+N / Ctrl+Alt+P op macOS).
Choose Editor Gutter Mode...Uit, balken alleen op ongedekte regels, rood-amber-groene balken, of een heatmap van trefferaantallen in de gutter van de editor.
Cycle Editor Gutter ModeEén stap verder door off, uncovered, coverage en heatmap — Alt+G, of de modusknop in de statusbalk.
Choose Coverage Source for This File...Wanneer meer dan één geladen rapport het open bestand meet, kies je uit welk rapport de cijfers komen, voor het bestand, de map ervan of een patroon — schrijft een regel in coverageFile.sources.
Clear Coverage Source for This File...Verwijder de regels in coverageFile.sources die voor het open bestand gelden.
Toggle Inline Hit CountsDe ×N-uitvoeringsaantallen achter elke regel tonen of verbergen — schakelt hitCounts.inline om.
Show in Test Coverage ViewDe actieve run publiceren naar het eigen Test Coverage-paneel van VS Code (ook met testCoverage.publish uit) en het openen.
Suggest Path Remap RuleDe pathRemap-regel afleiden die de niet-overeenkomende bestanden van de actieve run aan de werkruimte zou koppelen, en aanbieden die toe te voegen.
What Community IncludesElke limiet en achtergehouden functie van het gratis niveau in één lijst, met hoeveel van elke limiet is gebruikt.
Open HTML ReportHet gegenereerde statische rapport openen.
Generate Full HTML ReportHet rapport met meerdere pagina’s bouwen.
Open Annotated Source / …to the SideGeannoteerde coverageweergave voor een bestand.
Toggle Annotated SourceWisselen tussen bron en geannoteerde weergave. Standaard Alt+A (Ctrl+Alt+A op macOS).
Show Worst-Covered Files / Folders / FunctionsQuick Pick, laagste eerst gerangschikt.
Copy Uncovered LinesMarkdown-samenvatting van elk niet-gedekt bereik.
Compare Two History Runs / with Last RunRegressiediff per bestand — twee runs uit de geschiedenis, of de run op het scherm tegen die hij verving.
Compare with CI BaselineDe geladen run tegen het rapport dat baseline.report noemt — dat van de main-branch uit CI, een URL of een gedownload artefact — bestand voor bestand.
Show Indirect Coverage Changes…De regels waarvan de dekking verschoof terwijl niemand ze bewerkte, tegenover de CI-baseline of de run ervoor, per bestand.
Check Coverage ThresholdsDe compliancepoorten evalueren.
Export Fucini JSONDe huidige run exporteren als Fucini JSON.
Export Coverage Report...Kies een formaat — CSV, Markdown, LCOV, Cobertura-XML, SARIF of een SVG-badge — en een bestemming.
Generate Coverage BadgeDe SVG-badge voor de actieve run naar badge.outputPath schrijven, met badge.metric erop, en aanbieden hem te openen.
Copy MCP Server ConfigurationWat een MCP-client nodig heeft om naar de dekking op het scherm te vragen — het adres van de server en je token — op het klembord zetten; staat de server uit, dan aanbieden hem aan te zetten.
Show Status Bar MenuHet snelactiemenu openen.
Browse for External HTML Report / Full Report Output Dir…De rapportmappen instellen via een kiezer.

16. Instellingenreferentie

De volledige, gecategoriseerde instellingentabel — elke optie met zijn standaardwaarde — staat op de pagina Features & Settings. Alle sleutels hebben het voorvoegsel fuciniCoverage..

Het is de moeite waard om te noemen: fuciniCoverage.language zet de eigen runtime-UI van deze extensie (statusbalk, meldingen, tooltips, webviews) vast op een specifieke taal, onafhankelijk van de Display Language van VS Code — standaard auto, met bundels voor alle 18 ondersteunde talen. Het verandert niet de Command Palette-items of de labels van de Instellingen-UI, die VS Code zelf uit zijn eigen Display Language haalt.

In Visual Studio. Dezelfde fuciniCoverage.*-sleutels, gelezen uit maximaal vier bestanden, waarbij het latere wint: de eigen gebruikersinstellingen van VS Code als VS Code op de machine staat — gelezen, nooit geschreven, zodat uw kleuren en drempels meekomen; %APPDATA%\Fucini\CoverageStudio\settings.json, de gebruikersinstellingen van deze editie; .vscode\settings.json in de map of naast de solution, zodat een repository die voor VS Code is ingericht ook voor Visual Studio is ingericht; en fucini-coverage.json in de hoofdmap van de solution, voor een team dat liever geen .vscode-map in een .NET-repository houdt — de VS Code-editie leest het ook. Het tandwiel in de werkbalk van het Coverage-venster opent een instellingenvenster dat het gebruikersbestand of het bestand van de map dat bestaat schrijft, zoals zijn Write changes to-keuze zegt, en de commentaren bewaart van een bestand dat het bewerkt. fuciniCoverage.language werkt daar op dezelfde manier; de menu's volgen de eigen taal van Visual Studio.

17. Foutcodes

Diagnostiek gaat naar het uitvoerkanaal Fucini Coverage (View → Output → Fucini Coverage), elk met een stabiele FUCINI_*-code.

In Visual Studio. Dezelfde codes gaan naar het Fucini Coverage-paneel van het Output-venster (View → Output) en worden bewaard in %LOCALAPPDATA%\Fucini\CoverageStudio\coverage-studio.log, voor de vraag die komt nadat de IDE gesloten is. Drie die voorkomen: er is niets gemarkeerd hoewel het paneel zegt dat er bestanden zijn geladen — de guttermodus is off, kies Show Coverage in Editor; FUCINI_REMAP_001 en een informatiebalk — het rapport noemt paden die hier niet bestaan, en het paneel stelt de pathRemap-regel voor; het Coverage-venster zegt dat het WebView2 nodig heeft — installeer de Microsoft Edge WebView2 Runtime, de markeringen in de editor hebben hem niet nodig.

CodeBetekenis
FUCINI_PARSE_001Niet-ondersteund/onherkend coverageformaat — geen enkele parser paste bij het bestand.
FUCINI_PARSE_010lcov-bestand bevatte geen SF-records.
FUCINI_PARSE_020llvm-cov-JSON ongeldig, data[] ontbreekt of bevatte geen bestanden.
FUCINI_PARSE_030Cobertura-root <coverage> ontbreekt of XML is ongeldig.
FUCINI_PARSE_040JaCoCo-root <report> ontbreekt of geen bronbestanden.
FUCINI_PARSE_050Istanbul/SimpleCov-JSON ongeldig of bevatte geen bestanden.
FUCINI_PARSE_060SimpleCov-JSON ongeldig of mist een files-array op het hoogste niveau.
FUCINI_PARSE_070Go-profiel zonder mode:-kop, of zonder dekkingsblokken.
FUCINI_PARSE_080Clover-root <coverage> of <project> ontbreekt, of er staan geen bestanden in.
FUCINI_PARSE_090OpenCover-root <CoverageSession> ontbreekt, of er staan geen bestanden in.
FUCINI_PARSE_100coverage.py-JSON ongeldig of zonder files-object op het hoogste niveau.
FUCINI_PARSE_110gcov/gcovr-JSON ongeldig of zonder files-array op het hoogste niveau.
FUCINI_PARSE_120GNATcoverage-XML zonder <source>-element, of een index.xml waarvan de xi:includes nooit zijn opgelost — laad in plaats daarvan de *.xml-bestanden per bronbestand.
FUCINI_PARSE_130BullseyeCoverage-hoofdelement <BullseyeCoverage> ontbreekt, of bevat geen <src>-elementen.
FUCINI_PARSE_140Hoofdelement <CoverageDSPriv> ontbreekt, geen <SourceFileNames>-tabel om regelrijen mee op te lossen, of geen regelgegevens.
FUCINI_PARSE_150Xcode-dekkings-JSON ongeldig, of een targets-array op het hoogste niveau ontbreekt.
FUCINI_PARSE_160SonarQube-hoofdelement <coverage> ontbreekt, of bevat geen <file>-elementen.
FUCINI_PARSE_170Coveralls-JSON ongeldig, of een source_files-array op het hoogste niveau ontbreekt.
FUCINI_LOADEen lading is geannuleerd vanuit haar voortgangsmelding; de vorige run, als die er is, blijft geladen.
FUCINI_REMOTE_001Een URL in coverageFile.paths kon niet worden opgehaald, met de reden; in plaats daarvan wordt de laatst gedownloade kopie geladen. Gewone [FUCINI_REMOTE]-regels leggen elke download en elke ongewijzigd-controle (304) vast.
FUCINI_REMOTE_002Een URL in coverageFile.paths gaf binnen 30 seconden geen volledig antwoord — meestal een proxy of VPN die de verbinding accepteert en daarna zwijgt; in plaats daarvan wordt de laatst gedownloade kopie geladen.
FUCINI_REMOTE_003Een URL in coverageFile.paths antwoordde met een HTML-pagina in plaats van een tracefile — hoogstwaarschijnlijk een aanmeldpagina. De pagina wordt niet gecachet en in plaats daarvan wordt de laatst gedownloade kopie geladen; controleer het token in remote.headers.
FUCINI_REMAP_002Een pathRemap-regel is voorgesteld voor de paden die een lading zonder overeenkomst achterliet, met hoeveel ervan hij verklaart — of er kon geen worden afgeleid, of de afgeleide regel staat al in de instelling en heeft ze niet opgelost.
FUCINI_REMAP_003De voorgestelde regel is door Apply Suggested Remap toegevoegd aan fuciniCoverage.pathRemap en de dekking wordt opnieuw geladen.
FUCINI_GITDIFF_001De Git-extensie is niet beschikbaar; de diff-dekking wordt overgeslagen en de hele run wordt getoond.
FUCINI_GITDIFF_002gitDiff.baseRef begint met -, waarmee geen enkele git-ref kan beginnen (git zou het als optie lezen); de diff-dekking wordt overgeslagen en de hele run wordt getoond.
FUCINI_IGNOREHoeveel bestanden fuciniCoverage.ignore uit de run heeft weggelaten, en welke.
FUCINI_UNMEASURED_001De bestanden van de soort van de run die geen test heeft geladen, één per regel.
FUCINI_UNMEASURED_002Meer dan 5.000 werkruimtebestanden kwamen overeen met een van de extensies van de run; alleen de eerste 5.000 zijn voor de lijst Unmeasured in aanmerking genomen.
FUCINI_UNMEASURED_003In de modus count worden sommige ongemeten bestanden opgesomd maar niet meegeteld: de leeslimiet (2.000 bestanden of 50 MB per lading) is bereikt.
FUCINI_UNMEASURED_004Een ongemeten bestand kon niet worden gelezen; het wordt opgesomd maar niet meegeteld.
FUCINI_TESTCOVERAGEHoeveel bestanden naar de Test Coverage-weergave van VS Code zijn gepubliceerd.
FUCINI_BADGEDe badge is geschreven, met zijn pad, label en waarde.
FUCINI_BADGE_001De badge kon niet worden geschreven, met de reden.
FUCINI_WORKSPACEEen map is aan de werkruimte toegevoegd of eruit verwijderd; de dekking wordt opnieuw gedetecteerd.
FUCINI_VARIABLESWat elke ${command:…} in de padinstellingen antwoordde, of waarom die bleef staan zoals geschreven: het commando mislukte, gaf niets bruikbaars terug, of de werkruimte is niet vertrouwd.
FUCINI_WATCHWat de watcher doet: de paden die worden bewaakt, een geconfigureerd bestand dat is verschenen, een taak uit watch.reloadAfterTasks die is geëindigd (met haar exitcode) en een herlading heeft gestart, of een pad onder files.watcherExclude dat in plaats daarvan wordt gepeild.

18. Privacy

Telemetrie wordt geregeld door de window-scoped instelling telemetry.enabled. Standaard staat hij uit. De dagelijkse samenvatting en de verwijdermelding vereisen daarnaast dat de globale telemetry.telemetryLevel van VS Code telemetrie toestaat; de installatieping en een paar kleine gebeurtenissen worden hoe dan ook verstuurd, en dat geldt ook voor de vermelding in het gebruiksregister van een installatie in de proefperiode of op het gratis Community-niveau. Op Community ruilt Unlock Full Features deze telemetrie voor elke Pro-functie, MC/DC inbegrepen, gedurende 30 dagen, één keer per machine — zet hem weer uit en de standaard Community-set geldt; een betaalde licentie wordt hoe dan ook niet beïnvloed. Zie het privacybeleid voor wat er wordt verstuurd.

Twee dingen zijn het waard om te weten, omdat je er iets mee kunt. Het eerste is je gebruiksregister-ID: in de proefperiode en op Community toont de extensie hem onder Show License / Activation en onderaan What Community Includes, waar het selecteren van de rij hem kopieert en het privacybeleid opent. Het register kent je machine aan een hash en aan niets anders, dus die ID is de enige manier om te vragen wat het over jou bevat, het te laten verwijderen of er bezwaar tegen te maken — noem hem en we vinden je rij; zonder hem kunnen we dat niet. Het tweede is het installatierecord: één rij, geschreven de eerste keer dat een installatie zich meldt en bewaard in plaats van na 90 dagen verwijderd, met de installatie-identificatie, de dag, de plaats waarnaar het adres werd herleid, de versies en het besturingssysteem — niet het adres zelf, en niets over je code. Het is wat ons in staat stelt te zeggen hoeveel installaties er door de jaren heen zijn geweest. Beide worden volledig beschreven in het privacybeleid, en beide worden verwijderd als je erom vraagt.

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
Het einde van What Community Includes: hoe de limieten worden geteld, en de rij die je je gebruiksregister-ID aanreikt.

19. Evaluatie & activering

Fucini Coverage Studio wordt uitgebracht als evaluatie-prerelease. Bij de eerste start wordt je gevraagd akkoord te gaan met het evalueren ervan, waarna de proefperiode begint — elke functie is beschikbaar tijdens een proefperiode van 14 dagen, gerekend vanaf de eerste keer dat je hem op die installatie gebruikt. Er is geen vaste datum waarna er iets stopt.

Vanaf versie 2.2026.2 begint de proefperiode van een nieuwe installatie zodra de extensie de licentieserver één keer heeft bereikt; tot dan draait ze op het Community-niveau en meldt ze dat. In een ontwikkelcontainer of een Codespace begint geen proefperiode — een abonnementscode, een sleutel of de 7-dagenpas ontgrendelt daar de volledige set.

Als de proefperiode afloopt wordt er niets afgesloten: de extensie valt terug op het gratis Community-niveau. Wil je de volledige set terug, activeer dan — activering maakt verbinding met de licentieserver en past de teruggegeven sleutel automatisch toe, zonder e-mail en zonder een sleutel die je met de hand moet overnemen:

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. Voer Fucini Coverage: Show License / Activation uit (ook bereikbaar vanaf de statusbalk zodra de proefperiode/sleutel is verlopen) en klik op Request License… (of Request Renewed Key… als je eerder hebt geactiveerd).
  2. Bevestig de aanvraag. De sleutel wordt automatisch uitgegeven, en je contactgegevens uit een eerdere aanvraag worden hergebruikt in plaats van opnieuw gevraagd.
  3. Dat is alles. De activeringssleutel wordt gegenereerd en automatisch naar fuciniCoverage.license.key geschreven. De statusbalk schakelt binnen een moment van de proefperiode over naar een geactiveerde licentie.

De handmatige route in één beeld: open het licentiepaneel, kies Enter Key, plak de sleutel uit uw e-mail en de banner slaat om naar “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).

Mocht de geautomatiseerde aanvraag ooit mislukken (geen verbinding, serverprobleem): voer Fucini Coverage: Copy Activation Request Code uit, stuur de code via de contactpagina of naar info@fucini.consulting, en plak de FCK1.…-sleutel die je terugkrijgt met Fucini Coverage: Enter Activation Key (of rechtstreeks in settings.json):

{ "fuciniCoverage.license.key": "FCK1.…plak hier de hele sleutel…" }

De naam van de instelling is fuciniCoverage.license.key (user/global-bereik). De sleutel is gebonden aan je machine en OS-gebruiker, kan een vervaldatum hebben, en kan afzonderlijke functies in- of uitschakelen en het aantal coverage-ladingen per dag beperken. Als de melding “invalid for this machine” verschijnt, vraag dan vanuit deze installatie een nieuwe sleutel aan — een sleutel die voor een andere machine is uitgegeven, wordt hier nooit geldig.

In Visual Studio. Die editie heeft geen gratis niveau: zonder abonnement wordt er niets gelezen. Met een abonnement bepaalt het plan daar wat het in VS Code bepaalt — een functie die buiten het plan valt, wordt achtergehouden, en de opdracht ervan zegt dat in plaats van te draaien. Ook de oudste versie die de licentieserver nog ondersteunt, geldt daar: een oudere build meldt dat één keer per dag, met de datum waarop hij ophoudt te werken, en werkt tot dan door. Offline zijn houdt een build nooit tegen.

De gratis Community-laag: een weektegoed

Community stopt nooit met het tonen van coverage. De gutters, de overzichtsliniaal, hovers, CodeLens, de Coverage-weergave, de watch-modus, diff-coverage en de geschiedenis worden helemaal niet geteld, en het laden van een tracefile via een opdracht is alleen begrensd op 25 per dag. Wat wel wordt gemeten is uitvoer: elk vijf per week voor het openen van het HTML-rapport, exporteren, het vergelijken van twee runs, het controleren van de drempelwaarden en het bekijken van de geannoteerde broncode op dezelfde plek.

Een week is van jou, niet van de kalender: hij begint bij het eerste gebruik en eindigt zeven dagen later. Als een tegoed op is, noemt de melding de actie en de dag waarop het terugkomt, en na die ene melding vermeldt alleen de statusbalk het nog. Fucini Coverage: What Community Includes toont elk tegoed, met hoeveel er is gebruikt en wanneer het wordt vernieuwd, nog voordat je er ooit een bereikt.

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).

Drie details horen bij de betaalde abonnementen, terwijl de bevindingen gratis blijven: Community markeert elke regel met overlevende mutanten en zegt hoeveel het er zijn, maar niet wat elke mutant heeft gewijzigd; het zegt hoeveel tests een regel hebben uitgevoerd, maar niet hun namen; en het toont de Max CRAP van een run, maar niet de gerangschikte lijst 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).

Gebruikte je Community al toen het weektegoed kwam (0.2026.83), dan blijven je eerdere limieten 30 dagen gelden; je krijgt dat één keer te horen, met de datum. De tellers worden op je eigen machine bewaard – in de eigen opslag van VS Code en in ~/.fucini-coverage/, zodat een nieuw VS Code-profiel dezelfde week voortzet – en worden nooit ergens naartoe verzonden.

De 7-dagenpas

Nog niet toe aan een abonnement? Een 7-dagenpas is alles van Pro voor één week, één keer betaald: er wordt niets verlengd en er valt niets op te zeggen. Koop hem op de prijspagina (de melding bij een Community-limiet heeft er een knop voor), en de activatiecode komt 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. Voer Fucini Coverage: Enter Subscription Code uit – de opdracht bestaat zowel in de Community-editie als in Pro.
  2. Kies Pro en plak de code FCB1-… uit de e-mail.
  3. Dat is alles. De sleutel wordt voor je uitgegeven en toegepast, en werkt offline. De week loopt vanaf de betaling, dus activeer zodra je koopt. Als de week voorbij is, keert de extensie vanzelf terug naar Community en blijft ze coverage tonen.
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. Dezelfde code activeert Fucini Coverage Studio voor Visual Studio, 2022 en 2026: open Tools → Coverage Studio → Licence…, plak de code, kies het plan waarvoor hij is en druk op Activate. Het Coverage-venster zegt dan Activated boven de boom; opengeklapt met het pijltje toont de rij tot welke datum de sleutel geldig is en een knop naar uw account. Eén machine is één seat: activeer VS Code of Visual Studio, en de andere editor op dezelfde machine volgt vanzelf — Visual Studio leest de sleutel van VS Code en VS Code die van Visual Studio — dus niets wordt twee keer ingevoerd en er wordt geen tweede seat ingenomen. Beide houden een sleutel op dezelfde manier in leven: Pro Plus, Business en Enterprise melden zich twee keer per dag, en een Pro-sleutel wordt vernieuwd in de week voordat hij verloopt.

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

Naar een nieuwe computer, en seats beheren

Een sleutel is aan één machine gebonden, dus een nieuwe computer heeft een nieuwe nodig — en je abonnement betaalt voor niet meer machines dan er staat. Geef de oude zelf vrij: log in bij je abonnement beheren, zoek de seat die je niet meer gebruikt, kies Free up en activeer daarna de nieuwe machine met dezelfde code. Bij de aankoop van Pro krijg je geen wachtwoord toegestuurd — je account bestaat wel, het heeft er alleen nog geen, dus gebruik de eerste keer wachtwoord instellen of opnieuw instellen met het adres waarmee je je hebt geabonneerd.

Bij Business en Enterprise nodig je elke collega per e-mail uit vanaf diezelfde pagina. Iedereen krijgt een activatiecode die alleen van hem is, en zodra hij die gebruikt verschijnt zijn adres bij zijn seat — vertrekt er iemand, dan zie je welke seat van hem was en maak je die vrij voor de volgende. Een uitnodiging houdt een seat bezet vanaf het moment dat je hem verstuurt en verloopt na 14 dagen als hij ongebruikt blijft; trek hem in om de plek meteen terug te krijgen.

Pre-releasebuilds testen

Nieuw werk bereikt fucini.software voordat het de Marketplace bereikt, en je kunt vragen om het aangeboden te krijgen. Open de Coverage-weergave, klap het licentiepaneel uit en druk op Pre-releasebuilds testen… — of zet fuciniCoverage.update.preRelease. Vanaf dan controleert de extensie hier een aparte pre-releasefeed naast de gewone, en biedt ze de nieuwste van de twee aan.

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).

Pre-releases zijn getest, maar het zijn de builds waarover we het minst zeker zijn — je meldt je vrijwillig om te vinden wat wij hebben gemist. Meedoen vertelt ons dat deze installatie in het kanaal zit, zodat we weten hoeveel mensen er testen en kunnen vertellen wat er is veranderd; stoppen zet je bij de volgende stabiele versie terug op het gewone pad. Er is niet altijd een pre-release, en meedoen terwijl er geen is kost niets: de extensie vindt een lege feed, zegt daar niets over en blijft stabiele versies aanbieden tot er een wordt gepubliceerd.

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. Contact & licentie

Vragen, bugmeldingen of alternatieve licentievoorwaarden — zie de contactpagina of mail naar info@fucini.consulting. Gelicentieerd onder MIT met een attributievoorwaarde in de release notes; zie ook de Notice.

21. Op de opdrachtregel

De lezer draait ook zonder editor: npm install -g fucini-coverage, gratis, op Windows, Linux, WSL en macOS. fucini-coverage check coverage/lcov.info --lines 80 is de gate waarop een pipeline faalt; summary, export, report, badge en compare doen wat de gelijknamige opdrachten van de editors doen, en mcp serveert de zes tools uit de sectie hierboven aan een agent op een server. Hij leest fucini-coverage.json, het instellingenbestand dat de Visual Studio-editie leest, zodat de drempels één keer worden ingesteld. fucini-coverage help <command> legt elke opdracht uit; de volledige pagina is fucini-coverage op 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).