Fucini Coverage Studio는 언어 기반이 아니라 포맷 기반입니다. 툴체인이 지원되는 25가지 포맷 중 하나를 출력할 수 있는 언어라면 모두 동작합니다. 아래는 컴파일러별 구체적인 레시피입니다. 명령은 <pre> 블록에 있습니다 — 그대로 복사하고 이름/경로를 프로젝트에 맞게 조정하세요.
| 포맷 | 대표 파일 | 언어 |
|---|---|---|
| LCOV | lcov.info | C, C++, Rust, Go |
| llvm-cov JSON | coverage.json | C, C++, Obj-C, Rust, Swift |
| Cobertura XML | coverage.xml | Python, .NET/C#, JS, PHP |
| JaCoCo XML | jacoco.xml | Java, Kotlin, Scala, Groovy |
| Istanbul / nyc | coverage-final.json | JavaScript, TypeScript |
| SimpleCov | .resultset.json | Ruby |
| Clover XML | clover.xml | PHP, JavaScript |
| OpenCover XML | coverage.opencover.xml | .NET/C#, VB.NET |
| coverage.py JSON | coverage.json | Python |
| gcov / gcovr JSON | gcov --json-format, gcovr --json | C, C++ |
| Go coverage profile | coverage.out | Go |
| gcov plain text | *.gcov | C, C++ (pre-GCC 9 toolchains) |
| VectorCAST | coverage.xml | C, C++, Ada |
| Testwell CTC++ | *.txt (ctcpost) | C, C++ |
| Lauterbach TRACE32 | *.xml | Any target the debugger traces |
| EMMA XML | coverage.xml | Java, Delphi / Object Pascal |
| UCIS / Aldec UCDB | *.xml | VHDL, Verilog, SystemVerilog |
| NCover XML | Coverage.xml | .NET / C# |
| dotCover DetailedXML | dotCover.xml | .NET / C# |
| PIT / Stryker (mutation) | mutations.xml, mutation-report.json | Java, Kotlin, Scala, JS, TS, C# |
Swift llvm-cov JSON
Swift는 내부적으로 LLVM을 사용하므로, 테스트 바이너리와 병합된 프로파일에서 llvm-cov export --format=json으로 JSON을 내보냅니다.
# 1. Run tests with coverage (Swift Package Manager)
swift test --enable-code-coverage
# 2. Resolve the profdata and test-binary paths
PROF=$(swift build --show-bin-path)/codecov/default.profdata
BIN=$(swift build --show-bin-path)/<PackageName>PackageTests.xctest/Contents/MacOS/<PackageName>PackageTests
# Linux: BIN=$(swift build --show-bin-path)/<PackageName>PackageTests.xctest
# 3. Export JSON
xcrun llvm-cov export "$BIN" -instr-profile "$PROF" -format=json > coverage.json
# Linux (no xcrun): llvm-cov export "$BIN" -instr-profile "$PROF" -format=json > coverage.json
Xcode 프로젝트: xcodebuild test -enableCodeCoverage YES -derivedDataPath ./DerivedData로 빌드한 뒤 DerivedData 아래에서 .profdata와 앱 바이너리를 찾아 동일한 llvm-cov export를 실행합니다.
Swift / Objective-C — Xcode report xccov JSON
The shortest path from an .xcresult: no profdata hunting, no binary paths, one command. Use it when you want percentages and per-function coverage quickly.
# 1. Run the tests
xcodebuild test -scheme MyApp -enableCodeCoverage YES -derivedDataPath ./DerivedData
# 2. Export the coverage report from the .xcresult
xcrun xccov view --report --json \
./DerivedData/Logs/Test/*.xcresult > coverage.json
Gutters stay empty for this format, by design. xccov reports how many of a file's lines are executable and how many were covered, but not which — that answer needs one xccov view --file run per file. Studio will not invent the missing line numbers, because an invented gutter is indistinguishable from a measured one. You get file percentages, per-function execution counts, CodeLens and the worst-covered rankings. For line-by-line highlighting, use the llvm-cov route above against the same build, or slather for Cobertura.
C / C++ — Clang / LLVM llvm-cov JSON
가장 풍부한 입력: 문장, 분기, 함수, 리전, MC/DC 및 C++ 템플릿 인스턴스화 커버리지. C/C++에 권장.
# 1. Compile with instrumentation (add -fcoverage-mcdc on Clang 18+ for MC/DC)
clang++ -fprofile-instr-generate -fcoverage-mapping -o app main.cpp
# 2. Run the instrumented binary
LLVM_PROFILE_FILE="app.profraw" ./app
# 3. Merge raw profiles
llvm-profdata merge -sparse app.profraw -o app.profdata
# 4. Export JSON
llvm-cov export ./app -instr-profile=app.profdata -format=json > coverage.json
C / C++ — GCC LCOV / gcov JSON
GCC는 lcov(또는 gcovr)가 lcov.info로 바꾸는 .gcda/.gcno 데이터를 생성합니다. gcov와 gcovr이 직접 쓰는 JSON도 읽히므로 변환 단계를 완전히 건너뛸 수 있습니다 — 다만 gcov --json-format은 --stdout을 주지 않으면 출력을 gzip으로 압축합니다.
# 1. Compile with coverage flags (--coverage == -fprofile-arcs -ftest-coverage)
gcc --coverage -O0 -o app main.c
# 2. Run the binary (writes .gcda next to .gcno)
./app
# 3. Capture lcov.info and drop system/test files
lcov --capture --directory . --output-file lcov.info
lcov --remove lcov.info '/usr/*' '*/test/*' --output-file lcov.info
# Alternative: no conversion at all — native JSON
# gcovr --json coverage.json
# gcov --json-format --stdout app.gcda > coverage.json
# Alternative: gcovr straight to Cobertura or lcov
# gcovr --lcov lcov.info
# gcovr --cobertura coverage.xml
GCC 버전에 맞는 gcov를 사용하세요(예: gcc-13에는 gcov-13). 그렇지 않으면 .gcda에서 버전 불일치가 발생합니다.
Rust LCOV / llvm-cov JSON
가장 쉬운 방법은 Rust의 LLVM 계측을 대신 처리해 주는 cargo-llvm-cov(cargo install cargo-llvm-cov)입니다.
# LCOV
cargo llvm-cov --lcov --output-path lcov.info
# llvm-cov JSON (richer metrics)
cargo llvm-cov --json --output-path coverage.json
# Manual, without cargo-llvm-cov:
# RUSTFLAGS="-C instrument-coverage" cargo test
# llvm-profdata merge -sparse default_*.profraw -o cov.profdata
# llvm-cov export target/debug/<testbin> -instr-profile=cov.profdata -format=json > coverage.json
Go Go coverage profile
Go의 기본 프로파일은 곧바로 읽힙니다 — 변환 단계가 없습니다. coverage.out은 탐색이 찾는 파일 이름 중 하나이기도 하므로 Go 프로젝트에는 설정이 전혀 필요 없습니다.
# Run tests with a coverage profile — that is the whole recipe
go test ./... -coverprofile=coverage.out
# Converting still works if your pipeline already does it:
# go install github.com/jandelgado/gcov2lcov@latest
# gcov2lcov -infile=coverage.out -outfile=lcov.info
Python coverage.py JSON
coverage.py(또는 pytest-cov)를 사용해 기본 JSON을 생성하세요. Cobertura 내보내기보다 이쪽을 권합니다. 어떤 줄이 # pragma: no cover로 제외됐는지 기록하는 것은 JSON뿐이며, Studio는 그 구분을 유지해 해당 줄을 덮였다고도 놓쳤다고도 세지 않습니다.
# coverage.py — native JSON (recommended)
coverage run --branch -m pytest
coverage json # -> coverage.json
# The Cobertura export still works
coverage xml # -> coverage.xml (Cobertura)
# or pytest-cov in one step
pytest --cov=my_package --cov-report=xml
Java / Kotlin JaCoCo XML
JaCoCo는 Studio가 읽는 XML 보고서를 생성합니다 — XML 포맷이 켜져 있는지 확인하세요(HTML 보고서는 읽지 않습니다).
# Maven (jacoco-maven-plugin configured, XML format on)
mvn test
# -> target/site/jacoco/jacoco.xml
# Gradle
# build.gradle: jacocoTestReport { reports { xml.required = true } }
./gradlew test jacocoTestReport
# -> build/reports/jacoco/test/jacocoTestReport.xml
JavaScript / TypeScript Istanbul / nyc
Istanbul은 (nyc, Jest 또는 Vitest를 통해) coverage-final.json을 생성합니다. Clover와 Cobertura 리포터도 읽힙니다 — Vitest는 기본으로 Clover를 쓰므로 Vitest 프로젝트에는 Studio가 열 수 있는 파일이 이미 있는 경우가 많습니다.
# nyc
npx nyc --reporter=json mocha # -> coverage/coverage-final.json
# Jest (Istanbul built in)
jest --coverage --coverageReporters=json
# Vitest
vitest run --coverage --coverage.reporter=json
# Clover --coverageReporters=clover (-> coverage/clover.xml)
# Cobertura --coverageReporters=cobertura (-> cobertura-coverage.xml)
.NET / C# OpenCover / Cobertura XML
dotnet test 중에 coverlet으로 커버리지를 수집하세요. 두 XML 형식 모두 읽히지만, 분기의 각 갈래마다 방문 횟수를 기록하는 OpenCover를 권합니다. Cobertura는 몇 개의 갈래가 덮였는지만 알려 줍니다.
# OpenCover — keeps per-arm branch counts (recommended)
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
# -> coverage.opencover.xml
# Cobertura, via Coverlet's data collector
dotnet test --collect:"XPlat Code Coverage"
# -> TestResults/<guid>/coverage.cobertura.xml
PHP Clover XML
커버리지 드라이버로 Xdebug 또는 PCOV를 지정해 PHPUnit을 실행하고 Clover를 출력하세요. php-code-coverage가 기본으로 생성하는 형식이며, 대부분의 프로젝트에 이미 설정되어 있습니다. 파이프라인이 대신 Cobertura를 낸다면 그것도 읽습니다.
XDEBUG_MODE=coverage phpunit --coverage-clover clover.xml
# phpunit.xml alternative:
# <coverage><report><clover outputFile="clover.xml"/></report></coverage>
# Cobertura also works:
# XDEBUG_MODE=coverage phpunit --coverage-cobertura coverage.xml
Ruby SimpleCov
SimpleCov의 JSON 포매터(gem 'simplecov-json')를 설정해 기계가 읽을 수 있는 coverage.json이 작성되도록 합니다.
# test_helper.rb / spec_helper.rb (before loading your code)
require 'simplecov'
require 'simplecov-json'
SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
SimpleCov.start
# then run your tests normally
rake test # or: rspec
# -> coverage/coverage.json (or .resultset.json)
Ada — GNATcoverage GNATcov XML
The format DO-178C and EN 50128 teams actually produce. --annotate=xml writes a directory, not a file: load the per-source *.xml files, several at once if you like.
# 1. Instrument and build
gnatcov instrument --level=stmt+mcdc --projects my_project.gpr
gprbuild -P my_project.gpr --src-subdirs=gnatcov-instr --implicit-with=gnatcov_rts
# 2. Run, then produce XML
gnatcov coverage --level=stmt+mcdc --annotate=xml \
--output-dir=coverage/ my_project.gpr obj/my_program.srctrace
# -> coverage/*.xml (one per source; index.xml is just a directory listing)
A partially covered line (!) stays a covered line with an uncovered decision — the shortfall appears in branch and MC/DC coverage, where it belongs, rather than being written off as an uncovered line. pragma Annotate (Xcov, Exempt_On) regions become excluded lines. With --level=stmt+mcdc, MC/DC drives the compliance gate and the composite score.
C / C++ — BullseyeCoverage Bullseye XML
The commercial tool most embedded and safety-critical teams already own. Its headline metric is condition/decision coverage rather than line coverage, and Studio keeps the two separate rather than blending them.
# 1. Build with the Bullseye compiler wrappers on PATH, then run your tests
cov01 -1 # enable instrumentation
make && ./run_tests
# 2. Export XML
covxml -f test.cov -o coverage.xml
A single-outcome probe is scored out of one rather than two, so a fully tested switch is not reported as half covered.
.NET — MSTest / vstest Visual Studio .coveragexml
For teams on vstest rather than Coverlet. The binary .coverage file has to be converted first.
dotnet test --collect:"Code Coverage"
dotnet-coverage convert -o coverage.coveragexml TestResults/**/*.coverage
Any language — Coveralls JSON Coveralls
If you already upload to Coveralls, the payload your reporter builds loads here directly — line-level, so gutters work. Reporters exist for most ecosystems: coveralls-lcov, excoveralls (Elixir), coveralls-python, simplecov-coveralls (Ruby), goveralls (Go), cargo-tarpaulin --out Coveralls (Rust) and node-coveralls.
# Example: Elixir, writing the payload instead of posting it
MIX_ENV=test mix coveralls.json
# -> cover/excoveralls.json
# Example: Rust
cargo tarpaulin --out Coveralls --output-dir .
A null in the coverage array means the line is not executable — a blank, a comment, a brace — and is excluded from the totals rather than counted as a miss.
Any language — SonarQube generic Generic coverage XML
SonarQube's own hand-written format, for a language with no native tool of its own. Useful mainly when something upstream already emits it.
<coverage version="1">
<file path="src/a.c">
<lineToCover lineNumber="5" covered="true"/>
<lineToCover lineNumber="6" covered="false"/>
</file>
</coverage>
C / C++ / Ada — VectorCAST VectorCAST XML
VectorCAST writes a Cobertura report with extra attributes attached — mcdcpair-coverage, function-coverage and functioncall-coverage — that plain Cobertura tooling ignores and this reader keeps. No conversion step: point Studio at the report VectorCAST already writes.
# From the VectorCAST GUI or vcast_gui.py, export the Cobertura-format report
# (Environment / Project → Reports → Cobertura), or via the API:
clicast -e <env> report custom Cobertura coverage.xml
The MC/DC pair counts drive the MC/DC gate and composite score exactly as GNATcoverage's do. Function-call coverage is read as its own metric, not folded into branches.
C / C++ — Testwell CTC++ CTC++ text listing
The tool that sits opposite Bullseye in European embedded and safety evaluations, and the one that measures multicondition coverage. Load the execution-profile listing as-is — no conversion, and no trip through Cobertura that would flatten it.
# 1. Instrument and build (per CTC++'s compiler wrapper for your toolchain)
ctc++ gcc -c file.c -o file.o
ctc++ gcc file.o -o app
# 2. Run the instrumented binary (writes MON.sym / MON.dat)
./app
# 3. Produce the text listing
ctcpost --projectfile ctc.proj -m src -t profile.txt
Newer CTC++ installs can skip the listing entirely. ctcpost's LCOV template (-m lcov, where the installed template set includes it) writes LCOV directly, which loads here with no format-specific parsing at all. Use the text listing when only multicondition coverage matters — LCOV has no place for it, and it is reported here as branch coverage rather than as MC/DC, since the two ask different questions.
Any target — Lauterbach TRACE32 TRACE32 XML
The on-chip-trace route: a debugger reports the instruction stream a real target actually executed, with no instrumentation and no probe effect on timing. An export carries exactly one metric — run it once per metric you need, and load all the exports together.
# From a TRACE32 PRACTICE script (.cmm), after a trace-based run:
COVerage.EXPORT.ListModule stmt.xml metric=stmt
COVerage.EXPORT.ListModule mcdc.xml metric=mcdc
COVerage.EXPORT.ListModule func.xml metric=func
COVerage.EXPORT.ListModule call.xml metric=call
COVerage.EXPORT.ListModule object.xml metric=object
stmt becomes line coverage; dec/cond become branch coverage; mcdc drives the MC/DC gate; func and call feed function and function-call coverage; object is the one export that produces object-code coverage. Loading several exports of the same run merges them by module name.
VHDL — GHDL LCOV / gcov JSON
Open-source VHDL simulation already has a way in through GHDL's GCC backend — no dedicated parser needed, because the result is ordinary gcov data.
# 1. Analyse and elaborate with coverage instrumentation
ghdl -a --coverage=stmt,cond your_design.vhd your_testbench.vhd
ghdl -e --coverage=stmt,cond your_testbench
# 2. Run the testbench (writes .gcda next to .gcno)
ghdl -r your_testbench
# 3. Capture as usual
lcov --capture --directory . --output-file lcov.info
# or: gcovr --json coverage.json
For commercial simulators (Riviera-PRO, Active-HDL, QuestaSim), see UCIS/UCDB below instead.
VHDL / Verilog / SystemVerilog — UCIS / Aldec UCDB UCIS / UCDB XML
Two documents answer to this name; load whichever your simulator writes. Statement and branch coverage come across — toggle, FSM, assertion and functional coverage are HDL-specific concepts with no equivalent metric here, and are not read.
# Accellera-standard UCIS interchange (Questa, VCS, Xcelium — consult your
# simulator's manual for the exact export command, typically via its GUI
# or a `ucis` command-line utility)
# Aldec Riviera-PRO / Active-HDL — native .ucdb converted to UCIS XML
acdb2xml -i coverage.ucdb -o coverage.xml
Beckhoff TwinCAT 3 Visual Studio .coveragexml
TwinCAT 3's C++ modules compile with MSVC inside Visual Studio, so ordinary .NET/C++ coverage tooling already applies — see MSTest/vstest above, or OpenCppCoverage for an instrumentation-free alternative. The Structured Text (ST) half has no coverage tool at all, from Beckhoff or any third party; if your project is ST-only, there is currently nothing to load here.
# OpenCppCoverage against a TwinCAT C++ module's unit tests
OpenCppCoverage.exe --sources=MyModule --export_type=cobertura:coverage.xml -- MyModuleTests.exe
Simulink SonarQube generic coverage
Simulink Coverage's own report has no format this extension reads directly. A short MATLAB script walking the cvdata object produced by cvsim or cvload can write SonarQube's generic coverage XML, which is four attributes on two elements — well within reach of a project's own build script.
% Sketch: iterate cvdata's per-line decision/condition results and
% write <coverage version="1"><file path="..."><lineToCover .../>
% See the SonarQube example in the table above for the exact schema.
cv_data = cvload('model_cvdata.cvt');
% ... walk cv_data.get('metric_summary') per model block ...
CODESYS Not supported
CODESYS's own Profiler cannot say which statements ran — only how much time a POU spent — and its counters live in the runtime's RAM, clearing on a warm reset with no export this extension could read. If your PLC toolchain is Siemens instead, TIA Portal exports coverage data through its own test-management tooling that can be converted to SonarQube's generic format the same way as Simulink above.
.NET / C# — NCover NCover XML
NCover's Coverage.xml outlived the tool itself: a decade of build scripts and other coverage tools still write or consume this schema. Load it as-is, no conversion needed.
NCover.Console.exe //x Coverage.xml -- dotnet test
.NET / C# — JetBrains dotCover dotCover DetailedXML
The report type matters. dotCover's plain Xml report is a rollup with no line numbers at all; ask for DetailedXml specifically.
dotnet dotcover.dll cover --Output=dotCover.dcvr --TargetExecutable=dotnet --TargetArguments="test"
dotnet dotcover.dll report --Source=dotCover.dcvr --Output=dotCover.xml --ReportType=DetailedXML
JetBrains deprecated DetailedXml in dotCover 2025.2 — check your installed version's documentation for the current flag spelling if this one is rejected.
Delphi / Object Pascal & legacy Java — EMMA EMMA XML
Delphi has no lcov, no Cobertura, nothing else this extension reads — DelphiCodeCoverage is the way in. The same schema is also what a good deal of older Java tooling still emits.
# DelphiCodeCoverage, with per-line hit counts (needed for gutters)
DelphiCodeCoverage.exe -e MyApp.exe -m MyApp.map -xml -xmllines -o coverage.xml
Without -xmllines the report is a rollup percentage only — Studio shows a file summary and no gutters for it, the same treatment Xcode's xccov gets, rather than guessing which lines ran.
Any language — PIT / Stryker Mutation reports
Mutation testing answers a question coverage cannot: not whether a line ran, but whether anything failed when it was changed. Load the report beside a real coverage tracefile — the two merge by path, and the mutation score appears as its own metric, never averaged into the composite score.
# PIT — Java, Kotlin, Scala
mvn org.pitest:pitest-maven:mutationCoverage
# -> target/pit-reports/<timestamp>/mutations.xml
# Stryker — JavaScript, TypeScript, C#, Scala
npx stryker run
# -> reports/mutation/mutation.json (rename or point discovery at it)
Already covered, with no work at all
A few ecosystems reach Studio through a format it already reads, so there is nothing extra to install or configure:
- Rust —
cargo llvm-cov --lcovorgrcovboth emit LCOV;cargo llvm-cov --jsonemits llvm-cov JSON. - Kotlin — Kover writes JaCoCo XML.
- Dart / Flutter —
flutter test --coveragewritescoverage/lcov.info. - PHP — PHPUnit's
--coverage-cloveris Clover XML. - Qt / Squish Coco — exports Cobertura or LCOV.
- Erlang —
rebar3 coverconverts to Cobertura viacovertool. - Elixir —
excoverallswrites Coveralls JSON directly (mix coveralls.json). - Haskell —
hpccoverage converts to Cobertura or LCOV viahpc-lcov. - Perl —
Devel::Cover's-report cloverwrites Clover XML. - R — the
covrpackage'sto_cobertura()writes Cobertura XML. - Julia —
Coverage.jl'sLCOV.writefilewrites LCOV directly. - Fortran — GCC-based (
gfortran --coverage) goes through gcov/lcov like C. - PL/SQL — Oracle's
DBMS_PLSQL_CODE_COVERAGEexports convert to Cobertura via community tooling (e.g.plsql-cover).
결과를 Studio에 로드
- 추적 파일을 워크스페이스(예: 프로젝트 루트)에 둡니다.
- 명령 팔레트 →
Fucini Coverage: Load Coverage— 또는watch.enabled를 켜 두면(기본값) 자동으로 로드됩니다. - 커버된 소스 파일을 엽니다: 커버된 줄은 적중 횟수가 있는 초록색 거터, 커버되지 않은 줄은 빨간색이 되고 Covered Files 뷰가 채워집니다.
일반 팁(모든 언어)
- 소스-커버리지 1:1 매핑을 위해 최적화를 끄고(
-O0) 빌드/테스트하세요. 최적화는 줄을 병합하거나 제거할 수 있습니다. - 종합 점수가 왜곡되지 않도록 항상 서드파티/테스트 코드를 걸러내세요(ignore/remove 플래그).
- 추적 파일이 여러 개인가요? 모두 로드하세요 — Studio가 출처를 기록하며 결정론적으로 하나의 실행으로 병합합니다.
- CI 경로가 체크아웃과 다르면
fuciniCoverage경로 리매핑을 사용하세요(사용자 가이드 §7 참조).