1. 소개
Fucini Coverage Studio는 빌드가 이미 만들어 내는 커버리지 추적 파일을 편집기 안의 일급 커버리지로 바꿉니다 — VS Code에서도, Visual Studio에서도. 25가지 형식을 읽어 하나의 정규 Fucini 모델로 정규화하고, 여러 실행을 결정론적으로 병합해, 편집기 자체에서 보여줍니다 — 여백 표시, CodeLens, 호버, Covered Files 보기 — 그래서 편집기를 떠나 따로 열어야 할 뷰어가 없습니다. 두 에디션은 리더 하나를 공유합니다. 같은 보고서가 두 곳에서 자릿수까지 같은 숫자를 냅니다. 이 가이드는 VS Code 기준으로 쓰였으며, Visual Studio가 다른 곳에는 In Visual Studio 상자가 방법을 알려줍니다.
이 확장 프로그램은 기능 안전 워크플로를 염두에 두고 설계되었습니다: MC/DC 커버리지, 리전 및 C++ 인스턴스화 커버리지, 안전 가중치가 적용된 종합 점수, 그리고 IEC 61508, ISO 26262, DO-178C의 접근 방식에 맞춘 구성 가능한 COMPLIANT / NON-COMPLIANT 판정.
Screenshot pending — add assets/img/marketplace-demo.gif (see SCREENSHOTS.md).2. 설치 및 요구 사항
- VS Code 1.88 이상 — 이 확장이 지원하는 최소 버전 — 또는 Visual Studio 2022나 2026, Community, Professional, Enterprise 중 하나(아래 상자 참고).
- 프로젝트가 이미 만들어 내는 커버리지 추적 파일(§4 참고).
Marketplace에서 설치하거나, Extensions → ⋯ → Install from VSIX…를 통해 .vsix 파일로 설치합니다. 확장 프로그램은 시작 시 활성화되며 액티비티 바에 Coverage 아이콘을 추가합니다.
Visual Studio에서는. 같은 제품이 두 번째 확장 Visual Studio용 Fucini Coverage Studio로 Visual Studio 2022와 2026 — Community, Professional, Enterprise용으로 제공됩니다. Visual Studio 자체 코드 커버리지는 사용하지 않습니다. Visual Studio 2022에서 그것은 Enterprise 기능이라, Community와 Professional에서는 이것이 IDE가 보여주는 유일한 커버리지입니다. .vsix를 열어 설치하거나(VSIX Installer가 어느 Visual Studio인지 묻습니다) Extensions → Manage Extensions를 통해 설치하세요. 확장은 솔루션이나 폴더를 열 때 로드됩니다. Coverage 창에는 Microsoft Edge WebView2 Runtime이 필요하며, Windows 11과 Visual Studio 2026에는 이미 들어 있습니다. 편집기의 표시는 그것 없이도 동작합니다.
3. 빠른 시작
자신의 프로젝트를 연결하기 전에 작동 방식을 먼저 보고 싶으신가요? 데모 프로젝트 다운로드(약 6 KB — 미리 준비된 lcov.info가 포함된 작은 C 프로젝트):
- 원하는 위치에 압축을 풀고 VS Code에서
coverage-studio-demo.code-workspace를 엽니다(File → Open Workspace from File…). - 아직 설치하지 않았다면 Fucini Coverage Studio를 설치합니다(위의 §2 참조).
- 워크스페이스 자체의
.vscode/settings.json이 이미 포함된coverage/lcov.info를 가리키고 있으므로, 확장 프로그램이 활성화되는 즉시 거터와 Covered Files 뷰가 나타납니다 —Load Coverage단계가 필요 없습니다. - 트레이스 파일을 직접 다시 생성하고 싶으신가요(예: 다른 컴파일러 사용)?
scripts/gen-coverage.sh(Windows에서는.ps1)를 실행하세요 — 사용 가능한 컴파일러 대상은 워크스페이스 자체의README.md를 참조하세요.
Visual Studio에서는. 솔루션이나 폴더를 여세요(File → Open → Folder, CMake 프로젝트는 이렇게 엽니다) — 위의 데모는 폴더로 열리며, 그 .vscode/settings.json도 거기서 읽힙니다. 설정이 가리키는 위치의 보고서는 저절로 로드되고, 출력 창의 Fucini Coverage 창이 어떤 파일인지 알려줍니다. 그렇지 않으면 Tools → Coverage Studio → Load Coverage File…을 한 번만 하면 기억됩니다. 소스 파일을 열고 Show Coverage in Editor를 선택하세요. 빨간색은 한 번도 실행되지 않은 줄, 호박색은 한쪽으로만 분기한 결정이며, Ctrl+Shift+U, N은 다음 미커버 줄로 이동합니다. View → Other Windows → Coverage는 모든 파일의 숫자와 전체 점수 하나를 보여주는 트리이며, 상태 표시줄은 그 점수를 실행 전체와 현재 파일에 대해 보여줍니다. Tools → Coverage Studio → Getting Started는 이 단계들을 각각 버튼이 있는 페이지로 열며, 처음에는 저절로 열립니다.
- 평소 테스트 워크플로로 커버리지 트레이스 파일을 생성합니다.
- 명령 팔레트(
Ctrl+Shift+P) →Fucini Coverage: Load Coverage.watch.enabled가 켜져 있으면(기본값) 일치하는 파일이 자동으로 로드됩니다. - 커버된 소스 파일을 엽니다: 상태 표시줄에 그 백분율이 표시되고, Coverage 보기가 채워지며, 줄에 마우스를 올리면 실행 횟수가 표시되고, 실행이 네이티브 Test Coverage 패널에 나타납니다. 커버되지 않은 줄의 막대, 실행 횟수 히트맵, 인라인
×N횟수는 설정 하나로 켤 수 있습니다(editorGutter.mode,hitCounts.inline).
Screenshot pending — add assets/img/gutters.png (see SCREENSHOTS.md).4. 트레이스 파일 생성
다음 중 어느 것이든 로드 시 자동으로 감지됩니다:
Swift, Rust, Go, Python, .NET, PHP 등 각 컴파일러별 전체 복사-붙여넣기 레시피는 커버리지 레시피: 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은 가장 풍부한 입력으로, 라인, 브랜치, 함수 외에도 리전, MC/DC, C++ 템플릿 인스턴스화를 포함합니다.
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
| 형식 | 대표 파일 | 추가 지표 |
|---|---|---|
| LCOV | lcov.info | 행, 분기, 함수 |
| llvm-cov JSON | coverage.json | + 리전, MC/DC, 인스턴스화 |
| Cobertura XML | coverage.xml | 행, 분기 |
| JaCoCo XML | jacoco.xml | 행, 분기, 함수 |
| Istanbul / nyc | coverage-final.json | 구문, 분기, 함수 |
| SimpleCov | .resultset.json | 행 |
| Clover XML | clover.xml | 행, 분기, 함수 |
| OpenCover XML | coverage.opencover.xml | 행, 분기, 함수 |
| coverage.py JSON | coverage.json | 행, 분기 |
| gcov / gcovr JSON | coverage.json | 행, 분기, 함수 |
| Go coverage profile | coverage.out | 행 |
| SonarQube generic | coverage.xml | 행, 분기 |
| GNATcoverage XML (Ada) | *.xml | 행, 분기, MC/DC |
| BullseyeCoverage XML | coverage.xml | 행, 조건/결정 |
| Visual Studio | *.coveragexml | 행, 분기 |
| Coveralls JSON | coveralls.json | 행, 분기 |
| Xcode xccov JSON | coverage.json | 함수와 파일 단위 합계 — 행 단위 데이터 없음 |
| gcov plain text | *.gcov | 행, 분기, 함수 호출 |
| VectorCAST | coverage.xml | 행, 분기, MC/DC 쌍, 함수, 함수 호출 |
| Testwell CTC++ | *.txt | 행, 조건/결정 |
| Lauterbach TRACE32 | *.xml | 문, 결정, 조건, MC/DC, 함수, 호출, 목적 코드 |
| EMMA XML (Java) | coverage.xml | 행 |
| UCIS / Aldec UCDB | *.xml | 문, 결정 분기 |
| NCover XML | Coverage.xml | 행, 함수 |
| dotCover DetailedXML | dotCover.xml | 행, 함수 |
| PIT (mutation) | mutations.xml | 뮤테이션 점수 — 커버리지 없음 |
| Stryker (mutation) | mutation-report.json | 뮤테이션 점수 — 커버리지 없음 |
네이티브 C++ 프로젝트를 Visual Studio에서 측정하기
Visual Studio에서는. Visual Studio 자체의 C++ 프로젝트 커버리지는 Enterprise 전용이었고, 그 빈자리를 채우던 무료 OpenCppCoverage 플러그인은 은퇴했습니다. Tools → Coverage Studio → Run Native Project with Coverage는 시작 프로젝트 — .vcxproj — 를 잡아 MSBuild에 어디로 빌드되고 어떤 도구 집합을 쓰는지 묻고, 두 가지 방법 중 하나로 측정합니다. ClangCL 도구 집합에서는 LLVM의 llvm-profdata와 llvm-cov가 컴퓨터에 있으면(Visual Studio의 C++ Clang tools for Windows 구성 요소가 함께 가져옵니다) MSBuild가 먼저 가져오도록 지시된 props 파일을 통해 프로젝트를 -fprofile-instr-generate -fcoverage-mapping으로 coverage\native\에 다시 빌드하고 — 프로젝트에서는 아무것도 바뀌지 않습니다 — LLVM_PROFILE_FILE을 설정한 채 프로그램을 실행한 뒤, 프로필을 병합하고 coverage\native\lcov.info를 내보냅니다. 영역 단위로 정확합니다. 다른 도구 집합에서는 OpenCppCoverage가 설치되어 있으면 프로젝트를 있는 그대로 빌드하고 — Debug 빌드에는 PDB가 있습니다 — OpenCppCoverage 아래에서 실행하며, 그러면 coverage\native\opencppcoverage.xml이 기록됩니다. 모든 명령은 Fucini Coverage 창으로 가고, 보고서는 테스트 실행의 보고서처럼 로드되고 기억됩니다. 측정할 수 없는 프로젝트에는 그 이유와 무엇을 설치해야 하는지 알려 줍니다. 이 질문을 위해 MSBuild 17.8(Visual Studio 2022 17.8) 이상이 필요합니다.
Screenshot pending — add assets/img/vs-native-run.gif (see SCREENSHOTS.md).5. 로딩 및 검색
기본적으로 확장 프로그램은 워크스페이스 루트부터 스캔합니다. 다음 두 가지 설정으로 더 정확하게 지정할 수 있습니다:
{
"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"
]
}
- 각
paths항목은defaultLocation(설정하지 않은 경우 워크스페이스 루트)에 대한 상대 경로입니다. *를 포함하는 항목은 재귀적으로 검색됩니다. 단순 파일명은 기본 폴더에서 직접적으로만 일치합니다.paths가 비어 있으면 확장 프로그램은 먼저coverage.json을, 그다음lcov.info를 찾아 먼저 발견되는 것을 로드합니다.- Pick Coverage File은 이 경로 대신 고른 파일을 사용합니다 — 고를 때마다 목록에 더해지고 모두 병합됩니다 — 언로드하거나 이 설정을 편집할 때까지.
- 변수 — 모든 경로 설정은
${workspaceFolder},${workspaceFolderBasename},${userHome},${env:NAME},${command:id},${config:section.key}를 확장합니다. 확장이 모르는 변수는 적힌 그대로 남으므로, 오타는 사라지는 대신 찾아본 경로로 검색 로그에 드러납니다.${command:id}는 먼저 그 명령을 실행합니다(신뢰할 수 있는 작업 영역에서만, 최대 5초). 그래서${command:cmake.buildDirectory}는 선택한 CMake 키트를 따라갑니다. - URL 항목 —
http(s)://항목은 로드할 때마다 확장의 저장소로 가져와 그곳에서 로드되며, Coverage 보기는 URL을 표시합니다. 각 가져오기는 조건부(ETag / Last-Modified)여서 바뀌지 않은 아티팩트는 아무것도 내려받지 않고, 가져오기가 실패하면 마지막으로 내려받은 사본이 대신 로드되며 이유는 출력에 기록됩니다.remote.headers는 변수가 확장된Name: value헤더를 더하고,remote.refreshMinutes는 타이머에 따라 다시 가져오며, URL 자체가 파일 이름으로 끝나지 않으면#lcov.info조각이 형식을 알려 줍니다. - 무시 glob —
fuciniCoverage.ignore는 로드하면서 파일 전체(벤더, 생성, 서드파티)를 실행에서 빼므로 모든 보기, 게이트, 내보내기가 그것들 없이 셉니다. 로드 결과는 몇 개가 빠졌는지 알리고 출력은 그 이름을 밝힙니다. 패턴은 작업 영역 상대 경로와 절대 경로에 맞춰지며,/가 없는 패턴은.gitignore처럼 어느 깊이에서든 폴더나 파일 이름에 맞습니다. - 다중 루트 작업 영역 — 모든 폴더가 각자의 조건으로 검색됩니다:
defaultLocation,paths,pathRemap,ignore,watch.*,remote.*가 폴더별로 읽히므로 폴더 자체의.vscode/settings.json이나.code-workspace항목이 적용되고, 항목 안의${workspaceFolder}는 그 항목이 속한 폴더를 뜻합니다. 모든 폴더의 추적 파일은 하나의 실행으로 병합되고, Coverage 보기는 파일을 폴더별로 묶으며, 작업 영역에 폴더가 추가되거나 제거되면 커버리지가 저절로 다시 로드됩니다. - 작업 후 다시 로드 —
watch.reloadAfterTasks는watch.enabled가 켜져 있든 아니든 끝나면 커버리지를 다시 로드할 작업의 이름(tasks.json의label, 또는 Run Task 목록에 보이는 대로source: name)을 지정합니다 — 감시자가 따라갈 수 없는 빌드를 위해서입니다. 작업 영역 밖의 절대paths항목도 폴링되므로 그곳에 나타난 파일이 로드됩니다. - 취소할 수 있는 진행률 — 추적 파일이 열 개 이상이거나 8 MB 이상인 로드는 읽고 있는 파일과 단계를 알리는 Cancel 버튼이 있는 진행률 알림 아래에서 실행되고, 그보다 작은 로드는 상태 표시줄만 돌립니다. 취소하면 이전 실행이 로드된 채로 남고 그렇다고 알립니다.
1.2026.6부터는 절대 항목에도 와일드카드를 넣을 수 있습니다: ${workspaceFolder}/build/coverage-merged/*.lcov.info는 그 폴더의 그런 파일을 모두 로드하고, **는 어느 깊이든 뜻합니다. 첫 와일드카드 앞의 폴더들이 찾아보는 곳이며 감시되므로, 빌드가 그곳에 쓰는 보고서는 저절로 로드됩니다. Visual Studio 에디션도 그런 항목을 같은 방식으로 읽고, 1.2026.5부터는 상대 와일드카드가 그곳에서도 여기서 늘 그랬듯 어느 깊이에서든 검색됩니다.
paths가 설정되어 있지 않으면 기본 폴더 아래에서 발견되는 잘 알려진 보고서 이름 중 첫 번째 것이 로드됩니다. 먼저 지금까지 항상 찾던 네 가지 — coverage.json, lcov.info, coverage.out, clover.xml — 를 찾고, 0.2026.83부터는 이어서 jacoco.xml, coverage.xml, cobertura.xml, coverage.cobertura.xml, coverage.opencover.xml, coverage-final.json을 찾으며, 그다음에는 기본 구성이 출력하는 위치를 찾습니다: coverage/ (nyc, Jest, vitest, PHPUnit, SimpleCov), target/site/jacoco/jacoco.xml (Maven), build/reports/jacoco/test/jacocoTestReport.xml (Gradle), TestResults/*/coverage.cobertura.xml (dotnet test). 따라서 Java나 .NET 프로젝트도 lcov 프로젝트가 늘 그랬던 것처럼 처음 열 때 바로 커버리지를 보여 줍니다.
1.2026.3부터 .NET 솔루션에는 더 적은 것만 필요합니다. 워크스페이스 폴더 자체의 폴더뿐 아니라 모든 테스트 프로젝트의 TestResults/<run>/ 폴더가 잘 알려진 위치에 포함되고, Microsoft 수집기의 <user>_<machine>_<date>.cobertura.xml이 Coverlet의 coverage.cobertura.xml 옆에서 발견됩니다. 그래서 Visual Studio의 Test Explorer에서 테스트를 실행한 솔루션은 처음 열 때부터 커버리지를 보여 주고, 모든 실행 폴더가 로드되며, 병합은 각 파일에 대해 가장 최근 실행의 결과를 유지합니다. 그리고 기본으로 켜져 있는 fuciniCoverage.ignore.generated는 디자이너 파일과 생성된 파일 — *.Designer.cs, *.g.cs, *.generated.cs, *.razor.g.cs, AssemblyInfo, 전역 using, Migrations/와 obj/ — 을 ignore가 적용되기 전에 모든 합계, 페이지, 내보내기에서 제외하므로, 아무도 테스트하지 않는 생성된 테이블 때문에 솔루션이 게이트를 잃는 일이 없습니다.
Visual Studio에서는: 모든 테스트 실행 뒤의 커버리지. 평소처럼 테스트를 실행하세요. Tools → Coverage Studio → Collect Coverage in Test Explorer…는 Microsoft의 Cobertura 수집기를 담은 .runsettings 하나를 솔루션 옆에 둡니다. Tools → Options → Test → Auto detect runsettings files가 켜져 있으면 Visual Studio가 이를 스스로 인식하고, 그렇지 않으면 Test → Configure Run Settings에서 한 번만 선택하세요. 그때부터 모든 실행이 테스트 프로젝트 아래에 보고서를 쓰고, 솔루션에 대한 감시가 보고서가 나타나는 즉시 설정이 지정하는 것과 병합하여 로드합니다 — Test Explorer에서든, 터미널에서든, 스크립트에서든 마찬가지입니다. Test Explorer에 아무것도 연결하지 않으므로 Visual Studio 2026과 Microsoft.Testing.Platform은 그대로 동작합니다. Run Tests with Coverage는 VS Code의 명령입니다. dotnet test, vitest, jest, pytest, go, cargo, maven, gradle, phpunit, ctest를 인식하고, Output 창에서 커버리지를 켠 채 테스트를 실행한 뒤 테스트가 쓴 결과를 로드합니다. coverlet.collector가 없는 테스트 프로젝트는 테스트 SDK에 포함된 수집기로 실행되며, testRun.skipWhenTestsFail은 실행이 실패로 끝났을 때 마지막 정상 커버리지를 화면에 유지합니다.
토큰 뒤에 있는 CI 아티팩트를 15분마다 다시 확인 — 토큰은 환경에 남고 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
}
Screenshot pending — add assets/img/remote-tracefile.png (see SCREENSHOTS.md).다시 읽기는 일부러 조용합니다. 빌드마다 뜨는 대화 상자는 답이 하나뿐인 질문이기 때문입니다. 조용하지 않은 것은 Coverage 아이콘입니다. 뷰가 눈앞에 없는 동안 다시 읽힌 트레이스 파일의 수를 표시하고, 툴팁이 그 이름을 알려 줍니다. 뷰를 열면 숫자는 사라집니다.
Screenshot pending — add assets/img/coverage-badge.gif (see SCREENSHOTS.md).추적 파일이 뭐라고 하든 결코 세지 말아야 할 파일:
{
"fuciniCoverage.ignore": ["vendor/**", "**/*.generated.ts", "build/**"]
}
파일 감시자가 따라갈 수 없는 빌드 — 심볼릭 링크된 출력 트리를 교체하는 실행, 네트워크 공유의 보고서, 자기 파일을 후처리하는 커버리지 단계 — 를 위해 테스트 작업이 끝나면 다시 로드:
{
"fuciniCoverage.watch.reloadAfterTasks": ["npm: test", "coverage-report"]
}
6. 실행 병합
기존의 모든 paths 항목이 로드되어 하나의 실행으로 병합됩니다. 병합은 결정적이며 결과는 로드 순서에 좌우되지 않습니다. 둘 이상의 트레이스 파일이 측정한 파일은 디스크에서 mtime이 가장 최신인 파일의 수치를 가져옵니다. 즉 모듈 단독 재실행은 더 넓고 오래된 실행이 그 파일에 대해 말한 내용에 더해지는 것이 아니라 그것을 대체합니다. 커버리지 보기는 그 결과를 보여줍니다. 각 파일 행에는 수치의 출처인 트레이스 파일이 표시되고, 그 수치가 이전 보고서를 덮어쓴 곳에는 배지에 테두리가 붙으며, 트리 위의 각 트레이스 파일 행은 자신의 파일 중 몇 개가 덮어쓰였거나 다른 파일을 덮어썼는지 세고, 트레이스 파일 행을 클릭하면 다시 클릭할 때까지 트리에서 해당 파일이 강조됩니다(coverageView.mergedMarks로 테두리와 강조를 끌 수 있습니다).
병합된 실행에는 전통적인 여섯 가지 지표보다 더 많은 지표가 담길 수 있으며, 각 지표는 그것을 측정하는 보고서에서 가져옵니다. 행, 함수, 리전, 분기, MC/DC, 인스턴스화와 더불어 함수 호출, 오브젝트 코드, 뮤테이션 점수가 그것입니다. Coverage 뷰는 실행에 담긴 모든 지표에 대해 열을 표시하고, 담기지 않은 지표의 열은 표시하지 않습니다. 열은 점수에서 차지하는 가중치가 큰 순서로 정렬되어 너비와 무관하게 표시되며, 들어가지 않는 열은 사라지는 대신 옆으로 스크롤됩니다. 뷰를 하단 패널로 끌어다 놓으면 표가 됩니다. 상태 표시줄 카드, HTML 보고서, CSV 및 Markdown 내보내기도 같은 규칙을 따릅니다. 보고서에 담긴 것은 표시되고, 담기지 않은 것은 0으로 출력되는 대신 생략됩니다.
Screenshot pending — add assets/img/coverage-view-editor.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/coverage-view-columns.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/workspace-overview.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-workspace-overview.gif (see SCREENSHOTS.md).파일이 어느 보고서에서 오는가
여러 로드된 보고서가 같은 파일을 측정하면, 가장 최신 보고서가 그 파일을 통째로 가져갑니다 — 모듈 자체의 재실행이 더 오래되고 범위가 넓은 실행의 결과를 대체할 때는 이것이 맞습니다. 하지만 보고서들이 의도적으로 같은 코드를 측정할 때는 틀립니다. 그러면 에디터는 빌드할 때마다 보고서 사이를 오가고, 각 보고서는 이야기의 일부만 전합니다. coverageFile.sources는 대신 어떻게 할지를 파일별로 지정합니다. 다음 세 가지 상황에서 필요합니다:
- 한 보고서가 더 낫습니다. llvm-cov의
coverage.json은 MC/DC를 담고 있고, 같은 빌드의 GCCgcov.info는 줄과 분기만 담습니다.coverage.json을 선택하고, 다른 하나는 GCC만 빌드하는 몇몇 파일을 위해 남겨 둡니다. - 한 빌드의 여러 테스트 스위트. 단위 테스트, 통합 테스트, HIL(hardware-in-the-loop) 테스트가 각각 보고서를 작성하며, 각 보고서만으로는 다른 스위트가 실행한 줄이 빠집니다. 결합, union: 어느 보고서든 실행한 줄은 커버된 것이며, 실행 횟수는 합산됩니다.
- 하나의 코드베이스, 두 컴파일러. 같은 소스를 clang과 GCC로 빌드하면 툴체인별 코드 — 여기서는 인트린식, 저기서는 이식 가능한 대체 구현 — 에서 서로 다른 경로를 타며, 각 보고서는 나머지 절반이 한 번도 실행되지 않았다고 말합니다. 결합, agree: 그 줄을 측정하는 모든 보고서가 실행한 줄만 커버된 것이며, 보고서 간에 일치하지 않는 줄은 청록색으로 표시됩니다. 이것이 크로스 컴파일러 검사가 묻는 질문입니다. 내가 출시하는 모든 빌드가 실제로 무엇을 실행했는가?
규칙을 직접 작성할 일은 드뭅니다. Coverage 보기에서 파일을 마우스 오른쪽 버튼으로 클릭하고 Choose Coverage Source...을 고르면(또는 열린 파일에서 Choose Coverage Source for This File...을 실행하면), 그 파일을 측정하는 모든 보고서가 각자의 줄, 분기, MC/DC와 함께 나열되고, 이어서 Combine them — agree와 Combine them — union이 표시됩니다. 하나를 고르고, 그것을 파일, 그 폴더, 또는 패턴 중 어디에 적용할지 정합니다. Clear Coverage Source for This File...는 규칙을 다시 제거합니다. 설정에서 각 규칙은 파일에 대한 glob, 보고서에 대한 glob(/가 없는 패턴은 보고서의 파일 이름과 일치하며, {a,b}로 여러 개를 지정합니다), 그리고 결합하려면 "combine": "agree" 또는 "union"으로 이루어집니다. 파일이 일치하고 그 보고서가 파일을 측정하는 첫 번째 규칙이 결정합니다. 하나의 보고서만 측정하는 파일은 결코 그 보고서에서 빼앗기지 않습니다. 결합된 파일의 분기, MC/DC, 영역은 그것들을 가장 풍부하게 가진 보고서에서 가져옵니다. coverageFile.mergeStrategy: "order"는 어떤 규칙도 다루지 않는 파일을 시간 대신 coverageFile.paths의 순서로 정합니다.
{
"fuciniCoverage.coverageFile.paths": ["clang.json", "gcc/bits.gcov.json.gz"],
"fuciniCoverage.coverageFile.sources": [
{ "files": "src/**", "report": "{clang.json,bits.gcov.json.gz}", "combine": "agree" }
]
}
보이는 것: Coverage 보기에서 파일의 행은 수치의 출처인 보고서 이름을 알려 주며, 결합된 경우에는 모든 보고서와 모드를, 불일치하는 줄에 대한 ≠ n과 함께 표시합니다. 거터와 주석이 달린 소스는 그 줄들을 청록색으로 표시하고, 어느 보고서가 몇 번 실행했는지 알려 줍니다. 상태 표시줄의 호버 카드는 열린 파일의 출처와, 실행 전체에 대해 적용 중인 규칙 및 다른 파일들이 어떻게 결정되었는지를 알려 줍니다. 데모의 samples/c-cross-check가 두 컴파일러 사례이며, 바로 열 수 있습니다. Visual Studio에서도 이 모든 것을 할 수 있습니다. Coverage 보기의 행에서 Choose Coverage Source...를, Tools > Coverage Studio 아래에서 Choose 및 Clear Coverage Source for This File...를 사용합니다.
출처 선택과 결합은 유료 플랜에 포함됩니다. Community에서는 규칙이 없을 때처럼 가장 최신 보고서가 모든 파일을 가져가며, 설정에 있는 규칙은 조용히 무시되는 대신 사용되지 않는다고 표시됩니다.

bits.c에 대해 Choose Coverage Source... — clang 보고서, GCC 보고서, 또는 둘을 결합.


bits.c — 행에 ≠ 4가 표시되고, 한 빌드만 실행한 네 줄은 청록색입니다.
bits.c는 줄의 100%에 도달합니다 — 그리고 빌드 간에 불일치하는 줄은 청록색으로 남습니다.


7. 경로 재매핑
CI는 워크스테이션에 존재하지 않는 절대 빌드 머신 경로를 기록하는 경우가 많습니다. 순서가 지정된 규칙으로 이를 재작성합니다:
{
"fuciniCoverage.pathRemap": [
{ "from": "/builds/ci/project", "to": "${workspaceFolder}" },
{ "from": "\\\\", "to": "/" }
]
}
규칙은 순서대로 적용되며, 각 접두사에 대해 첫 번째로 일치하는 항목이 우선합니다. 이를 사용하여 Windows/Unix 구분자 차이를 조정하거나 컨테이너 경로를 체크아웃에 매핑할 수 있습니다.
규칙을 직접 써야 하는 일은 드뭅니다. 가장 흔한 “로드는 됐는데 아무것도 켜지지 않는” 경우는 작업 영역에는 src/a.c가 있는데 추적 파일의 경로가 컨테이너나 CI 체크아웃에서 온(/build/src/a.c, /home/runner/work/repo/repo/src/a.c, C:\agent\_work\1\s\src\a.c) 경우입니다. 로드 후 맞지 않는 파일이 남으면 확장은 작업 영역에서 파일 이름을 찾아보고, 그중 가장 많은 것을 설명하는 접두사 규칙을 추론해 [FUCINI_REMAP_002]로 기록하며, 로드 결과가 Apply Suggested Remap을 제공합니다 — 한 번 클릭하면 규칙이 fuciniCoverage.pathRemap에 추가되고 다시 로드됩니다. Suggest Path Remap Rule은 팔레트에서 같은 분석을 요청 시 실행합니다. 클릭 없이는 아무것도 기록되지 않습니다.
to는 ${workspaceRoot}를 쓸 수 있으며, 이는 추적 파일이 있는 작업 영역 폴더를 뜻합니다. 다중 루트 작업 영역에서는 그 폴더를 먼저 시도한 뒤 그 파일이 있는 것으로 확인되는 다른 모든 폴더를 시도합니다. 규칙 자체가 폴더별로 읽히므로 다중 루트 작업 영역의 각 루트는 자기만의 규칙을 가질 수 있습니다.
8. 에디터 내 커버리지
- 거터 및 눈금자 — 기본적으로 에디터 자체 거터는 발견 사항만 보여 줍니다: MC/DC 막대, 이전 실행 이후 삼각형, 편집된 줄의 점.
editorGutter.mode는 커버되지 않은 줄만의 막대나 실행 횟수 히트맵을 더하고(아래 참조), 파일 전체를 색상으로 구분해 보는 것은 Annotated Source입니다. - 함수 CodeLens — 각 함수 위에 표시되는 커버리지 %; 클릭하면 첫 번째 미커버 라인으로 이동합니다.
codeLens.enabled로 전환합니다. - 브랜치 및 MC/DC 호버 — 판정 라인에 마우스를 올리면 분기별 통과/미통과 횟수와 조건별 벡터 테이블이 표시됩니다.
mcdcGutter.enabled로 색상이 지정된 여백 표시줄을 활성화합니다. - 데드 코드 경고 — 측정 가능한 라인이 있고 커버리지가 0인 함수는 Problems 패널에 표시됩니다(
deadCode.enabled). - Next / Previous Uncovered — 미커버 구간 사이를 이동합니다.
- 상태 표시줄 — 실행 전체의
$(dashboard) NN%항목과 파일별 항목이 있으며, 둘 다 종합 점수에 따라 색상이 지정됩니다. 전체 지표 테이블을 보려면 마우스를 올리세요. - 탐색기 배지 — 파일별, 폴더별 커버리지 배지와 호버 시 지표별 세부 내역. 기본값은 꺼짐:
explorerBadges.enabled로 켤 수 있습니다. - 이전 실행 이후 — 이전 실행에서 실행되었지만 이번에는 실행되지 않은 모든 줄에 빨간 삼각형, 반대의 경우 녹색 삼각형, 개요 눈금자와 호버의 실행 횟수와 함께.
- 편집된 버퍼 — 편집에 따라 모든 표시, 호버, CodeLens가 텍스트와 함께 이동하고, 다시 쓰인 줄에서는 물러나며, 회색 점이 그 이유를 알려 줍니다.
- 인라인 실행 횟수 —
hitCounts.inline은 문장이 시작하는 각 줄 뒤에×12를 적으며,×0도 포함합니다: 늘 호버에 있던 그 숫자를 호버 없이. Toggle Inline Hit Counts가 이를 뒤집고, 상태 표시줄 메뉴는 상황에 맞게 Show 또는 Hide로 제공합니다. - 줄 단위 Problems 항목 —
problems.perLine은 열린 문서에서 한 번도 실행되지 않은 연속된 줄 블록마다(마흔 줄짜리 죽은 함수는 마흔 개가 아니라 한 항목) 에디터의 물결선과 함께 Information 진단을 두고,uncoveredAndPartial에서는 분기 갈래가 한 번도 타지 않은 모든 줄에도 둡니다. 항목은 편집에 따라 자기 줄을 따라가고 문서가 닫히면 사라지며,problems.enabled뒤의 파일별 항목은 그대로입니다. - 줄 색상 —
lineHighlight는 여백이 표시하는 내용에 맞춰 줄 자체 뒤에 반투명한 색을 깝니다(uncovered, 실행된 줄까지 포함하려면heatmap). 별도 설정이므로 여백은 깨끗하게 두고 빈틈만 칠하거나 그 반대로 할 수 있습니다. - 개요 눈금자 —
overviewRuler는 스크롤 막대의 줄무늬를 여백과 무관하게 정합니다.follow(막대와 함께, 이전과 동일),uncovered(항상. 여백을 꺼도 스크롤 막대는 파일의 빈틈을 계속 보여 줍니다),off중에서 고릅니다. - 어떤 추적 파일이 줄을 커버했는지 — 여러 보고서를 병합했을 때 실행 횟수 호버가 커버한 항목: 과 그 줄을 커버한 보고서들로 끝나며, lcov
TN:의 스위트 이름도 포함됩니다. Coverage 뷰에서 추적 파일 행을 클릭하면 그 파일이 기여한 줄이 열려 있는 모든 편집기에서 강조됩니다.
Screenshot pending — add assets/img/codelens-hover.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/codelens-crap.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/jump-between-gaps.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/explorer-badges.png (see SCREENSHOTS.md).에디터 거터 모드
editorGutter.mode는 에디터 자체 거터가 늘 보여 주는 발견 사항에 더해 커버리지에 대해 무엇을 보여 줄지 정합니다. off(기본값)는 그것들뿐입니다. uncovered는 한 번도 실행되지 않은 모든 줄에 막대를, 분기 갈래가 한 번도 타지 않은 모든 줄에 호박색 막대를 두고 커버된 줄에는 아무것도 두지 않으므로, 초록 벽이 빨간 세 줄을 가리지 않습니다. coverage는 커버된 모든 줄에 초록 막대를 더해, 파일 전체가 색상 스케일의 색으로 빨강, 호박색, 초록으로 읽힙니다. heatmap은 대신 실행된 모든 줄에 따뜻한 색조를 더하며, 자주 실행될수록 더 뜨겁습니다. 이것은 줄이 커버되었는지가 아니라 몇 번 실행되었는지를 보여 주므로, 100%인 파일도 여기서는 노란색에서 갈색이며 결코 초록이 아닙니다. Choose Editor Gutter Mode...가 팔레트나 상태 표시줄 메뉴에서 하나를 고르고, 상태 표시줄 오른쪽의 모드 버튼이나 Alt+G는 한 번 누를 때마다 다음 모드로 넘어갑니다(statusBar.showModeToggle로 버튼을 숨길 수 있습니다). 둘 다 설정에 기록합니다. 예시는 커버되지 않은 줄의 막대와 인라인 횟수를 함께 켭니다:
{
"fuciniCoverage.editorGutter.mode": "uncovered",
"fuciniCoverage.hitCounts.inline": true
}
Screenshot pending — add assets/img/gutters.png (see SCREENSHOTS.md).
coverage 모드 — 줄이 완전히 실행된 곳은 초록, 분기 갈래가 한 번도 타지 않은 곳은 호박색, 아무것도 실행되지 않은 곳은 빨강. 파일의 상태 표시줄 항목은 수치의 출처인 보고서 이름을 알려 주고, 그 옆의 모드 버튼에는 Coverage라고 표시됩니다.
Alt+G를 네 번 — heatmap, off, uncovered, 그리고 다시 coverage.
Quote.cs의 Gutter: Coverage (Red, Amber, Green).히트맵은 파일을 기준으로 한 상대적인 값입니다. 행의 음영은 해당 행의 횟수를 같은 파일에서 가장 많이 실행된 행과 로그 스케일로 다섯 단계에 걸쳐 비교한 것입니다. 따라서 천 번 실행된 루프 본문과 두 번 실행된 함수가 어느 한쪽에 묻히지 않고 모두 눈에 보이며, 모든 것이 정확히 한 번씩 실행된 파일은 균일하게 옅은 것이 아니라 균일하게 따뜻한 색으로 표시됩니다. 어두운 테마에서는 색상 단계가 흐린 올리브색에서 선명한 주황색으로, 밝은 테마에서는 옅은 노란색에서 갈색으로 이어집니다. 어느 쪽이든 색이 짙을수록 실행 횟수가 많다는 뜻이며, 빨간색은 한 번도 실행되지 않은 행을 위해 남겨 둡니다. lineHighlight: "heatmap"은 같은 음영을 코드 뒤에 옅게 깔아 주고, hitCounts.inline은 정확한 횟수를 행 뒤에 적어 줍니다.
{
"fuciniCoverage.editorGutter.mode": "heatmap",
"fuciniCoverage.lineHighlight": "heatmap",
"fuciniCoverage.hitCounts.inline": true
}
Screenshot pending — add assets/img/heatmap-dark.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/heatmap-light.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/heatmap.gif (see SCREENSHOTS.md).색상은 여러분이 정합니다. colorScale.lowColor, midColor, highColor가 거터, 줄 배경 색, 모든 백분율의 빨강, 호박색, 초록을 칠하고, heatmap.colors와 heatmap.colorsDark는 밝은 테마와 어두운 테마용 히트맵의 다섯 가지 음영을 가장 적게 실행된 줄부터 가장 많이 실행된 줄까지 담습니다. 설정 페이지는 아무것도 저장하기 전에 결과를 보여 줍니다. Colour scale 아래에서는 행들이 스크롤되어 지나가는 동안에도 미리 보기가 계속 보입니다 — 두 개의 기준점이 있는 그라데이션, 각자의 색으로 표시된 몇 가지 백분율, 그리고 coverage 모드와 히트맵으로 칠해진 작은 밝은 에디터와 작은 어두운 에디터 — 그리고 색을 고를 때마다 다시 그려집니다.
{
"fuciniCoverage.heatmap.colors": ["#e3f2fd", "#90caf9", "#42a5f5", "#1e88e5", "#0d47a1"]
}


줄에서 한 번도 실행되지 않은 부분
줄은 커버되었거나 커버되지 않았거나 둘 중 하나이지만, 실제는 그 중간인 경우가 많습니다. return x > hi ? hi : x;는 실행되었지만 그 hi 쪽은 한 번도 실행되지 않은 경우입니다. lineHighlight를 켜면 열 범위를 담고 있는 모든 형식(llvm-cov, Istanbul, Go, dotnet-coverage)에 대해, 실행된 줄에서 한 번도 실행되지 않은 부분이 편집기에 색으로 표시됩니다. 주석 처리된 소스가 표시하는 것과 같은 범위입니다. 실행된 줄에만 적용됩니다. 한 번도 실행되지 않은 줄은 이미 줄 전체가 표시되어 있기 때문입니다. C++ 템플릿은 어느 하나의 인스턴스화라도 실행한 곳이면 실행된 것으로 집계합니다. 각 인스턴스화가 무엇을 했는지는 인스턴스화 지표가 보고합니다.
Screenshot pending — add assets/img/partial-line.png (see SCREENSHOTS.md).이 줄을 실행한 테스트
일부 보고서는 줄이 실행되었다는 사실뿐 아니라 어떤 테스트가 실행했는지도 알려 줍니다: .coveragerc에 dynamic_context = test_function을 설정하고 coverage json --show-contexts로 출력한 coverage.py, -coverbytest로 수집한 OpenCover, 그리고 테스트마다 한 섹션(TN:)으로 기록된 lcov 추적 파일 — 그 섹션들은 줄마다 테스트를 가진 하나의 레코드로 합산됩니다. 적중 횟수가 표시되는 줄의 시작 부분에 마우스를 올리면 테스트 이름이 표시됩니다 — 클래스와 메서드로 줄여서, 처음 다섯 개는 이름으로, 나머지는 개수로. 함수의 CodeLens는 몇 개의 테스트가 그 함수를 실행했는지 말해 줍니다. Show Tests That Ran This Line — Command Palette, 에디터의 컨텍스트 메뉴, Visual Studio에서는 Tools → Coverage Studio 또는 Ctrl+Shift+U, T — 은 그 테스트들을 가장 많이 실행한 것부터 나열하고, 고른 테스트를 워크스페이스에서 그것이 작성된 곳에서 엽니다. dotnet test 실행은 어떤 테스트가 무엇을 실행했는지 말하지 못합니다. testRun.perTest를 설정하면 Run Tests with Coverage가 테스트 클래스를 나열해 하나씩 실행하고 각 보고서에 그 클래스를 태그로 붙이므로, 마우스를 올렸을 때의 설명과 렌즈와 명령이 .NET에서도 답할 수 있습니다. 이 정보는 파일별로 보관되므로, 테스트에 대해 아무것도 모르는 보고서와 병합해도 유지됩니다.
{
"fuciniCoverage.testRun.perTest": true
}
# .coveragerc
[run]
dynamic_context = test_function
coverage run -m pytest && coverage json --show-contexts
Screenshot pending — add assets/img/tests-per-line.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/tests-for-line.gif (see SCREENSHOTS.md).
Quote.cs의 62번째 줄에서 Show Tests That Ran This Line — 그 줄을 실행한 테스트와, 그 테스트를 여는 Go to Test.표시에 나타나는 통과와 실패
커버된 줄은 그 테스트가 통과했든 아니든 똑같아 보입니다. 보고서가 어떤 테스트가 줄을 실행했는지 알려 주고 또한 러너의 결과 파일이 그 테스트들이 어떻게 끝났는지 알려 주는 경우, 실패한 테스트가 실행한 줄에는 줄 시작 부분에 빨간 막대가, 개요 눈금자에 줄무늬가 표시됩니다. 호버에는 실패한 테스트의 이름이 나오고, Show Tests That Ran This Line은 각 테스트 옆에 실패라고 적습니다. 테스트가 빨간색일 때 살펴볼 곳은 그 테스트가 거쳐 간 코드입니다. 결과는 로드할 때마다 각 보고서의 폴더에서 — 모든 .trx와 JUnit 작성기들이 쓰는 이름(TEST-*.xml, junit*.xml, test-results*.xml)의 파일 — 읽고, 폴더 기준의 상대 경로나 글로브를 적는 testResults.paths에서도 읽습니다. Run Tests with Coverage는 dotnet test에 보고서 옆에 test-results.trx를 쓰도록 요청하므로, testRun.perTest가 켜져 있으면 따로 설정할 것이 없습니다. testResults.enabled로 이 읽기를 끌 수 있습니다.
{
"fuciniCoverage.testResults.paths": ["build/test-results/**/*.xml", "reports/junit.xml"]
}
Screenshot pending — add assets/img/pass-fail.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-pass-fail.gif (see SCREENSHOTS.md).변경의 영향을 받는 테스트
전체 실행이 느리게 답하는 것을 Run Tests Affected by My Changes…는 바로 답합니다: 모든 테스트 가운데 내가 방금 편집한 코드를 거쳐 간 것은 어느 것인가? git에 testImpact.baseRef 대비 작업 트리의 diff를 요청하고 — 기본값은 HEAD로, 아직 커밋되지 않은 것을 뜻하며, 브랜치가 변경한 모든 것을 보려면 origin/main입니다 — 변경된 줄을 실행한 테스트를, 변경된 부분을 가장 많이 실행한 것부터 나열합니다. 테스트를 고르면 그 테스트가 열립니다. 보고서가 테스트별 실행(testRun.perTest)에서 나온 경우에는 첫 항목이 그 테스트들만 실행하되 클래스마다 자체 보고서에 쓰므로, 나머지 클래스의 보고서는 모두 그대로 남고 합계는 계속 스위트 전체의 합계입니다. 삽입이나 삭제 아래의 줄만 실행한 테스트도 나열됩니다: 그렇게 하지 않으면 그 테스트의 보고서가 엉뚱한 줄을 가리키게 되기 때문입니다.
Screenshot pending — add assets/img/test-impact.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-test-impact.gif (see SCREENSHOTS.md).모든 줄을 여전히 실행하는 가장 적은 수의 테스트
Show Minimal Test Set…은 같은 테스트별 줄 정보로 두 가지 질문에 답합니다: 스위트가 실행하는 모든 줄을 여전히 실행하는 소수의 테스트는 어느 것인가 — 커밋 전의 빠른 실행을 위해 — 그리고 다른 테스트가 이미 실행하는 줄 말고는 아무 줄도 실행하지 않는 테스트는 어느 것인가. 선택된 테스트가 먼저 나오고, 각각 그 테스트가 더하는 줄과 그 테스트만 실행하는 줄이 함께 표시됩니다. 그다음에 나머지가 나오며, 각각 아무것도 더하지 않는다고 표시됩니다. 선택은 탐욕적 방식입니다 — 가장 많이 실행하는 테스트, 그다음에는 거기에 가장 많이 더하는 테스트 — 그래서 가장 작은 집합에 가깝고 매번 같습니다. 줄 기준으로 중복이라고 해서 테스트가 검사하는 내용 기준으로도 중복인 것은 아닙니다: 줄을 하나도 더하지 않는 테스트가 그 줄들에서 값을 단언하는 유일한 테스트일 수도 있습니다. 이 목록은 스위트를 정리할 때 어디를 살펴볼지 알려 줄 뿐, 무엇을 삭제할지 알려 주는 것이 결코 아닙니다.
Screenshot pending — add assets/img/minimal-test-set.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-minimal-test-set.png (see SCREENSHOTS.md).이 테스트를 커버리지와 함께 실행
캐럿을 테스트에 두고 Run This Test with Coverage를 실행하면 — Command Palette, 에디터의 컨텍스트 메뉴, Visual Studio에서는 Tools → Coverage Studio 또는 Ctrl+Shift+U, R — 그 테스트만 커버리지를 켠 채 실행됩니다: 캐럿이 있는 테스트 메서드, 메서드 사이에 있으면 테스트 클래스나 describe 블록, 모든 클래스보다 위에 있으면 파일입니다. 캐럿 아래에 있는 것은 텍스트에서 읽어 내므로, 어떤 언어 서비스가 설치되어 있든 C#, VB, F#([Fact], [Test], [TestMethod] 등), JavaScript와 TypeScript(it, test, describe), Python(def test_…)에서 동작합니다. 폴더의 레시피는 그것으로 좁혀지고 — dotnet test --filter "FullyQualifiedName~…", jest 또는 vitest <file> -t "…", pytest 노드 ID — 기록된 결과는 다른 실행과 같이 로드됩니다. 좁힐 수 없는 러너는 그렇다고 알리고, Run Tests with Coverage가 전부를 실행합니다.
Screenshot pending — add assets/img/run-this-test.gif (see SCREENSHOTS.md).
[Fact] 안에서 Run This Test with Coverage — Tracefiles 목록에 실행이 나타나고, 메서드 위의 줄이 코드를 테스트 하나가 실행했다고 말합니다.Go와 Rust. Go 파일에서는 캐럿이 있는 func TestXxx(또는 Fuzz…, Example…)가 자기 패키지 안에서 정확한 이름으로 단독 실행되고 — go test ./pkg/calc -run "^TestTotal$" — 테스트 밖에서는 그 파일의 패키지가 실행됩니다. Rust 파일에서는 #[test] 함수가 크레이트 안의 경로로 --exact와 함께 실행됩니다. 캐럿이 mod 안에 있고 어떤 테스트 안에도 없으면 그 모듈의 테스트들이 실행되고, tests/ 아래의 통합 테스트는 자체 바이너리에서 실행됩니다(--test api). 러너에는 자기 언어의 파일만 넘겨집니다: Go 폴더의 TypeScript 파일에서는 아무것도 실행하지 않는 실행 대신 안내 문장 하나가 나옵니다.
저장할 때마다 커버리지
testRun.onSave를 켜면 소스를 저장할 때 저장 직후에 그 소스를 커버하는 테스트가 커버리지와 함께 실행되고, 거터가 따라옵니다. .NET 솔루션에서는 저장한 파일의 프로젝트를 .csproj 그래프에서 찾아, 그것을 — 직접 또는 다른 프로젝트를 거쳐 — 참조하는 테스트 프로젝트만 각각 한 번의 dotnet test <project>로 실행합니다. 다른 러너는 레시피 전체를 실행하고, 어떤 프로젝트에도 속하지 않고 어떤 보고서도 측정하지 않는 파일은 아무것도 실행하지 않습니다. 연달아 저장하면 한 번의 실행이 되고, 이미 진행 중인 실행은 중단되지 않습니다. 나머지는 Run Tests with Coverage가 하는 것과 같습니다: 터미널, Output 창, 로드되는 보고서. 기본적으로 꺼져 있습니다 — 직접 선택할 습관이지, 우연히 발견할 기본값이 아니기 때문입니다.
{
"fuciniCoverage.testRun.onSave": true
}
Screenshot pending — add assets/img/coverage-on-save.gif (see SCREENSHOTS.md).
testRun.onSave 켜짐 — Quote.cs를 저장하면 테스트가 저절로 실행되고 메서드 위의 줄이 바뀝니다.앱 자체를 커버리지와 함께
테스트 실행은 테스트가 거쳐 가는 코드를 알려 줍니다. 사람이 거쳐 가는 코드 — 릴리스 전에 화면을 하나씩 클릭해 보거나 고객이 밟은 단계를 재현하면서 — 도 커버리지이며, Run App with Coverage…가 그것을 수집합니다. 폴더의 .NET 앱 — Exe, WinExe, 웹 또는 워커 프로젝트이며 테스트 프로젝트는 결코 아니고, 여러 개 있으면 고르게 됩니다 — 이 Microsoft의 dotnet-coverage 아래에서 자체 콘솔로 시작되므로 콘솔 앱에 입력할 수 있고, 사용자가 닫을 때까지 실행됩니다. 그런 다음 사용자가 거쳐 간 것이 여느 실행처럼 로드되고, 커버리지 세션에서는 테스트가 실행한 것에 더해집니다. 앱이 어떻게 종료되었든 그 실행을 실패로 치지 않습니다. 이 도구는 한 번 설치해야 합니다: dotnet tool install --global dotnet-coverage.
Screenshot pending — add assets/img/run-app.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-run-app.gif (see SCREENSHOTS.md).뮤턴트와 그 위치
뮤테이션 도구 — Java용 PIT, JavaScript, C#, Scala용 Stryker, C와 C++용 Mull — 는 코드를 조금씩 변경하고 각 변경에 대해 테스트를 실행합니다. 어떤 테스트도 알아채지 못한 변경이 생존 뮤턴트입니다. 코드는 실행되었지만 그 코드가 무엇을 했는지는 아무도 검사하지 않았다는 뜻입니다. 뮤테이션 점수는 몇 개가 잡혔는지를 알려 주고, 0.2026.83부터는 편집기가 나머지가 어디에 있는지를 알려 줍니다. 생존 뮤턴트가 있는 줄에는 줄 끝에 메모(⚑ 2 mutants survived)가 붙고, 보고서가 어떤 텍스트인지 알려 주는 경우(Stryker와 Mull이 그렇습니다) 변경된 텍스트에 밑줄이 그어지며, 개요 눈금자에는 줄무늬가 표시됩니다. 마우스를 올리면 무엇이 변경되었는지, 몇 개의 테스트가 그곳을 실행했는지, 그리고 잡힌 뮤턴트의 경우 어떤 테스트가 잡았는지가 표시됩니다.
Screenshot pending — add assets/img/mutant-hover.png (see SCREENSHOTS.md).생존은 테스트가 변경된 코드를 실행했고 모두 통과했음을 의미합니다. 미테스트(보고서의 no coverage)는 그 코드를 실행하는 테스트가 전혀 없어서 아무것도 알아챌 수 없었음을 의미합니다. 잡힌 뮤턴트는 호버에서 개수로만 집계되고 표시되지는 않으며, 애초에 공정한 테스트가 될 수 없었던 뮤턴트 — 예를 들어 컴파일되지 않는 것 — 는 점수에서 제외됩니다. 주석 처리된 소스에는 그러한 줄마다 아래에 행이 하나씩 있고 Next Mutant 버튼(U)이 있으며, HTML 보고서에는 해당 줄로 연결되는 Surviving Mutants 섹션이 있습니다. 따로 켤 것은 없으며, 뮤테이션 보고서가 없는 프로젝트에서는 아무것도 보이지 않습니다.
Screenshot pending — add assets/img/mutants.gif (see SCREENSHOTS.md).테스트가 알아챌까? 캐럿 위치에서의 뮤테이션 실행
프로젝트 전체의 뮤테이션 실행은 한 시간이 걸리지만, 함수 하나의 뮤테이션 실행은 일 분이면 됩니다. Run Mutation Tests Here가 그 일 분짜리 실행을 합니다: 캐럿이 있는 함수 — 또는 선택한 줄들, 또는 파일 — 를 변이시키라고 폴더의 뮤테이션 러너에 지시하고, 그 보고서를 화면의 커버리지 옆에 로드하며, 거기에 생존 뮤턴트가 표시됩니다. C#에는 Stryker.NET(dotnet tool install --global dotnet-stryker)을 쓰며, 문자 범위와 그 파일의 프로젝트를 참조하는 테스트 프로젝트를 알려 줍니다. JavaScript와 TypeScript에는 StrykerJS를 쓰며 줄을 알려 주고, Java에는 Maven과 함께 PIT을 쓰며 클래스를 알려 줍니다. 러너가 어떻게 종료되었든 그 실행을 실패로 치지 않습니다: 임계값에 못 미치는 점수는 종료 코드일 뿐이고, 보고서는 여전히 보고서입니다. 러너가 아무것도 쓰지 않았으면 그렇다고 알리고, 무엇을 설치해야 하는지도 함께 알려 줍니다.
Screenshot pending — add assets/img/mutation-here.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-mutation-here.gif (see SCREENSHOTS.md).VS Code 자체의 Test Coverage 보기
testCoverage.publish가 켜져 있으면(기본값) 로드된 모든 실행이 에디터의 네이티브 Test Coverage 보기 — Test Explorer의 커버리지 패널, 그것이 Explorer에 두는 파일별 백분율, 에디터 자체의 Show Inline Coverage 토글 — 에도 줄, 분기 갈래, 함수로 전달되며, 세부 정보는 요청 시 로드됩니다. 어느 추적 파일에서 왔든, 테스트 어댑터 없이 말입니다. Show in Test Coverage View는 설정과 무관하게 활성 실행을 게시하고 패널을 열며, 상태 표시줄 메뉴는 quickActions.showTestCoverage 뒤에서 이를 제공합니다. 끄면 Test Explorer에 Fucini Coverage 항목이 아예 나타나지 않습니다. 트레이스 파일이 테스트 이름을 담고 있으면(lcov의 TN: 섹션) 각 테스트가 Test Explorer의 Fucini Coverage 아래에 나타나고, 뷰에서 파일의 커버리지를 테스트별로 필터링할 수 있습니다.
Screenshot pending — add assets/img/test-coverage-view.png (see SCREENSHOTS.md).Problems 패널의 커버되지 않은 줄
본질적으로 시끄럽기 때문에 기본값은 꺼짐이며, 언제나 열린 문서에만 적용됩니다 — 파일 이천 개짜리 실행이 패널을 넘치게 할 수 없습니다. 파일당 항목 하나로 유지되는 problems.enabled와는 독립적입니다:
{
"fuciniCoverage.problems.perLine": "uncoveredAndPartial"
}
Screenshot pending — add assets/img/problems-panel.png (see SCREENSHOTS.md).9. 차이 커버리지
장식을 git 기준 참조 대비 변경된 라인으로만 제한합니다 — PR이 실제로 무엇을 커버했고 커버하지 않았는지 정확히 검토하는 데 이상적입니다:
{
"fuciniCoverage.gitDiff.enabled": true,
"fuciniCoverage.gitDiff.baseRef": "origin/main"
}
Screenshot pending — add assets/img/diff-coverage.png (see SCREENSHOTS.md).Visual Studio에서는. 같은 두 설정을 같은 파일에서 읽습니다. 확장은 실행의 모든 파일에 대해 git diff <baseRef>를 직접 실행하고, 실행을 브랜치에서 변경한 줄로 줄입니다 — 여백에서, Coverage 창에서, 게이트에서 모두. git이 아무것도 답하지 않을 때는 Output 창이 git의 답을 알려 줍니다.
새 코드에 대한 게이트
threshold.newCode는 전체 실행에 대한 게이트들 옆에 놓이는 별도의 게이트입니다: gitDiff.baseRef 대비 변경된 줄 가운데 측정할 수 있는 줄 중에서 실행되어야 하는 최소 백분율입니다. 전체가 62%인 프로젝트도 오늘 작성하는 코드는 테스트되어야 한다고 요구할 수 있습니다. 로드할 때마다 전체 실행을 대상으로 계산하며, 전체 실행은 화면에 그대로 남습니다 — gitDiff.enabled는 그와 다른 것으로, 실행 대신 변경된 줄을 표시합니다. Check Coverage Thresholds와 Problems의 컴플라이언스 항목은 이 게이트의 실패를 별도의 문장으로 알립니다: New code 72.00% < 80% (18 of 25 line(s) changed against origin/main ran). 측정할 수 있는 줄이 하나도 없는 변경 — 주석, README — 은 아무것도 실패시키지 않습니다.
{
"fuciniCoverage.threshold.newCode": 80,
"fuciniCoverage.gitDiff.baseRef": "origin/main"
}
Screenshot pending — add assets/img/new-code-gate.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-new-code-gate.png (see SCREENSHOTS.md).태그별, 작성자별, 날짜별 새 코드
새 코드는 기본적으로 작업 트리가 gitDiff.baseRef 대비 변경한 줄입니다 — 브랜치, 커밋 또는 태그를 지정하며, "v1.4.0"은 그 릴리스 이후의 모든 것입니다. 두 설정은 참조(ref)로는 물을 수 없는 것을 묻습니다. gitDiff.author는 작성자 이름의 일부를 받고, 그러면 새 코드는 git이 그 작성자의 것으로 보는 줄입니다. gitDiff.since는 날짜를 받고, 그러면 새 코드는 어느 브랜치를 통해 들어왔든 그날 또는 그 이후에 마지막으로 변경된 줄입니다. 둘을 함께 쓰면 그 작성자가 그날 이후 작성한 줄입니다. 이 줄들은 git blame에서 파일 하나씩 읽어 오며 — 큰 실행에서는 로드할 때마다 그만큼 시간이 걸립니다 — 차이 커버리지와 위의 게이트에서 diff를 대신합니다. 아직 커밋하지 않은 줄은 어느 경우에나 포함됩니다.
{
"fuciniCoverage.gitDiff.author": "Ada",
"fuciniCoverage.gitDiff.since": "2026-09-01"
}
Screenshot pending — add assets/img/new-code-author.png (see SCREENSHOTS.md).간접 변경: 아무도 건드리지 않았는데 달라진 것
diff는 어느 줄이 변경되었는지 알려 주고, 두 실행은 어느 줄이 더 이상 실행되지 않거나 새로 실행되기 시작했는지 알려 줍니다. 살펴볼 만한 줄은 이 둘이 어긋나는 줄입니다: 아무도 편집하지 않았는데 더 이상 실행되지 않는 코드로, 테스트가 삭제되었거나, 앞쪽의 분기가 이제 일찍 반환하거나, 픽스처가 바뀌었기 때문입니다. diff를 검토해서는 이런 줄을 볼 수 없습니다 — 정의상 diff 밖에 있기 때문입니다. Show Indirect Coverage Changes…는 이런 줄을 파일별로, 가장 많이 잃은 파일부터 나열하고, 고른 파일을 그런 줄 가운데 첫 줄에서 엽니다. baseline.report가 CI 기준선을 지정한 경우에는 실행을 그 기준선과 비교하고 — 풀 리퀘스트를 판정하는 기준이 바로 그것입니다 — 그렇지 않으면 이전 실행과 비교합니다. 작업 트리가 gitDiff.baseRef 대비 변경한 줄과, 그 변경이 파일의 줄을 밀어내는 지점 아래의 모든 것은 제외됩니다.
Screenshot pending — add assets/img/indirect-changes.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-indirect-changes.png (see SCREENSHOTS.md).10. 종합 점수
확장 프로그램은 6개의 숫자를 보고하는 대신 이를 단일 가중 조화 평균(WHM)으로 통합합니다. 백분율 pᵢ과 가중치 wᵢ를 가진 지표의 경우:
WHM = ( Σ wᵢ ) / ( Σ wᵢ / pᵢ )
조화 평균은 가장 작은 항에 의해 지배되므로, 약한 지표가 완벽한 지표에 의해 가려질 수 없습니다 — 이는 안전 게이트에 필요한 정확한 특성입니다. 기본 가중치:
| 지표 | 가중치 | 근거 |
|---|---|---|
| MC/DC | 4 | IEC 61508 SIL 3–4 / ISO 26262 ASIL C–D / DO-178C DAL A–B. |
| 분기 | 2 | IEC 61508 SIL 2+ / ISO 26262 ASIL B+. |
| 조건 | 3 | 분기와 MC/DC 사이 (DO-178C, ISO 26262). |
| 리전 | 1.5 | 구문 내부 경로(예: 부분 단락 평가). |
| 행 | 1 | IEC 61508 SIL 1+ / ISO 26262 ASIL A+. |
| 함수 | 1 | 데드 코드 검사. |
| 인스턴스화 | 0.5 | C++ 템플릿 커버리지. 가장 좁은 범위. |
| 함수 호출 | 1 | 실행된 호출 지점 (gcov, VectorCAST, Testwell CTC++, TRACE32). |
| 오브젝트 코드 | 0 | 가중치를 지정하지 않으면 꺼져 있습니다. 구문 커버리지를 포괄하기 때문입니다. |
| 뮤테이션 점수 | 0 | 가중치를 지정하지 않으면 꺼져 있습니다. 커버리지가 아니기 때문입니다. |
해당 지표를 점수에서 제외하려면 가중치를 0으로 설정하세요. 데이터에 없는 지표(예: 일반 lcov 실행의 MC/DC)는 단순히 생략됩니다.
오브젝트 코드와 뮤테이션 점수의 가중치는 직접 바꾸기 전까지 0입니다 (whmWeights.objectCode, whmWeights.mutation). 오브젝트 코드 커버리지는 구문 커버리지를 포괄하므로, 둘 모두에 가중치를 주면 같은 증거를 두 번 세게 됩니다. 뮤테이션 점수는 애초에 커버리지가 아닙니다. 테스트 스위트가 모든 행을 실행하고도 아무것도 검출하지 못할 수 있습니다. 그래도 둘 다 자체 열과 자체 임계값을 갖습니다.
조건 커버리지
a && b는 하나의 결정 — 두 개의 분기 — 이자, 네 가지 결과를 갖는 두 개의 조건입니다. 테스트 스위트가 두 분기를 모두 지나면서도 b가 거짓인 경우를 한 번도 보지 못할 수 있습니다. 이때 분기 커버리지는 완전하지만 조건 커버리지는 4분의 3입니다. 이 수준은 DO-178C와 ISO 26262에서 분기 커버리지와 MC/DC 사이에 위치하며, 0.2026.83부터는 분기에 합산되지 않고 독립된 지표가 되었습니다. 상태 표시줄 카드의 한 행, Coverage 보기와 보고서 및 내보내기의 한 열, 점수에서의 가중치 3(whmWeights.conditions), 그리고 게이트(threshold.conditions. standard 프로필에서는 게이트가 적용되지 않고, safety에서는 100)로 다뤄집니다.
BullseyeCoverage의 condition 프로브, TRACE32의 cond 내보내기, 그리고 -fcondition-coverage로 빌드한 GCC 14에서 읽어 옵니다. 조건과 결정을 구분하지 않는 보고서에는 이러한 행도, 열도, 가중치도 없습니다. Bullseye 또는 TRACE32를 사용하는 경우: 이전에는 조건이 분기로 집계되었으므로 이번 릴리스에서 분기 백분율이 달라지고, 새 가중치로 인해 종합 점수도 달라집니다. 이전과 같은 점수를 원하면 whmWeights.conditions를 0으로 설정하십시오.
GCC 14, 줄 단위로. -fcondition-coverage를 쓰면 gcov가 어느 조건의 어느 결과가 빠졌는지 알려 줍니다 — 조건 1은 참인 적이 없음, 조건 0은 어느 쪽으로도 평가된 적 없음 — 그리고 각 조건은 gcov의 JSON과 텍스트 목록(condition outcomes covered 3/6)을 바탕으로 해당 줄에 표시되고 호버에 이름이 나옵니다. 이 지표는 다른 지표들이 있는 곳에 함께 있습니다: threshold.conditions가 게이트를 걸며 실행에 그런 수치가 없으면 판정하지 않고, Copy Coverage Summary에는 Conditions 열이 있으며, badge.metric은 conditions를 받고, 검색 상자는 conditions < 80을 받습니다. 함수의 분기 수치에는 그 조건들의 결과가 들어가지 않으며, 파일과 실행의 분기 수치도 마찬가지입니다.
Screenshot pending — add assets/img/gcc-conditions.png (see SCREENSHOTS.md).복잡도와 CRAP
일부 보고서에는 각 함수의 순환 복잡도가 담겨 있습니다. OpenCover (Coverlet이 출력하는 형식), JaCoCo, Clover, Cobertura가 그렇습니다. 이 경우 확장은 그 복잡도와 직접 측정한 커버리지로부터 함수의 CRAP 점수(Change Risk Anti-Patterns)를 계산합니다:
CRAP = complexity² × (1 − coverage)³ + complexity
단순하고 완전히 테스트된 함수의 점수는 자신의 복잡도와 같고 그 이상은 되지 않습니다. 복잡하고 거의 테스트되지 않은 함수의 점수는 수백에 이릅니다. 데모 프로젝트의 C# 샘플에서 Price()는 복잡도가 22이고 행의 약 37%가 커버되어 142.2가 되며, Shipping()은 복잡도가 12이고 완전히 커버되어 12가 됩니다. 통상적인 기준선은 30입니다. 이 값 이상인 함수는 HTML 보고서의 Riskiest Methods 아래에 점수가 나쁜 순서대로 나열됩니다.
복잡도와 점수는 함수의 CodeLens와 주석이 달린 소스의 함수 옆에 표시됩니다. Max CRAP은 파일 내 함수 중 가장 높은 점수입니다. 평균이 아니라 최악의 값이며, Coverage 뷰, HTML 보고서, CSV 및 Markdown 내보내기에서 하나의 열로 표시됩니다. 이것은 참고 정보입니다. 임계값이 없고 종합 점수에서의 가중치도 없습니다. 복잡도가 담기지 않은 보고서(lcov, gcov, Istanbul, coverage.py)에는 CRAP이 없으며, 빈 열도 표시되지 않습니다.
0.2026.83부터는 C와 C++에서도 제공됩니다. llvm-cov는 복잡도를 보고하지 않으므로, 보고서에 이미 들어 있는 분기 데이터로부터 계산합니다. 함수 자신의 파일에 작성된 조건의 수에 1을 더한 값으로, 이는 McCabe의 정의이며 .NET과 Java용 소스 수준 도구가 세는 것과 같습니다. 다른 파일의 매크로에서 나온 조건 — 예를 들어 모든 assert — 은 세지 않습니다.
Screenshot pending — add assets/img/riskiest-methods.png (see SCREENSHOTS.md).Risk hotspots, 그리고 어떤 파일을 보여 줄지
Coverage 보기의 트리 아래에서 Risk hotspots는 복잡한 코드가 적은 커버리지와 만나는 함수를 가장 나쁜 것부터 나열하며, 각 항목은 파일을 그 함수 위치에서 엽니다. 함수는 CRAP 점수로 — hotspots.crapThreshold, 기본값 30, 이 지표의 저자들이 제안한 수치 — 또는 순환 복잡도만으로 — hotspots.complexityThreshold, 기본은 꺼짐 — 선정됩니다. 복잡도를 담은 보고서(OpenCover, Coverlet의 Cobertura, JaCoCo, llvm-cov)에만 있습니다. Community는 개수와 최악의 점수를 보고, 순위 목록은 Pro입니다. 정렬 옆의 두 번째 드롭다운은 트리에 어떤 파일을 보여 줄지 정합니다 — 전체, 공백이 있는 파일, 테스트되지 않은 파일, 또는 마지막 실행 이후 변경된 파일. 폴더는 파일을 따르되 자체 수치를 유지합니다. 둘 다 Visual Studio의 Coverage 창에도 있습니다.
Screenshot pending — add assets/img/vs-hotspots.png (see SCREENSHOTS.md).네임스페이스, 클래스, 메서드
클래스 이름을 담은 .NET 보고서 — Cobertura와 Coverlet의 coverage.cobertura.xml, OpenCover — 에서는 세 번째 드롭다운 Folders / Namespaces가 같은 실행을 네임스페이스, 클래스, 메서드로 그립니다: 네임스페이스의 수치는 그 클래스들의 합, 클래스의 수치는 그 메서드들의 합으로, 폴더의 수치가 그 파일들의 합인 것과 똑같으며, 같은 정렬과 같은 필터를 씁니다. 메서드 행은 파일을 그 메서드 위치에서 열고, 네임스페이스 없이 선언된 클래스는 (no namespace) 아래에 있습니다. 선택은 coverageView.perspective에 기록됩니다. 클래스 이름이 없는 실행에는 드롭다운이 없고 폴더가 표시됩니다. Visual Studio에서는 Coverage 창에 같은 드롭다운이 있습니다.
Screenshot pending — add assets/img/namespace-perspective.png (see SCREENSHOTS.md).
트리 검색
버튼과 드롭다운 아래에 검색 상자가 있습니다. 단어는 이름이나 경로에 그 단어가 들어 있는 행을 남깁니다 — 입력한 모든 단어가 있어야 합니다. 비교는 수치가 그 조건을 통과하는 행을 남깁니다 — 점수에 대한 < 80%, lines >= 90, branches = 0, functions != 100, mcdc < 50 — 그리고 invoice < 80은 둘 다를 요구합니다. 네임스페이스 관점의 메서드 행과 risk hotspots도 파일과 함께 검색되므로, 함수는 실행이 그것을 둔 곳에서 찾아집니다. 트리는 입력하는 대로 페이지 안에서 다시 그리지 않고 필터링됩니다. 일치하는 항목을 담은 폴더는 그것을 위해 열리고, 상자가 비면 다시 닫힙니다. Esc가 상자를 비웁니다. Visual Studio에서도 같은 상자, 같은 문법입니다.
Screenshot pending — add assets/img/tree-search.gif (see SCREENSHOTS.md).lines < 80.트리가 에디터를 따라갑니다
보고 있는 파일이 Coverage 보기에서 강조되고, 그 위의 폴더들이 펼쳐지며, 그 행이 보이도록 스크롤됩니다 — 이미 열려 있는 파일을 트리에서 찾아 헤맬 필요가 더 이상 없습니다. 그 밖에는 트리가 스크롤 위치를 유지하며, 아무것도 다시 그려지지 않습니다. coverageView.followActiveEditor는 기본적으로 켜져 있으며, 트리를 자신이 둔 자리에 그대로 두고 싶다면 이 설정으로 끌 수 있습니다.
Screenshot pending — add assets/img/follow-editor.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-follow-editor.gif (see SCREENSHOTS.md).11. 컴플라이언스 게이팅
COMPLIANT / NON-COMPLIANT 판정(주석 처리된 소스 보기, HTML 보고서, 두 상태 표시줄 호버에 표시됨)은 지표별 임계값과 모드에 따라 결정됩니다:
Screenshot pending — add assets/img/statusbar.png (see SCREENSHOTS.md).| 모드 | COMPLIANT 조건… |
|---|---|
strict (default) | 개별적으로 검사되는 각 지표가 자체 임계값을 충족합니다 — 절충 없음. |
whm | 단일 가중 종합 점수가 threshold.weighted를 충족합니다. |
both | 가중 게이트와 지표별 엄격 게이트를 모두 충족합니다. |
either | 가중 게이트 또는 지표별 엄격 게이트 중 하나를 충족합니다(가장 느슨함). |
임계값을 0으로 설정하면 해당 게이트가 꺼지며, 보고서에 담기지 않은 지표는 판정되지 않습니다. 설정하지 않은 임계값이 무엇을 의미하는지는 아래의 프로필이 결정합니다. 필요에 따라 평가하려면 Fucini Coverage: Check Coverage Thresholds를 실행하세요.
Visual Studio에서는. Tools → Coverage Studio → Check Coverage Thresholds는 같은 threshold.* 키에 따라 실행을 판정하고 상태 표시줄과 Output 창에 결과를 알립니다. compliance.diagnostics, problems.enabled, problems.perLine 또는 deadCode.enabled가 있으면 결과가 컴파일러 자체의 항목 옆 Error List에 놓입니다 — 게이트 아래의 파일마다 하나, 미커버 범위마다 하나, 한 번도 실행되지 않은 함수마다 하나 — 각 항목은 파일을 해당 줄에서 엽니다.
Screenshot pending — add assets/img/vs-error-list.png (see SCREENSHOTS.md).임계값 프로필
threshold.profile은 설정하지 않은 임계값이 무엇을 의미하는지를 결정합니다. 0.2026.82부터 기본값인 standard는 안전과 관련되지 않은 일반적인 프로젝트에 요구할 수 있는 수준입니다. safety는 모든 게이트를 100으로 둡니다. 이는 세이프티 케이스가 요구하는 수준이며, 0.2026.81까지 출하되던 동작과 정확히 같습니다.
| 지표 | standard | safety |
|---|---|---|
| 행 | 80 | 100 |
| 함수 | 80 | 100 |
| 리전 | 75 | 100 |
| 분기 | 70 | 100 |
| 종합 점수 | 75 | 100 |
| MC/DC, 인스턴스화, 함수 호출, 오브젝트 코드 | 게이트 없음 | 100 |
| 조건 | 게이트 없음 | 100 |
| 뮤테이션 점수 | 게이트 없음 | 게이트 없음 |
직접 설정한 임계값은 어느 프로필보다도 우선합니다. 예시에서는 분기를 90으로, 나머지는 모두 100으로 게이트합니다. 일부 지표만 100으로 유지하려면 standard를 그대로 두고 해당 지표를 직접 설정하세요. 설정이 동작하는 방식에서 비롯되는 주의 사항이 하나 있습니다. 출하 시 기본값과 같은 값은 값이 아예 없는 것과 구별할 수 없으므로, safety에서는 표준 수치와 정확히 같은 값으로 적은 임계값(예를 들어 행의 80)도 여전히 100으로 간주됩니다.
{
"fuciniCoverage.threshold.profile": "safety",
"fuciniCoverage.threshold.branch": 90
}
Screenshot pending — add assets/img/threshold-profile.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/threshold-profiles.gif (see SCREENSHOTS.md).이전 기본값에 의존하고 있었다면, 0.2026.82로 업데이트한 뒤에는 safety를 선택할 때까지 더 관대하게 판정됩니다. 이전부터 사용하던 설치에는 이 사실이 한 번 안내되며, 프로필을 사용자 설정에 기록하는 Keep 100% (safety) 버튼이 함께 표시됩니다. 공유 프로젝트라면 모두가 같은 기준으로 판정되도록 작업 영역 설정에도 넣어 두세요. Configure Coverage Compliance & Thresholds...에서는 임계값 그리드 위에 프로필이 있으며, 실시간 미리 보기는 실제로 적용 중인 게이트로 판정합니다. 모든 카드와 보고서에서 게이트가 꺼진 지표는 체크 표시나 X 표시 대신 중립적인 대시와 함께 수치를 표시합니다.
Screenshot pending — add assets/img/statusbar-metrics.png (see SCREENSHOTS.md).11a. 목적 코드 커버리지
여기의 다른 모든 지표는 소스에서 측정됩니다. 도구가 코드를 계측하고, 계측된 빌드가 실행되며, 카운터가 어떤 문·분기·조건이 실행되었는지 알려 줍니다. 목적 코드 커버리지는 다른 것을 측정합니다 — 빌드된 바이너리 중 실제로 실행된 양을, 소스를 계측하는 대신 명령 스트림을 관찰해 명령 바이트 단위로 셉니다. 이것이 중요한 이유는 컴파일러가 소스의 어느 줄로도 설명되지 않는 코드를 내보내기 때문입니다. 배열 경계 검사, switch 점프 테이블, 레지스터 스필, 스택 프로브, 해당 명령이 없는 코어에서 나눗셈이나 부동소수점을 위해 호출하는 런타임 보조 루틴 같은 것들입니다. 또한 이것이 어셈블리를 다루는가?라는 물음에 답할 수 있는 유일한 지표이기도 합니다. 손으로 쓴 어셈블리는 결코 계측되지 않으며 소스 기반 도구는 거기에 닿지 못합니다. DO-178C는 그 이유를 분명히 밝힙니다. 레벨 A에서 컴파일러나 링커가 소스 문으로 직접 추적되지 않는 코드를 생성하면, 목표 6.4.4.2b는 바로 그 생성된 코드에 대한 추가 검증을 요구합니다.
이것은 문 커버리지를 포함합니다 — 실행된 모든 명령은 어떤 문에서 나왔으므로, 목적 코드 커버리지 100%는 문 커버리지 100%를 의미합니다. 그 역은 성립하지 않으며, 바로 그 비대칭이 이를 측정하는 이유 전부입니다. 여기서 두 가지가 따라옵니다. 종합 점수에서 아무 가중치도 갖지 않습니다. 같은 실행에 대한 두 척도를 평균 내면 같은 증거를 두 번 세는 셈이기 때문입니다. 대신 fuciniCoverage.threshold.objectCode로 게이트됩니다 — 가중치가 아니라 요구사항이며, 표준이 요구하는 방식이 바로 이것입니다. 그리고 격차 자체가 산출물입니다. 행 커버리지 100%에 목적 코드 커버리지가 100% 미만인 실행은, 소스가 설명하지 못하는 컴파일러 생성 코드를 정확히 짚어낸 것입니다. 그래서 컴플라이언스 카드는 이를 「94%」로 묻어 두지 않고 312바이트가 한 번도 실행되지 않음, 행 커버리지는 100%라고 말합니다. 그 반대 — 소스는 실행되지 않았는데 바이너리 전체가 실행되었다고 보고되는 경우 — 는 낮은 점수가 아니라 모순입니다. 거의 언제나 병합 한쪽의 오래된 트레이스 파일이거나, 파일 경로와 한 번도 맞지 않은 모듈 이름입니다. 이는 발견 사항으로 보고됩니다.
목적 코드 커버리지는 바이너리가 명령을 관찰할 수 있는 곳에서 실행되어야 합니다. 경로는 셋이고 비용 차이가 매우 큽니다. 목적 코드 커버리지를 만들어 내는 것은 세 번째뿐이며, 앞의 둘을 함께 적는 이유는 이들이 관련된 문제 — 실제로 풀 가치가 있는 쪽인 경우가 많은 문제 — 를 해결하기 때문입니다.
- 타깃에서 실행되는 계측 빌드. GCC 크로스 컴파일러는
-fprofile-arcs -ftest-coverage를 받아들이므로, 워크스테이션에서 통하는 계측이 타깃에서도 통합니다. 다만 베어메탈 시스템에는.gcda카운터를 쓸 파일 시스템이 없고, 쓸 시점이 될exit()도 없는 경우가 많습니다. 카운터는 어차피 RAM에 있으므로, 그 메모리를 덤프해 타깃 밖에서 파일을 재구성하는 것이 해법입니다. NASA JPL의embedded-gcov(Apache-2.0)가 바로 그 일을 하며, 파일 시스템도 운영체제도 표준 C 라이브러리도 필요로 하지 않습니다. 이렇게 얻는 것은 여러분의 크로스 컴파일러가, 여러분의 명령어 집합을 대상으로, 여러분의 하드웨어에서 만든 빌드의 문·분기·함수 커버리지입니다. 목적 코드 커버리지가 아니며, 측정 대상 바이너리는 계측된 것이라 출하본보다 크고 느립니다. 결과는 LCOV, gcovr JSON, gcov JSON으로, 또는 GCC 9보다 오래된 툴체인에서는 일반 텍스트.gcov목록으로 불러오십시오. - 명령어 집합 시뮬레이터. 실제 타깃 바이너리를 시뮬레이터에서 실행하고 수행된 주소에서 커버리지를 도출합니다. 하드웨어도, 계측도, 프로브도 필요 없으며, 명령을 관찰하기 때문에 진짜 목적 코드 커버리지를 만들어 낼 수 있습니다. 한계는 충실도입니다. 시뮬레이터는 코어는 잘 모델링하지만 주변장치는 덜 그렇습니다. 여러분의 실리콘을 정밀하게 모델링하지 않는 한 시스템 전체 결과는 의심하고 보십시오.
- 온칩 트레이스와 디버거. 인증 등급의 경로이자 진정으로 비침습적인 유일한 방법입니다. 코어의 트레이스 유닛이 명령 스트림을 디버거에 보고하고, 디버거가 그것을 커버리지로 바꿉니다. 아무것도 계측되지 않고, 코드 크기는 변하지 않으며, 타이밍도 영향을 받지 않습니다 — 바로 그 점이 결과를 실제 출하하는 바이너리에 대한 증거로 만듭니다. 예산을 잡기 전에 실리콘을 확인하십시오. 많은 마이크로컨트롤러 제품군에서 완전한 트레이스는 큰 트레이스 버퍼와 고속 트레이스 포트를 갖춘 에뮬레이션 또는 개발용 변종에서만 제공되고, 양산품은 축소된 트레이스 유닛만 노출합니다. 그에 대한 공급사의 대안은 코드를 계측하고 CPU 시간을 소모하는 소프트웨어 트레이스인데, 이는 이 경로를 택한 이유 자체를 없애 버립니다.
많은 임베디드 프로젝트가 동일한 소스를 개발 머신용으로 컴파일해 그곳에서 단위 테스트를 실행함으로써 커버리지를 측정합니다. 빠르고 하드웨어가 필요 없어 대부분의 팀에게 올바른 기본값이지만, 그 증거가 실제로 무엇을 설명하는지는 분명히 해 둘 가치가 있습니다: 출하하는 것과는 다른 컴파일러, 다른 최적화기, 다른 명령어 집합, 다른 바이너리라는 점입니다. 대부분의 소프트웨어에서는 받아들일 만하고 잘 이해된 절충입니다. IEC 61508, ISO 26262, DO-178C 기준으로 평가되는 작업에서는 이것이 바로 그 표준적인 “호스트 대 타깃” 반론이며, 위의 경로들이 그에 대한 표준적인 답입니다 — 첫 번째는 소스 커버리지에 대해, 세 번째는 목적 코드에 대해 그 반론을 해소합니다.
현재 목적 코드용으로 읽는 내보내기는 metric="object"를 지정한 Lauterbach TRACE32의 COVerage.EXPORT.ListModule입니다. 다른 트레이스 파일과 마찬가지로 불러오면 됩니다. 이 지표는 유료 라이선스와 평가 기간 동안에만 점수화되고 게이트됩니다. Community 설치판은 이를 점수화하지 않지만, 트레이스 파일에 이 데이터가 포함되어 있다는 사실은 알려 줍니다. 파일 안의 가장 강력한 증거를 조용히 빠뜨리는 컴플라이언스 판정은, 무엇을 빠뜨렸는지 말하는 판정보다 더 나쁘기 때문입니다.
12. 비코드 라인 제외
excludeComments가 켜져 있으면(기본값), 전적으로 주석 전용 또는 빈 라인에 속하는 구문은 합계에서 제외됩니다 — 이는 우연한 적중 횟수가 주석에 떨어지는 알려진 llvm-cov/gcov 특이 현상도 무력화합니다. 표준 마커도 준수됩니다:
x = risky(); // LCOV_EXCL_LINE
// LCOV_EXCL_START
debug_only_block();
// LCOV_EXCL_STOP
C, C++, Objective-C, CUDA, C#에서는 전처리기 지시문도 코드가 아닌 것으로 칩니다. #로 시작하는 줄 — #define, #include, #if — 과 끝의 백슬래시로 이어지는 줄들입니다. gcov는 매크로의 각 사용을 그 매크로가 정의된 줄에 계산하므로, 보고된 유일한 줄이 #define CHANNEL_COUNT (33U)였던 헤더는 .c 파일의 루프가 거기까지 실행되었기 때문에 100% 커버된 것으로 읽혔고, 아무도 상수를 쓰지 않은 헤더는 0%로 읽혔습니다. 이런 헤더는 이제 측정할 것이 없으므로 목록에 나오지 않습니다.
제외된 라인을 그래도 카운트하려면 excluded.includeInTotals를 true로 설정하세요.
파일이나 폴더를 트리에서 제외하기
Coverage 보기에서 파일이나 폴더를 오른쪽 클릭하고 Exclude from Coverage를 고르거나 — 행의 경로 동작 중에도 있습니다 — 열린 파일에서 Exclude This File from Coverage를 실행하면, 파일의 워크스페이스 기준 상대 경로 또는 폴더의 /**가 폴더 설정의 fuciniCoverage.ignore에 한 번 들어가고, 다시 로드하면 모든 합계와 모든 페이지에서 빠집니다. 패턴은 거기에 있으니 다시 빼낼 수 있습니다. Visual Studio에서는 행의 메뉴와 Tools → Coverage Studio에 같은 두 명령이 있어, 같은 설정을 같은 파일에 씁니다.
Screenshot pending — add assets/img/exclude-from-tree.gif (see SCREENSHOTS.md).
fees.ts에 Exclude This File from Coverage — 그 파일이 빠진 트리와 .vscode/settings.json의 패턴..NET의 특성과 네임스페이스
두 설정이 보고서가 말하지 못하는 것을 소스에서 읽습니다. ignore.attributes — 기본값은 ExcludeFromCodeCoverage — 는 지정한 특성 아래의 클래스, 메서드, 속성을, 어떤 도구가 보고서를 썼든 LCOV_EXCL_START/STOP처럼 제외합니다: Coverlet은 이 특성을 존중하지만 OpenCover, dotCover, 변환된 lcov는 그렇지 않은데, 이제 모두가 일치합니다. 이름은 Attribute 접미사가 있든 없든, 네임스페이스가 있든 없든 됩니다. GeneratedCode, Obsolete 또는 직접 만든 것을 추가하세요. ignore.namespaces는 네임스페이스 선언이 접두어와 일치하는 모든 파일을 제외하며, *가 와일드카드입니다 — Acme.Generated, Acme.*.Migrations, *Tests — 그리고 Output 창이 제외한 파일의 이름을 알려 줍니다. 둘 다 주석 마커를 읽는 것과 같은 단계에서 읽히며, 두 에디션 모두에서 그렇습니다.
{
"fuciniCoverage.ignore.attributes": ["ExcludeFromCodeCoverage", "GeneratedCode"],
"fuciniCoverage.ignore.namespaces": ["Acme.Generated", "*.Migrations"]
}
에디터에서 제외하기
줄을 선택하고 전구, 에디터의 컨텍스트 메뉴 또는 Command Palette에서 Exclude Selection from Coverage를 고르면 — Visual Studio에서는 전구(Ctrl+.), 코드 창의 오른쪽 클릭 메뉴, Tools → Coverage Studio 또는 Ctrl+Shift+U, X — 제외가 코드가 있는 곳에 기록됩니다: C#, VB, F#의 클래스, 메서드, 속성 위에는 [ExcludeFromCodeCoverage]를, 파일이 이미 System.Diagnostics.CodeAnalysis를 가져오고 있으면 짧은 이름으로, 그렇지 않으면 정규화된 전체 이름으로, using을 추가하지 않아도 되도록; 코드 한 줄의 끝에는 LCOV_EXCL_LINE; 여러 줄 둘레에는 LCOV_EXCL_START와 LCOV_EXCL_STOP을 첫 줄의 들여쓰기에 맞춰 — 그 언어 자체의 주석 기호 //, #, ', -- 또는 ;로. 실행 취소는 한 단계입니다. 전구는 Problems 항목이 커버되지 않았다고 표시한 줄에서도 이것을 제안합니다. 이미 표시된 줄이나 이미 특성이 붙은 멤버는 그대로 둡니다.
Screenshot pending — add assets/img/exclude-selection.gif (see SCREENSHOTS.md).
LCOV_EXCL 표시, 그다음 메서드 위의 [ExcludeFromCodeCoverage].분기만 제외하기, 그리고 gcovr의 마커
방어적인 else, 어떤 값도 도달하지 않는 default:, 컴파일러가 예외를 위해 추가하는 갈래: 줄은 실행되고 계산에 들어가야 하며, 탈 수 없는 것은 그 분기뿐입니다. LCOV_EXCL_BR_LINE과 LCOV_EXCL_BR_START … LCOV_EXCL_BR_STOP은 해당 줄의 분기를 계산에서 빼고 줄은 계산에 남깁니다. LCOV_EXCL_EXCEPTION_BR_LINE과 그 영역 마커는 그보다도 적게 뺍니다 — gcov의 JSON처럼 보고서가 어느 갈래인지 알려 주는 경우에, 예외가 타는 갈래만 뺍니다. 모든 마커는 gcovr의 접두사로도 읽습니다: GCOVR_EXCL_LINE, GCOVR_EXCL_START, GCOVR_EXCL_BR_LINE, GCOV_EXCL_STOP 등은 LCOV_EXCL_ 마커와 같은 뜻이므로, gcovr용으로 작성된 소스는 어떤 도구가 보고서를 만들었든 여기서도 똑같이 읽힙니다. 읽지 않는 것: GCOVR_EXCL_FUNCTION — 그 줄에는 함수가 어디서 끝나는지 알려 주는 것이 없습니다.
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
Screenshot pending — add assets/img/branch-markers.png (see SCREENSHOTS.md).이유 밝히기: 사유가 있는 제외
코드를 계산에서 빼는 것은 하나의 주장입니다 — "이것은 테스트할 수 없다", "이것은 개발자용 보조 수단이다" — 그리고 DO-178C, ISO 26262 또는 IEC 61508에서는 인증서가 근거로 삼는 수치를 바꾸는 주장이라면 기록되어 있어야 하고 검토할 수 있어야 합니다. 그래서 제외는 그것이 작성된 자리에서 이유를 밝힐 수 있습니다: LCOV_EXCL_LINE 또는 LCOV_EXCL_START 뒤의 텍스트, 또는 [ExcludeFromCodeCoverage]의 Justification입니다.
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) { /* … */ }
사유는 로드할 때마다 읽고, 로그에 그 수가 기록됩니다. Export Coverage Report…는 그 목록 — 제외 항목과 그 사유 — 을 Markdown 또는 CSV로 씁니다: 파일, 줄, 작성된 방식, 그리고 사유 또는 none given(사유 없음). 측정할 수 있는 것이 하나도 남지 않은 파일도 그 목록에는 들어 있습니다. exclusions.requireReason이 켜져 있으면 이유를 밝히지 않은 제외는 발견 사항이 됩니다: 해당 줄에 Problems의 경고가 생기고, Check Coverage Thresholds가 실패합니다. 그때 Exclude Selection from Coverage는 먼저 사유를 묻고 그것을 마커와 함께, 또는 특성의 Justification으로 씁니다. 입력을 닫거나 비워 두면 아무것도 제외되지 않습니다.
Screenshot pending — add assets/img/justified-exclusions.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-justified-exclusions.png (see SCREENSHOTS.md).12a. 이 커버리지가 지금의 이 파일을 설명하나요?
트레이스 파일에서 읽은 커버리지는 테스트가 실행되던 시점의 소스를 설명하며, 대부분의 형식은 그것이 어느 버전이었는지 말하지 않습니다. 그래서 커버리지 패널의 각 파일은 세 가지 상태 중 하나입니다.
- ✓ 검증됨 — 트레이스 파일이 측정한 각 줄의 내용을 기록하고 있으며, 지금의 파일과 여전히 일치합니다.
- 표시 없음 — 반증되지 않음. 커버리지를 부정하는 것도 확인해 주는 것도 없습니다. 일반적인 상태입니다.
- ⚠ 반증됨 — 파일 자체가 그 커버리지를 부정합니다. 행이 흐리게 표시되고 툴팁이 무엇을 찾았는지 알려 줍니다.
체크 표시를 얻을 수 있는 형식은 둘뿐입니다. 측정한 소스에 대해 무언가를 기록하는 형식이 둘밖에 없기 때문입니다. --checksum으로 작성된 lcov(geninfo에서 기본은 꺼짐이며, 문서화된 목적이 바로 한 파일의 서로 다른 버전에서 나온 커버리지를 합치지 못하게 하는 것입니다)와, 측정한 모든 줄의 텍스트를 담는 GNATcoverage XML입니다. lcov의 그 옵션은 켤 만한 가치가 있습니다.
이 경고는 둘 다 필요 없으며 모든 형식에서 작동합니다: 파일 끝을 넘어 기록된 커버리지, 보고서가 가리키는 위치에 더 이상 없는 이름 있는 함수, 또는 파일에서 빈 줄인 실행된 줄. 타임스탬프만으로는 결코 충분하지 않습니다 — git checkout은 한 바이트도 바꾸지 않고 모든 타임스탬프를 바꿉니다 — 따라서 바뀐 타임스탬프는 기껏해야 다시 살펴볼 이유일 뿐입니다. 검사는 커버리지를 로드할 때 실행되고 파일이 저장되거나 디스크에서 변경될 때마다 다시 실행되므로 표시는 파일을 따라갑니다: 실행 결과와 모순되는 편집은 표시를 붙이고, 측정된 버전을 복원하는 체크아웃은 표시를 지웁니다. 도구 설명은 무엇이 그것을 증명했는지 정확히 알려 줍니다. 모두 끄려면 staleWarning.enabled를 false로 설정하세요.
12b. 측정되지 않음 대 커버되지 않음
실행이 한 번도 언급하지 않는 파일은 측정되지 않은 파일입니다: 어떤 테스트도 그것을 로드하지 않았으므로 어떤 도구도 그것에 대한 줄을 쓰지 않았습니다. 이는 커버되지 않은 — 측정되었지만 실행 횟수가 0인 — 것과 같지 않으며, 확장은 없는 파일을 0%로 점수화한 적이 없습니다. 0.2026.69까지 하지 않았던 것은 없는 파일을 아예 보여 주는 일이었습니다: 테스트가 전혀 없는 모듈은 트리, 합계, 임계값 검사 어디에도 나타나지 않았고, 읽는 사람은 파일 절반이 한 번도 실행된 적 없는 프로젝트에서 “92%”를 보았습니다.
이제 실행이 로드된 상태에서, 실행과 같은 종류인데 실행에 없는 소스 파일에 대해 파일별 상태 표시줄 항목이 not measured라고 말합니다 — “실행과 같은 종류”란 실행이 측정한 파일 확장자 중 하나를 가졌다는 뜻이므로, C 프로젝트의 헤더와 소스는 후보이고 그 Python 스크립트는 아닙니다. 그 이상의 모든 것은 fuciniCoverage.unmeasured.mode를 통한 옵트인입니다:
off(기본값) — 그 밖에 아무것도 바뀌지 않습니다.list— Coverage 보기 맨 아래에 그런 파일을 모두 이름으로 나열하는 Unmeasured 그룹이 생기고 각 행은 그 파일을 엽니다. 로드 결과가 그 수를 세고, 배지는 Explorer에서?로 표시하며,fuciniCoverage.threshold.unmeasuredFiles는 정해 둔 수보다 많을 때 Check Coverage Thresholds를 실패시킬 수 있습니다. 백분율은 움직이지 않습니다.count—list가 하는 모든 것에 더해, 측정되지 않은 각 파일이 자기 코드 줄 수만큼 커버되지 않은 파일로 실행에 반영되므로 상태 표시줄, 임계값, 배지, 기록, 모든 내보내기, Test Coverage 보기가 더 낮은 숫자를 보여 줍니다. 그 파일은 나타나는 어디서나 측정되지 않음으로 그려지고, 거터 막대는 “한 번도 실행되지 않음”이 아니라 “측정되지 않음”이라고 말하며, 불일치 검사는 그것을 건드리지 않습니다 — 그 내용이 모순될 측정이 없기 때문입니다.
{
"fuciniCoverage.unmeasured.mode": "list",
"fuciniCoverage.threshold.unmeasuredFiles": 0
}
헤더 파일은 C에서 알려진 거짓 양성입니다: 실행의 확장자 계열에 속하지만 어떤 추적 파일도 헤더의 이름을 대지 않습니다. 헤더 자체만으로는 아무것도 컴파일되지 않기 때문입니다. 그래서 fuciniCoverage.unmeasured.exclude는 fuciniCoverage.ignore와 같은 glob 문법으로 기본값에서 **/*.h, **/*.hpp, **/*.hh, **/*.inl, **/*.d.ts를 빼 둡니다. 여기서 빌드하지 않는 플랫폼 포트나 생성된 스텁을 추가하면 목록, 개수, 상태 표시줄 상태에서 빠집니다. ignore가 이름을 댄 파일도 결코 측정되지 않음으로 불리지 않습니다 — 빼는 것이 애초의 목적이었으니까요. threshold.unmeasuredFiles의 기본값은 -1로 검사하지 않으며, 0은 실행과 같은 종류의 파일 하나라도 어떤 테스트도 로드하지 않은 순간 실패하고, unmeasured.mode가 list 또는 count인 동안에만 적용됩니다.
13. HTML 보고서
- Generate Full HTML Report — 디렉터리별로 자체 렌더링되는 다중 페이지 보고서입니다. 출력은
htmlReport.outputDir로 이동하며, 설정하지 않은 경우 확장 프로그램의 전역 저장소로 이동합니다. - Open Annotated Source — 단일 파일에 대한 주석 처리된 보기입니다. 내장 렌더러 대신 이러한 페이지를 사용하려면
externalHtmlReport.dir을 미리 빌드된llvm-cov show --format=html디렉터리로 지정하세요. - Export Fucini JSON — 자체 도구를 위한 전체 정규화된 모델입니다.
- Export Coverage Report... — 실행을 CSV(파일별 또는 함수별), Markdown 요약, LCOV 추적 파일, Cobertura XML, SARIF, 또는 README용 자체 완결형 SVG 배지로 내보냅니다. Covered Files 뷰의 Generate Full HTML Report 옆 버튼에서도 열 수 있습니다. CSV를 제외하면 전부 손실이 있습니다 — MC/DC, 리전, 인스턴스화는 LCOV·Cobertura·SARIF에 들어갈 자리가 없습니다 — 그래서 모든 지표를 담는 형식은 Fucini JSON과 CSV로 남습니다.
- Copy Uncovered Lines — PR에 붙여넣을 준비가 된, 모든 격차에 대한 Markdown 요약입니다.
Visual Studio에서는. Tools → Coverage Studio의 Reports 그룹: Show Annotated Source는 활성 문서를 문서 영역의 페이지로 엽니다 — 모든 줄이 제 색으로, 결과가 그 옆에 — 편집기와 양방향으로 함께 스크롤됩니다. Open HTML Report는 한 페이지 보고서를 htmlReport.outputDir(또는 %LOCALAPPDATA%\Fucini\CoverageStudio\html-report)에 쓰고 브라우저를 엽니다. Generate Full HTML Report는 폴더별 색인과 파일별 페이지를 거기에 씁니다. Export Coverage Report…는 같은 여덟 가지 형식을 제공하고 저장 위치를 묻습니다. Generate Coverage Badge는 badge.outputPath가 지정한 곳에 배지를 쓰며, badge.autoUpdate가 있으면 로드할 때마다 씁니다. 주석 페이지에는 Coverage 창과 마찬가지로 WebView2가 필요하지만, 디스크의 보고서에는 필요 없습니다.
Screenshot pending — add assets/img/vs-annotated-source.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/report.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/report-directory-summary.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/report-file-summary.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/report-coverage-gaps.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/report-mcdc-detail.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/export-picker.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/annotated-source.png (see SCREENSHOTS.md).주석이 달린 소스와 일반 소스 비교
Open Annotated Source는 같은 열에서 활성 탭을 해당 파일의 색상으로 구분된 커버리지 웹뷰로 바꿉니다. Open Annotated Source to the Side는 동일한 작업을 분할 화면으로 수행하여 소스와 주석이 달린 보기가 나란히 표시됩니다. 대신 같은 자리에서 전환하려면 — 분할하면 각 패널이 너무 좁아지는 작은 화면에서 유용합니다 — Toggle Annotated Source를 사용하세요. 현재 보고 있는 것을 기억하면서 활성 탭을 둘 사이에서 전환합니다. 주석이 달린 보기 자체에서 Show Source는 해당 파일의 일반 편집기로 바로 돌아갑니다.
실제로 어떤 HTML이 표시되는지는 externalHtmlReport.dir에 따라 달라집니다. 이 값이 설정되어 있고 활성 파일과 일치하는 페이지가 이미 존재하는 경우(llvm-cov는 파일별 페이지를 <repo-이름>/<상대-경로>.html 형태로 배치하므로 보고서 자체의 repo 이름 폴더를 설정할 필요가 전혀 없습니다), 내장 렌더러 대신 툴체인이 생성한 해당 페이지가 표시됩니다 — 로컬 링크/스타일시트는 웹뷰 내에서 작동하도록 다시 작성되며, 내장 보기에서는 재현되지 않는 세부 정보(MC/DC 확장 보기, 영역 강조 표시, 디렉터리 롤업)를 포함합니다. 해당 파일에 일치하는 페이지가 없거나 설정이 비어 있으면 어떻게 될까요? 그러면 내장 렌더러가 대신 사용됩니다. 확장 프로그램은 이 디렉터리를 읽기만 하며, 절대 쓰지 않습니다.
README용 커버리지 배지
Generate Coverage Badge는 활성 실행에 대한 shields 스타일 SVG를 작업 영역에 기록하고 — badge.outputPath, 기본값 coverage-badge.svg, 작업 영역 폴더 기준 상대 경로 또는 절대 경로, 다른 모든 경로 설정과 같은 변수 사용 가능 — 열지 제안합니다. 저장소 안의 평범한 파일이므로 README는 뒤에 어떤 서비스도, shields.io 왕복도 없이 이를 넣을 수 있으며, 망 분리된 저장소에서도 동작합니다:

badge.metric이 배지가 보여 줄 것을 고릅니다: lines(레이블 coverage), branches, mcdc, 또는 상태 표시줄이 보여 주는 것과 같은 종합 점수인 weighted(레이블 score). 고른 지표의 데이터가 없는 실행은 빨간 0% 대신 회색 n/a를 받습니다. 색상은 여러분의 colorScale.* 단계를 따릅니다: lowThreshold 아래는 lowColor, highThreshold까지는 midColor, 그 위는 highColor. badge.autoUpdate가 켜져 있으면 성공한 로드마다 배지가 조용히 다시 기록되고 출력 채널이 각 기록을 [FUCINI_BADGE]로 남깁니다 — 로드할 때마다 작업 영역에 기록하기 때문에 기본값은 꺼짐입니다. SVG를 코드와 함께 커밋하면 저장소 페이지의 그림이 에디터의 숫자를 따라갑니다.
{
"fuciniCoverage.badge.outputPath": "docs/coverage-badge.svg",
"fuciniCoverage.badge.metric": "weighted",
"fuciniCoverage.badge.autoUpdate": true
}
14. 기록 및 추세
history.enabled를 활성화하면 실행을 로컬에 유지할 수 있습니다(history.retention 개수만큼 보관). 그러면 상태 표시줄에 추세 화살표(▲/▼), Coverage 보기에 추세 차트, 그리고 Compare with Last Run과 Compare Two History Runs라는 두 가지 비교 명령을 사용할 수 있으며, 각각 파일별 회귀/개선 차이를 생성합니다.
Visual Studio에서는. 모든 로드가 이전 로드와 비교됩니다: 실행되기 시작했거나 실행이 멈춘 각 줄의 여백에 삼각형(sinceLastRun.enabled), 상태 표시줄의 점수 옆에 추세, 그리고 수치가 바뀐 파일을 위한 Compare with Last Run이 있습니다. history.enabled가 있으면 실행이 %LOCALAPPDATA%\Fucini\CoverageStudio\history 아래에 history.retention 개수만큼 보관되어, 비교가 재시작 뒤에도 유지되고, 추세 차트에 그릴 것이 생기며, Compare Two History Runs…로 그중 아무 둘이나 고를 수 있습니다.
Screenshot pending — add assets/img/history-compare.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/since-last-run.png (see SCREENSHOTS.md).추세 차트
Coverage 보기의 도구 모음 아래에, 저장된 실행이 둘 이상이면 기록의 줄 커버리지가 오래된 것부터 최신 것까지, 최신 서른 개가 선으로 그려집니다: 실행마다 점 하나가 마우스를 올리면 날짜와 수치를 말해 주고, 그 옆에 마지막 수치와 처음 이후의 방향을 나타내는 화살표가 있습니다. 세로 눈금은 실행들 자체의 범위이므로, 92–94%에 있는 팀은 100 아래의 평평한 선이 아니라 움직임을 봅니다. 두 에디션 모두 같은 기록에서 그립니다.
Screenshot pending — add assets/img/trend-chart.png (see SCREENSHOTS.md).
커버리지 세션
테스트 실행 한 번이 변경이 건드린 모든 것을 커버하는 일은 드뭅니다: 단위 테스트는 여기서, 통합 스위트는 저기서, 커버리지를 켠 채 UI를 한 바퀴 도는 것은 또 다른 곳에서. Start Coverage Session은 그 뒤에 오는 로드들을 하나의 합으로 만듭니다 — 각 실행이 이전 실행에 줄 단위로 합집합으로 더해져, 그중 하나라도 실행한 줄은 커버된 것이 되고 횟수는 합산됩니다 — 그래서 거터, 트리, 점수는 그것들이 함께 도달한 것을 보여 줍니다. 화면에 실행이 있으면 그것이 세션의 첫 실행입니다. 트리 위의 막대가 언제부터 몇 번의 실행인지 말해 주고 세션을 끝냅니다. End Coverage Session도 같은 일을 하며, 다음 로드는 다시 홀로 섭니다. Visual Studio에서는 Tools → Coverage Studio 아래의 항목 하나가 세션을 시작하고, 체크된 상태에서는 세션을 끝냅니다.
Screenshot pending — add assets/img/coverage-session.gif (see SCREENSHOTS.md).
CI 기준선: main에 비해 나는 어디에 있는가?
Compare with Last Run은 마지막 변경이 무엇을 했는지 답합니다. 풀 리퀘스트 전의 질문은 main에 비해 어디에 있느냐이고, 그 답은 빌드 서버에 있습니다. baseline.report는 main 브랜치의 빌드가 게시하는 보고서를 가리키고, 모든 로드가 그것과 견주어집니다: 상태 표시줄의 카드에 한 줄짜리 차이가 실리고 — vs CI baseline: 84.20% → 85.10% (+0.90%), 3 file(s) moved — Compare with CI Baseline이 바뀐 파일을 Compare with Last Run과 같은 말로 파일별로 나열합니다. Visual Studio에서는 이 명령이 Tools → Coverage Studio 아래에 있고, 요청할 때 보고서를 가져오거나 읽습니다. .vscode/settings.json에서 지정하는 방법은 세 가지입니다:
- CI가 제공하는 URL. GitLab은 브랜치의 마지막 작업 아티팩트를 안정된 주소에 보관합니다. 토큰은
remote.headers의${env:…}를 통해 설정 파일 밖에 둡니다. 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에Authorization: Bearer ${env:TC_TOKEN}을 더해서. URL은coverageFile.paths의 URL과 똑같이 가져오고 캐시됩니다(ETag,remote.refreshMinutes). - 파이프라인이 공유 폴더에 복사한 파일 —
\\build\drops\app\main\coverage.cobertura.xml같은 절대 경로. - 내려받은 아티팩트를 폴더 아래에 둔 것, 예를 들어
ci/main.lcov.info(그 폴더는.gitignore에 넣으세요) — 폴더 기준 상대 경로.
{
"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}"]
}
리더가 아는 어떤 형식이든 됩니다. CI가 자기 체크아웃 기준으로 상대 경로로 쓴 경로 — 러너에서 Coverlet이 쓰는 src/Billing/Invoice.cs 같은 — 는 차이를 내기 전에 이 폴더 아래에 놓여, 로컬 실행이 해석한 파일과 만납니다. 다른 컴퓨터의 절대 경로는 아무것과도 일치하지 않으니, 파이프라인이 상대 경로를 쓰게 하세요. 가져오거나 읽을 수 없는 기준선은 Output 창의 한 줄일 뿐, 로드가 실패하는 일은 없습니다.
Screenshot pending — add assets/img/ci-baseline.gif (see SCREENSHOTS.md).main에 비해 바뀐 파일.
아티팩트는 zip이며, 그것도 읽습니다. GitHub와 GitLab은 안에 무엇을 넣었든 아티팩트를 아카이브로 건네줍니다. 그 안의 보고서는 # 뒤에 이름을 적어 지정하세요: 멤버는 경로 또는 경로의 끝부분으로 찾습니다. #가 없으면 아카이브의 유일한 파일, 또는 보고서처럼 보이는 유일한 파일이 대상이며, 그런 파일이 여러 개이면 Output 창에 그 이름들이 나옵니다. 내려받은 zip(ci/artifact.zip#lcov.info)에도, 그리고 VS Code에서는 coverageFile.paths의 URL에도 똑같이 적용됩니다. 토큰은 그것이 설정된 대상 서버에만 전달되고 그 밖으로는 가지 않습니다: 아카이브를 보관하는 스토리지로의 리디렉션은 토큰 없이 따라갑니다.
{
"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. AI 에이전트용: 화면의 커버리지
테스트를 작성하는 에이전트는 테스트를 실행하고 백분율을 읽을 수 있습니다. 혼자서 할 수 없는 것은 에디터가 아는 것을 묻는 일입니다: 이 함수의 어느 줄이 한 번도 실행되지 않았는지, 어느 분기의 어느 쪽을 타지 않았는지, 어떤 테스트가 한 줄을 실행하는지, 방금 작성한 diff가 커버되는지. 여섯 가지 도구가 바로 그것을, 에이전트가 행동으로 옮길 수 있는 말로, 로드된 실행을 바탕으로 답합니다 — 화면과 같은 제외, 같은 재매핑, 같은 수치로. 그래서 함수의 빈틈을 커버하라는 지시를 받은 에이전트와 거터를 보는 검토자는 같은 줄에 대해 이야기하게 됩니다.
| 도구 | 답하는 내용 |
|---|---|
coverage_summary | 지표별 실행 합계와, 완전한 커버리지에서 가장 멀리 있는 파일들. 가장 먼저 물어볼 것입니다. |
coverage_gaps | 파일, 함수 또는 줄 범위에서 한 번도 실행되지 않은 것: 커버되지 않은 줄, 타지 않은 분기 갈래, 쌍이 없는 MC/DC 조건, 살아남은 뮤턴트. |
tests_for_line | 어떤 테스트가 한 줄을 실행했는지. 보고서가 그것을 알려 주는 경우, 곧 테스트별 실행에서 답합니다. |
patch_coverage | diff의 커버리지 — 참조 대비 작업 트리, 또는 건네받은 패치 — 와 그 diff에서 한 번도 실행되지 않은 줄. |
coverage_delta | 이전 실행 이후 달라진 것: 합계, 그리고 커버리지가 늘거나 줄어든 파일. |
test_run_command | 이 작업 영역의 테스트를 커버리지를 켠 채 실행하는 명령. 에이전트가 그 명령을 실행하고, 에디터는 보고서를 스스로 다시 로드합니다. |
VS Code 자체의 에이전트는 아무것도 설정하지 않아도 이것들을 도구로 갖추고 있습니다. 나머지 모든 에이전트 — MCP, 즉 Model Context Protocol을 쓰는 클라이언트라면 무엇이든 — 는 mcp.enabled가 켜져 있을 때 에디터가 실행하는 서버를 통해 이 도구들을 사용하며, VS Code에서도 Visual Studio에서도 마찬가지입니다. Copy MCP Server Configuration은 클라이언트의 항목을 VS Code와 Visual Studio가 mcp.json에서 읽는 형태로 클립보드에 넣습니다. 바깥쪽 키의 이름이 mcpServers인 클라이언트에서는 같은 항목을 그 이름 아래에 넣으면 됩니다.
Screenshot pending — add assets/img/mcp-config.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/vs-mcp-config.png (see SCREENSHOTS.md).{
"servers": {
"fucini-coverage": {
"type": "http",
"url": "http://127.0.0.1:39217/mcp",
"headers": { "Authorization": "Bearer …" }
}
}
}
- 사용자가 켜지 않는 한 꺼져 있으며,
127.0.0.1에서만 수신 대기합니다: 이 컴퓨터 밖에서는 아무것도 서버에 연결할 수 없습니다. - 호출에는 사용자의 토큰이 담겨 있어야 합니다. 토큰은 한 번 만들어져 사용자를 위해 보관되며, 토큰이 없으면 응답은 401입니다. 복사한 구성에는 토큰이 들어 있으니 저장소에 넣지 마세요.
- 웹 페이지가 보낸 호출 — 호출의
Origin에 그렇게 적혀 있습니다 — 은 무엇을 담고 있든 거부됩니다. - 로드된 실행을 읽을 뿐 아무것도 쓰지 않습니다. 테스트 실행은 명령을 알려 줄 뿐 시작하지는 않습니다: 에이전트가 자기 터미널에서 그 명령을 실행합니다.
포트는 mcp.port이며, 설정하지 않으면 39217입니다. 그 포트가 이미 사용 중이면 — 두 번째 창, 이 에디션 옆에서 실행 중인 다른 에디션 — 다음 빈 포트를 쓰고, 복사한 구성에는 실제로 동작하는 포트가 들어갑니다. Output 창은 서버가 어디에서 수신 대기하는지([FUCINI_MCP])와 왜 수신 대기하지 못했는지([FUCINI_MCP_001])를 알려 줍니다. 플랜에 포함되지 않은 것 — 테스트 이름, MC/DC 세부 정보 — 은 호버와 마찬가지로 도구가 개수만 세고 내용은 밝히지 않습니다.
15. 명령어 참조
Visual Studio에서는. 모든 명령은 Tools → Coverage Studio 아래에 있으며, 표의 이름에서 Fucini Coverage: 접두어를 뺀 이름입니다. Coverage 창의 도구 모음과 행의 오른쪽 클릭 메뉴에는 거기에 어울리는 명령이 있고, 코드 창의 오른쪽 클릭 메뉴에는 에디터에 작용하는 세 가지, Run This Test with Coverage, Show Tests That Ran This Line, Exclude Selection from Coverage가 있습니다. 키가 있는 것들은 Ctrl+Shift+U 다음의 두 번 누르는 코드입니다: R은 다시 읽기, N과 P는 다음과 이전 미커버 줄, B는 다음 부분 테스트 결정으로 이동, T는 줄을 실행한 테스트 나열, X는 선택 영역 제외 — VS Code의 Alt+N이 아닌데, Visual Studio에서는 Alt와 글자가 메뉴를 열기 때문입니다. Tools → Options → Keyboard에서 바꿀 수 있으며 Coverage Studio: …로 나열됩니다. 이 에디션에 없는 것: Test Coverage 패널은 VS Code API입니다 — 실행은 대신 Coverage 창에 있습니다. Solution Explorer는 배지를 표시할 수 없습니다. 이 에디션에만 있는 것: C++ 시작 프로젝트를 위한 Run Native Project with Coverage.
Visual Studio에서: 각 항목의 위치. Coverage 창은 View → Other Windows → Coverage에 있고, Tools → Coverage Studio의 첫 항목이기도 합니다. 이 메뉴에 이 에디션의 모든 명령이 그룹별로 있습니다: 로드와 다시 로드, 파일 감시, 두 가지 복사와 카드; Run Tests with Coverage, Run Native Project with Coverage, Collect Coverage in Test Explorer…; Next와 Previous Uncovered, 그리고 부분적으로 테스트된 분기; 채색, 실행 횟수와 거터 모드; 파일의 커버리지 소스, 줄을 실행한 테스트, 테스트 하나를 커버리지와 함께, 제외하는 두 가지 방법; Compare with Last Run, Compare Two History Runs…, Compare with CI Baseline, 커버리지 세션과 Check Coverage Thresholds; Reports 그룹 — Show Annotated Source, Open HTML Report, Generate Full HTML Report, Export Coverage Report…, Generate Coverage Badge; 그다음 Getting Started, 준수 임계값, 그리고 Licence…. 창 자체의 도구 모음에는 가장 자주 쓰는 다섯 가지가 있습니다: Load Coverage, Reload, Toggle Coverage Painting, Copy Coverage Summary, 준수 임계값. 그 아래에 관점, 필터와 정렬, 그리고 검색 상자. 그 아래에 추세. 트리의 행에 포인터를 올려 두고 그 행의 ⋯을 누르면 행 메뉴가 열립니다 — 파일 열기, 폴더 열기, 경로 복사(절대 또는 상대, 두 종류의 슬래시 모두), 커버리지에서 제외. 상태 표시줄 오른쪽 끝에는 실행의 점수와 열린 파일의 점수가 마지막 실행 이후의 추세와 함께 있으며, Show Coverage Card와 Show Coverage Card for This File이 그 뒤의 카드를 엽니다. VS Code에서 포인터를 상태 표시줄 항목에 올렸을 때 보이는 것과 같은 카드입니다.







Screenshot pending — add assets/img/statusbar-and-toolbar.gif (see SCREENSHOTS.md).
Screenshot pending — add assets/img/statusbar-menu.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/worst-functions.png (see SCREENSHOTS.md).| 명령 | 기능 |
|---|---|
| Load Coverage | 작업 영역의 커버리지를 찾아 불러옵니다. 기본값은 Alt+Shift+R(macOS에서는 Ctrl+Alt+R). |
| Pick Coverage File | 추적 파일을 선택합니다 — 하나, 여러 개, 또는 매번 하나 더. 선택은 누적되고 병합되며 coverageFile.paths에 기록되어 이후에는 스스로 로드됩니다. |
| Show Loaded Coverage Files | 활성 실행의 추적 파일을 나열합니다. 커버리지 보기에도 나열되며, 각각 언로드 버튼이 있고 옆에 선택 버튼이 있습니다. |
| Toggle Tracefile Watch | 추적 파일의 변경을 감시하고 자동으로 다시 로드합니다. |
| Run Tests with Coverage | 테스트 러너를 인식하고, 터미널 작업에서 커버리지와 함께 실행하고, 기록된 결과를 로드하고, 경로를 설정에 추가할지 제안합니다. |
| Run This Test with Coverage | 캐럿 아래의 테스트 — 메서드, 클래스나 describe 블록, 또는 파일 — 를 그것으로 좁힌 레시피로 실행하고, 다른 실행과 같이 로드합니다. 에디터의 컨텍스트 메뉴에도 있습니다. |
| Show Tests That Ran This Line | 보고서가 어떤 테스트가 무엇을 실행했는지 알려 주는 경우, 캐럿 아래의 줄을 실행한 테스트를 가장 많이 실행한 것부터 나열하고, 고른 테스트를 그것이 작성된 곳에서 엽니다. |
| Run Tests Affected by My Changes… | 작업 트리가 testImpact.baseRef 대비 변경한 줄을 실행한 테스트를 나열하고, 고른 테스트를 열거나, 보고서가 테스트별 실행에서 나온 경우 그 테스트들만 실행합니다. |
| Show Minimal Test Set… | 스위트가 실행하는 모든 줄을 여전히 실행하는 가장 적은 수의 테스트, 그다음에 자기만의 줄을 하나도 더하지 않는 테스트. |
| Run App with Coverage… | 폴더의 .NET 앱을 dotnet-coverage 아래에서 시작하고, 앱이 닫히면 사용자가 거쳐 간 것을 로드합니다. |
| Run Mutation Tests Here | 캐럿이 있는 함수 — 또는 선택 영역, 또는 파일 — 를 Stryker.NET, StrykerJS 또는 PIT으로 변이시키고, 보고서를 화면의 커버리지 옆에 로드합니다. |
| Exclude This File from Coverage / Exclude from Coverage | 열린 파일 — 또는 Coverage 보기의 행에서는 그 파일이나 폴더의 /** — 을 폴더 설정의 fuciniCoverage.ignore에 한 번 넣습니다. |
| Exclude Selection from Coverage | 제외를 코드가 있는 곳에 씁니다: .NET 멤버 위에 [ExcludeFromCodeCoverage], 한 줄에는 LCOV_EXCL_LINE, 여러 줄 둘레에는 LCOV_EXCL_START/STOP을, 그 파일 자체의 주석 기호로. 전구와 에디터의 컨텍스트 메뉴에도 있습니다. |
| Start Coverage Session / End Coverage Session | 세션이 켜져 있는 동안 모든 로드가 이전 로드에 합집합으로 더해집니다. 트리 위의 막대가 실행 수를 세고 세션을 끝냅니다. |
| Next / Previous Uncovered | 커버되지 않은 리전 사이를 이동합니다. 기본값은 Alt+N / Alt+P(macOS에서는 Ctrl+Alt+N / Ctrl+Alt+P). |
| Choose Editor Gutter Mode... | 에디터 거터에 끄기, 커버되지 않은 줄만의 막대, 빨강-호박색-초록 막대, 또는 실행 횟수 히트맵. |
| Cycle Editor Gutter Mode | off, uncovered, coverage, heatmap을 한 단계씩 넘어갑니다 — Alt+G 또는 상태 표시줄의 모드 버튼으로. |
| Choose Coverage Source for This File... | 둘 이상의 로드된 보고서가 열린 파일을 측정할 때, 그 수치를 어느 보고서에서 가져올지 파일, 그 폴더 또는 패턴에 대해 고릅니다 — coverageFile.sources 규칙을 기록합니다. |
| Clear Coverage Source for This File... | 열린 파일에 적용되는 coverageFile.sources 규칙을 제거합니다. |
| Toggle Inline Hit Counts | 각 줄 뒤의 ×N 실행 횟수를 표시하거나 숨깁니다 — hitCounts.inline을 뒤집습니다. |
| Show in Test Coverage View | 활성 실행을 VS Code 자체의 Test Coverage 패널에 게시하고(testCoverage.publish가 꺼져 있어도) 그 패널을 엽니다. |
| Suggest Path Remap Rule | 활성 실행에서 맞지 않는 파일을 작업 영역에 맞출 pathRemap 규칙을 추론하고, 추가할지 제안합니다. |
| What Community Includes | 무료 등급의 모든 한도와 보류된 기능을 각 한도의 사용량과 함께 하나의 목록으로 표시합니다. |
| Open HTML Report | 생성된 정적 보고서를 엽니다. |
| Generate Full HTML Report | 여러 페이지 보고서를 생성합니다. |
| Open Annotated Source / …to the Side | 파일의 주석이 달린 커버리지 보기. |
| Toggle Annotated Source | 소스와 주석이 달린 보기 사이를 전환합니다. 기본값은 Alt+A(macOS에서는 Ctrl+Alt+A). |
| Show Worst-Covered Files / Folders / Functions | 낮은 순으로 정렬된 Quick Pick. |
| Copy Uncovered Lines | 커버되지 않은 모든 범위의 Markdown 요약. |
| Compare Two History Runs / with Last Run | 파일별 회귀 차이 — 기록이 보관한 두 실행, 또는 화면의 실행과 그것이 대체한 실행. |
| Compare with CI Baseline | 로드된 실행을 baseline.report가 가리키는 보고서 — CI의 main 브랜치 보고서, URL 또는 내려받은 아티팩트 — 와 파일별로 비교합니다. |
| Show Indirect Coverage Changes… | 아무도 편집하지 않았는데 커버리지가 달라진 줄을, CI 기준선 또는 이전 실행과 비교하여 파일별로 보여 줍니다. |
| Check Coverage Thresholds | 컴플라이언스 게이트를 평가합니다. |
| Export Fucini JSON | 현재 실행을 Fucini JSON으로 내보냅니다. |
| Export Coverage Report... | 형식(CSV, Markdown, LCOV, Cobertura XML, SARIF 또는 SVG 배지)과 저장 위치를 고릅니다. |
| Generate Coverage Badge | 활성 실행의 SVG 배지를 badge.metric을 표시하도록 badge.outputPath에 기록하고, 열지 제안합니다. |
| Copy MCP Server Configuration | MCP 클라이언트가 화면의 커버리지에 대해 질의하는 데 필요한 것 — 서버 주소와 사용자의 토큰 — 을 클립보드에 넣습니다. 서버가 꺼져 있으면 켤지 제안합니다. |
| Show Status Bar Menu | 빠른 작업 메뉴를 엽니다. |
| Browse for External HTML Report / Full Report Output Dir… | 선택기를 통해 보고서 디렉터리를 설정합니다. |
16. 설정 참조
모든 옵션과 기본값을 포함한 완전하고 분류된 설정 테이블은 기능 및 설정 페이지에 있습니다. 모든 키의 접두사는 fuciniCoverage.입니다.
참고할 점: fuciniCoverage.language는 VS Code의 표시 언어와 무관하게 이 확장 프로그램 자체의 런타임 UI(상태 표시줄, 알림, 툴팁, 웹뷰)를 특정 언어로 고정합니다 — 기본값은 auto이며 지원되는 18개 언어 전체에 대한 번들이 포함되어 있습니다. 이는 명령 팔레트 항목이나 VS Code 자체 표시 언어로 해석되는 설정 UI 레이블은 변경하지 않습니다.
Visual Studio에서는. 같은 fuciniCoverage.* 키를 최대 네 파일에서 읽으며, 나중 것이 우선합니다. 컴퓨터에 VS Code가 있으면 VS Code 자체 사용자 설정 — 읽기만 하고 쓰지 않으므로 색상과 임계값이 그대로 따라옵니다 — 이 에디션의 사용자 설정인 %APPDATA%\Fucini\CoverageStudio\settings.json, 폴더 안이나 솔루션 옆의 .vscode\settings.json — 그래서 VS Code용으로 설정한 저장소는 Visual Studio용으로도 설정된 것입니다 — 그리고 솔루션 루트의 fucini-coverage.json, .NET 저장소에 .vscode 폴더를 두고 싶지 않은 팀을 위한 것입니다 — VS Code 에디션도 이 파일을 읽습니다. Coverage 창 도구 모음의 톱니바퀴는 설정 창을 열며, 이 창은 Write changes to 선택기가 말하는 대로 사용자 파일이나 폴더에 존재하는 파일에 쓰고, 편집하는 파일의 주석을 유지합니다. fuciniCoverage.language도 거기서 같은 방식으로 동작하며, 메뉴는 Visual Studio 자체 언어를 따릅니다.
17. 오류 코드
진단 정보는 Fucini Coverage 출력 채널(View → Output → Fucini Coverage)로 전송되며, 각각 고정된 FUCINI_* 코드를 갖습니다.
Visual Studio에서는. 같은 코드가 출력 창의 Fucini Coverage 창(View → Output)으로 가고, IDE를 닫은 뒤에 오는 질문을 위해 %LOCALAPPDATA%\Fucini\CoverageStudio\coverage-studio.log에 보관됩니다. 자주 나오는 세 가지: 창은 파일을 로드했다고 하는데 아무것도 표시되지 않음 — 여백 모드가 off이니 Show Coverage in Editor를 선택하세요. FUCINI_REMAP_001과 정보 표시줄 — 보고서가 여기에 없는 경로를 가리키며, 창이 pathRemap 규칙을 제안합니다. Coverage 창이 WebView2가 필요하다고 함 — Microsoft Edge WebView2 Runtime을 설치하세요. 편집기의 표시에는 필요 없습니다.
| 코드 | 의미 |
|---|---|
FUCINI_PARSE_001 | 지원되지 않거나 인식할 수 없는 커버리지 형식입니다 — 일치하는 파서가 없습니다. |
FUCINI_PARSE_010 | lcov 파일에 SF 레코드가 없습니다. |
FUCINI_PARSE_020 | llvm-cov JSON이 유효하지 않거나 data[]가 없거나 파일이 없습니다. |
FUCINI_PARSE_030 | Cobertura 루트 <coverage>가 없거나 XML이 유효하지 않습니다. |
FUCINI_PARSE_040 | JaCoCo 루트 <report>가 없거나 소스 파일이 없습니다. |
FUCINI_PARSE_050 | Istanbul/SimpleCov JSON이 유효하지 않거나 파일이 없습니다. |
FUCINI_PARSE_060 | SimpleCov JSON이 유효하지 않거나 최상위 files 배열이 없습니다. |
FUCINI_PARSE_070 | mode: 헤더가 없거나 커버리지 블록이 없는 Go 프로파일입니다. |
FUCINI_PARSE_080 | Clover 루트 <coverage> 또는 <project>가 없거나 그 안에 파일이 없습니다. |
FUCINI_PARSE_090 | OpenCover 루트 <CoverageSession>이 없거나 그 안에 파일이 없습니다. |
FUCINI_PARSE_100 | coverage.py JSON이 올바르지 않거나 최상위 files 객체가 없습니다. |
FUCINI_PARSE_110 | gcov/gcovr JSON이 올바르지 않거나 최상위 files 배열이 없습니다. |
FUCINI_PARSE_120 | <source> 요소가 없는 GNATcoverage XML이거나, xi:include가 전혀 해석되지 않은 index.xml입니다 — 대신 소스별 *.xml 파일을 불러오세요. |
FUCINI_PARSE_130 | 루트 요소 <BullseyeCoverage>가 없거나, 그 안에 <src> 요소가 없습니다. |
FUCINI_PARSE_140 | 루트 요소 <CoverageDSPriv>가 없거나, 행을 해석할 <SourceFileNames> 테이블이 없거나, 행 데이터가 없습니다. |
FUCINI_PARSE_150 | Xcode 커버리지 JSON이 잘못되었거나 최상위 targets 배열이 없습니다. |
FUCINI_PARSE_160 | SonarQube의 루트 요소 <coverage>가 없거나, 그 안에 <file> 요소가 없습니다. |
FUCINI_PARSE_170 | Coveralls JSON이 잘못되었거나 최상위 source_files 배열이 없습니다. |
FUCINI_LOAD | 로드가 진행률 알림에서 취소되었습니다. 이전 실행이 있으면 로드된 채로 남습니다. |
FUCINI_REMOTE_001 | coverageFile.paths URL을 가져올 수 없었습니다. 이유와 함께이며, 마지막으로 내려받은 사본이 대신 로드됩니다. 일반 [FUCINI_REMOTE] 줄은 각 다운로드와 각 변경 없음(304) 확인을 기록합니다. |
FUCINI_REMOTE_002 | coverageFile.paths URL이 30초 안에 완전한 응답을 주지 않았습니다. 연결을 받아들인 뒤 침묵하는 프록시나 VPN이 대부분의 원인이며, 마지막으로 내려받은 사본이 대신 로드됩니다. |
FUCINI_REMOTE_003 | coverageFile.paths URL이 트레이스 파일이 아니라 HTML 페이지로 응답했습니다. 로그인 페이지일 가능성이 큽니다. 이 페이지는 캐시되지 않으며 마지막으로 내려받은 사본이 대신 로드됩니다. remote.headers의 토큰을 확인하세요. |
FUCINI_REMAP_002 | 로드 후 맞지 않은 경로에 대해 pathRemap 규칙이 제안되었습니다. 그중 몇 개를 설명하는지와 함께 — 또는 아무것도 추론할 수 없었거나, 추론된 규칙이 이미 설정에 있는데도 해결하지 못했습니다. |
FUCINI_REMAP_003 | 제안된 규칙이 Apply Suggested Remap에 의해 fuciniCoverage.pathRemap에 추가되었고 커버리지를 다시 로드하는 중입니다. |
FUCINI_GITDIFF_001 | Git 확장을 사용할 수 없어 diff 커버리지를 건너뛰고 전체 실행을 표시합니다. |
FUCINI_GITDIFF_002 | gitDiff.baseRef가 -로 시작합니다. 어떤 git 참조도 그렇게 시작할 수 없습니다(git은 이를 옵션으로 읽습니다). diff 커버리지를 건너뛰고 전체 실행을 표시합니다. |
FUCINI_IGNORE | fuciniCoverage.ignore가 실행에서 뺀 파일이 몇 개인지, 그리고 어느 것인지. |
FUCINI_UNMEASURED_001 | 어떤 테스트도 로드하지 않은, 실행과 같은 종류의 파일, 한 줄에 하나씩. |
FUCINI_UNMEASURED_002 | 5,000개가 넘는 작업 영역 파일이 실행의 확장자 중 하나에 맞았습니다. 처음 5,000개만 Unmeasured 목록의 후보로 고려되었습니다. |
FUCINI_UNMEASURED_003 | count 모드에서 일부 측정되지 않은 파일이 나열은 되지만 세지지 않았습니다: 읽기 상한(로드당 2,000개 파일 또는 50 MB)에 도달했습니다. |
FUCINI_UNMEASURED_004 | 측정되지 않은 파일을 읽을 수 없었습니다. 나열은 되지만 세지는 않습니다. |
FUCINI_TESTCOVERAGE | VS Code의 Test Coverage 보기에 게시된 파일 수. |
FUCINI_BADGE | 배지가 기록되었습니다. 경로, 레이블, 값과 함께. |
FUCINI_BADGE_001 | 배지를 기록할 수 없었습니다. 이유와 함께. |
FUCINI_WORKSPACE | 작업 영역에 폴더가 추가되거나 제거되었습니다. 커버리지를 다시 검색합니다. |
FUCINI_VARIABLES | 경로 설정의 각 ${command:…}가 무엇을 반환했는지, 또는 왜 쓴 그대로 남았는지: 명령이 실패했거나, 쓸 수 있는 값을 반환하지 않았거나, 작업 영역을 신뢰할 수 없습니다. |
FUCINI_WATCH | 감시자가 하는 일: 감시 중인 경로, 나타난 설정된 파일, watch.reloadAfterTasks에 이름이 오른 작업이 끝나(종료 코드와 함께) 다시 로드를 일으킨 것, 또는 files.watcherExclude 아래에 있어 대신 폴링되는 경로. |
18. 개인정보 보호
원격 분석은 window 범위의 telemetry.enabled 설정으로 제어됩니다. 기본값은 꺼짐입니다. 일간 요약과 제거 알림은 VS Code의 전역 telemetry.telemetryLevel이 원격 분석을 허용해야 전송됩니다. 설치 알림과 몇 가지 작은 이벤트는 그와 관계없이 전송되며, 체험판이거나 무료 Community 등급에 있는 설치본의 사용 원장 항목도 마찬가지입니다. Community에서는 Unlock Full Features가 이 원격 분석을 대가로 MC/DC를 포함한 모든 Pro 기능을 30일 동안, 컴퓨터당 한 번 엽니다. 다시 끄면 표준 Community 기능 집합이 적용됩니다. 유료 라이선스는 어느 쪽이든 영향을 받지 않습니다. 무엇이 전송되는지는 개인정보 처리방침을 참조하세요.
직접 조치를 취할 수 있으므로 알아 둘 만한 것이 두 가지 있습니다. 첫째는 여러분의 사용 원장 ID입니다. 체험판과 Community에서는 확장이 이를 Show License / Activation 아래와 What Community Includes의 맨 아래에 표시하며, 그 행을 선택하면 ID가 복사되고 방침이 열립니다. 원장은 여러분의 컴퓨터를 해시로만 알 뿐 그 밖의 무엇으로도 알지 못하므로, 원장이 여러분에 대해 무엇을 보유하고 있는지 묻거나, 삭제를 요구하거나, 이의를 제기하는 유일한 방법이 바로 이 ID입니다. ID를 알려 주시면 해당 행을 찾을 수 있지만, 없으면 찾을 수 없습니다. 둘째는 설치 기록입니다. 어떤 설치가 처음 보고할 때 기록되는 한 줄로, 90일 후 삭제되지 않고 그대로 보관되며, 설치 식별자, 날짜, 그 주소가 가리킨 장소, 각 버전, 운영 체제를 담습니다 — 주소 자체는 담지 않고, 여러분의 코드에 관한 것도 전혀 담지 않습니다. 지난 수년간 설치가 몇 건이었는지 말할 수 있는 것은 바로 이 기록 덕분입니다. 두 가지 모두 개인정보 처리방침에 자세히 설명되어 있으며, 요청하시면 두 가지 모두 삭제됩니다.

19. 평가 및 활성화
Fucini Coverage Studio는 평가용 시험판으로 배포됩니다. 처음 실행할 때 평가에 동의할지 묻고 체험이 시작됩니다. 모든 기능은 해당 설치에서 처음 사용한 시점부터 계산되는 14일 체험 기간 동안 사용할 수 있습니다. 그 이후 무언가가 중단되는 고정된 날짜는 없습니다.
2.2026.2 버전부터 새 설치본의 평가판은 확장이 라이선스 서버에 한 번 연결되는 즉시 시작됩니다. 그때까지는 Community 등급으로 실행되며 그 사실을 알려 줍니다. 개발 컨테이너나 Codespace에서는 평가판이 시작되지 않으며, 그곳에서는 구독 코드, 키 또는 7일 패스로 전체 기능을 사용할 수 있습니다.
체험 기간이 끝나도 잠기는 것은 없습니다. 확장은 무료 Community 등급으로 전환됩니다. 전체 기능을 되찾으려면 활성화하세요. 활성화는 라이선스 서버에 연결해 반환된 키를 자동으로 적용하며, 이메일도 직접 옮겨 적을 키도 필요 없습니다:
Screenshot pending — add assets/img/licence-dialog.png (see SCREENSHOTS.md).Fucini Coverage: Show License / Activation를 실행하고(체험 기간이나 키가 만료되면 상태 표시줄에서도 열 수 있습니다) Request License…(이전에 활성화한 적이 있으면 Request Renewed Key…)을 클릭합니다.- 요청을 확인합니다. 키는 자동으로 발급되며, 이전 요청의 연락처 정보는 다시 묻지 않고 재사용됩니다.
- 끝입니다. 활성화 키가 생성되어
fuciniCoverage.license.key에 자동으로 기록됩니다. 상태 표시줄은 잠시 후 체험에서 활성화된 라이선스로 바뀝니다.
수동 경로를 한 장으로. 라이선스 패널을 열고 Enter Key를 선택한 뒤 메일로 받은 키를 붙여 넣으면 배너가 “Activated”로 바뀝니다.
Screenshot pending — add assets/img/activate-key.gif (see SCREENSHOTS.md).자동 요청이 실패하는 경우(연결 없음, 서버 문제): Fucini Coverage: Copy Activation Request Code를 실행하고 문의 페이지 또는 info@fucini.consulting을 통해 보내신 뒤, 받으신 FCK1.… 키를 Fucini Coverage: Enter Activation Key로 붙여 넣으세요(또는 settings.json에 직접 입력하세요):
{ "fuciniCoverage.license.key": "FCK1.…전체 키를 붙여 넣으세요…" }설정 이름은 fuciniCoverage.license.key(사용자/전역 범위)입니다. 키는 사용자의 기기와 OS 사용자에 종속되며, 만료일이 있을 수 있고, 개별 기능을 활성화 또는 제한하거나 하루 커버리지 로드 횟수를 제한할 수 있습니다. "invalid for this machine"이라는 메시지가 표시되면 이 설치에서 새 키를 요청하세요. 다른 기기용으로 발급된 키는 여기에서 결코 유효하지 않습니다.
Visual Studio에서는. 이 에디션에는 무료 등급이 없습니다: 구독이 없으면 아무것도 읽지 않습니다. 구독이 있으면 플랜이 VS Code에서 정하는 것과 같은 것을 여기서도 정합니다 — 플랜에 포함되지 않은 기능은 보류되고, 그 명령은 실행되는 대신 그렇다고 알립니다. 라이선스 서버가 아직 지원하는 가장 오래된 버전이라는 기준도 여기에 똑같이 적용됩니다: 그보다 낮은 빌드에는 작동을 멈추는 날짜와 함께 하루에 한 번 알림이 표시되고, 그때까지는 계속 동작합니다. 오프라인이라는 이유로 빌드가 멈추는 일은 결코 없습니다.
무료 Community 등급: 주간 사용량
Community는 커버리지 표시를 결코 멈추지 않습니다. 거터, 개요 눈금자, 호버, CodeLens, Coverage 보기, 감시 모드, diff 커버리지, 기록은 전혀 집계되지 않으며, 명령으로 트레이스 파일을 불러오는 것도 하루 25회로만 제한됩니다. 집계되는 것은 출력입니다. HTML 보고서 열기, 내보내기, 두 실행 비교, 임계값 검사, 주석이 달린 소스를 제자리에서 보기가 각각 주 5회입니다.
일주일은 달력이 아니라 사용자를 기준으로 합니다. 첫 사용과 함께 시작되어 7일 뒤에 끝납니다. 사용량을 모두 쓰면 메시지에 해당 작업과 사용량이 다시 채워지는 날이 표시되며, 그 한 번의 메시지 이후에는 상태 표시줄에서만 안내됩니다. Fucini Coverage: What Community Includes를 실행하면 한도에 도달하기 전에도 모든 사용량 항목과 사용한 횟수, 재설정 시점을 확인할 수 있습니다.
Screenshot pending — add assets/img/weekly-allowance.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/community-limit-prompt.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/community-includes-weekly.png (see SCREENSHOTS.md).세 가지 세부 정보는 유료 플랜에 속하지만, 발견 결과 자체는 계속 무료입니다. Community는 살아남은 뮤턴트가 있는 모든 줄을 표시하고 그 개수를 알려 주지만, 각 뮤턴트가 무엇을 바꿨는지는 알려 주지 않습니다. 한 줄을 실행한 테스트가 몇 개인지는 알려 주지만 테스트 이름은 알려 주지 않습니다. 실행의 Max CRAP은 보여 주지만 순위가 매겨진 Riskiest Methods 목록은 보여 주지 않습니다.
Screenshot pending — add assets/img/mutant-hover-community.png (see SCREENSHOTS.md).주간 사용량이 도입된 시점(0.2026.83)에 이미 Community를 사용하고 있었다면 이전 한도가 30일 동안 유지됩니다. 이 내용은 날짜와 함께 한 번만 안내됩니다. 카운터는 사용자의 컴퓨터에 — VS Code 자체 저장소와 ~/.fucini-coverage/에 — 보관되므로 새 VS Code 프로필에서도 같은 주가 이어지며, 어디로도 전송되지 않습니다.
7일 이용권
아직 구독할 준비가 되지 않으셨나요? 7일 이용권은 Pro의 모든 기능을 일주일 동안 제공하며 한 번만 결제하면 됩니다. 자동 갱신도 없고 해지할 것도 없습니다. 가격 페이지에서 구매하면(Community 한도에 도달했을 때 나오는 메시지에도 구매 버튼이 있습니다) 활성화 코드가 이메일로 도착합니다.
Screenshot pending — add assets/img/pricing-week-pass.png (see SCREENSHOTS.md).Fucini Coverage: Enter Subscription Code를 실행합니다 — 이 명령은 Community 에디션과 Pro 모두에 있습니다.- Pro를 선택하고 이메일에 있는
FCB1-…코드를 붙여 넣습니다. - 이것으로 끝입니다. 키는 자동으로 발급되어 적용되며 오프라인에서도 작동합니다. 일주일은 결제 시점부터 계산되므로 구매하면 바로 활성화하세요. 기간이 끝나면 확장 프로그램은 스스로 Community로 돌아가 계속 커버리지를 표시합니다.
Screenshot pending — add assets/img/pass-step-plan.png (see SCREENSHOTS.md).
Screenshot pending — add assets/img/pass-step-code.png (see SCREENSHOTS.md).Visual Studio에서. 같은 코드로 Fucini Coverage Studio for Visual Studio(2022 및 2026)를 활성화합니다. Tools → Coverage Studio → Licence…를 열고 코드를 붙여 넣은 뒤 코드에 해당하는 플랜을 선택하고 Activate를 누릅니다. 그러면 Coverage 창의 트리 위에 Activated가 표시되고, 화살표로 펼치면 키의 유효 기한 날짜와 계정으로 가는 버튼이 그 행에 나타납니다. 한 대의 컴퓨터가 하나의 시트입니다. VS Code나 Visual Studio 중 하나를 활성화하면 같은 컴퓨터의 다른 편집기가 자동으로 따라옵니다. Visual Studio는 VS Code의 키를, VS Code는 Visual Studio의 키를 읽으므로 아무것도 두 번 입력하지 않고 두 번째 시트도 차지하지 않습니다. 키를 유지하는 방식도 둘이 같습니다. Pro Plus, Business, Enterprise는 하루 두 번 체크인하고, Pro 키는 만료 전 주에 갱신됩니다.


새 컴퓨터로 옮기기, 그리고 좌석 관리
키는 한 대의 컴퓨터에 묶여 있으므로 새 컴퓨터에는 새 키가 필요하며, 구독은 명시된 대수까지만 지원합니다. 이전 좌석은 직접 반납하세요. 구독 관리에 로그인해 더 이상 쓰지 않는 좌석을 찾아 Free up을 선택한 뒤, 같은 코드로 새 컴퓨터를 활성화하면 됩니다. Pro를 구매해도 비밀번호는 발송되지 않습니다. 계정은 이미 있고 비밀번호만 아직 없는 상태이므로, 처음에는 구독에 사용한 주소로 비밀번호 설정 또는 재설정을 이용하세요.
Business와 Enterprise에서는 같은 페이지에서 동료를 이메일로 초대합니다. 각자 본인만의 활성화 코드를 받고, 사용하는 즉시 해당 좌석에 그 주소가 표시됩니다. 누군가 떠나면 어느 좌석이 그의 것이었는지 확인해 다음 사람을 위해 반납할 수 있습니다. 초대는 보내는 순간부터 좌석 하나를 차지하며, 사용되지 않으면 14일 뒤 만료됩니다. 철회하면 좌석이 즉시 돌아옵니다.
프리릴리스 빌드 사용해 보기
새 작업은 Marketplace보다 먼저 fucini.software에 도착하며, 그것을 받아 보겠다고 요청하실 수 있습니다. Coverage 뷰를 열고 라이선스 패널을 펼친 뒤 프리릴리스 빌드 사용해 보기…를 누르거나 fuciniCoverage.update.preRelease를 설정하세요. 그때부터 확장은 일반 피드와 함께 이곳의 별도 프리릴리스 피드도 확인하여 둘 중 더 새로운 쪽을 제공합니다.
Screenshot pending — add assets/img/licence-prerelease.png (see SCREENSHOTS.md).프리릴리스는 테스트를 거쳤지만 저희가 가장 확신하기 어려운 빌드이며, 저희가 놓친 것을 찾는 일에 자원하시는 셈입니다. 참여하시면 이 설치가 채널에 있다는 사실이 저희에게 전달되어, 몇 분이 테스트 중인지 파악하고 무엇이 바뀌었는지 알려 드릴 수 있습니다. 떠나시면 다음 안정 릴리스에서 평소 경로로 돌아갑니다. 프리릴리스가 늘 있는 것은 아니며, 없을 때 참여해도 손해는 없습니다. 확장은 비어 있는 피드를 발견하면 그에 대해 아무 말도 하지 않고, 하나가 게시될 때까지 계속 안정 릴리스를 제공합니다.
Screenshot pending — add assets/img/licence-prerelease-joined.png (see SCREENSHOTS.md).20. 문의 및 라이선스
질문, 버그 신고 또는 대체 라이선스 조건은 문의 페이지를 참조하거나 info@fucini.consulting으로 이메일을 보내주세요. 릴리스 노트 출처 표시 조건이 포함된 MIT 라이선스에 따라 라이선스가 부여됩니다. Notice도 참조하세요.
21. 명령줄에서
리더는 편집기 없이도 동작합니다: npm install -g fucini-coverage, 무료, Windows, Linux, WSL, macOS에서. fucini-coverage check coverage/lcov.info --lines 80은 파이프라인을 실패시키는 게이트이고, summary, export, report, badge, compare는 편집기의 같은 이름 명령이 하는 일을 하며, mcp는 위 절의 여섯 가지 도구를 서버의 에이전트에게 제공합니다. Visual Studio 에디션이 읽는 설정 파일 fucini-coverage.json을 읽으므로 임계값은 한 번만 정하면 됩니다. fucini-coverage help <command>가 각 명령을 설명하고, 전체 페이지는 npm의 fucini-coverage입니다.
Screenshot pending — add assets/img/cli-demo.gif (see SCREENSHOTS.md).