validation
LCOV Coverage Viewer
Parse lcov.info files from Jest, Istanbul, Vitest, gcov, and coverage.py — line, function, and branch coverage per file. Runs in your browser.
All tools
What is LCOV Coverage Viewer?
LCOV Coverage Viewer is a free online tool that parses LCOV .info files and displays a human-readable coverage report. LCOV is the standard output format for code coverage tools across many languages and test runners — including Jest (JavaScript), Istanbul/nyc (JavaScript), Vitest (TypeScript), gcov (C/C++), and coverage.py (Python). An LCOV .info file encodes line-by-line, function-by-function, and branch-by-branch execution data for every source file in your project. This tool reads that data and renders it as a sortable, filterable table showing which files are well-covered and which need more tests. Processing is entirely client-side — your source code and coverage data never leave your browser.
How to view your LCOV report
- Generate your LCOV report: Run your test suite with coverage enabled. For Jest: add --coverage and set coverageReporters: ['lcov'] in jest.config. For Vitest: set coverage.reporter: ['lcov']. For Python: run coverage run then coverage lcov. The output is a file called lcov.info or coverage/lcov.info.
- Upload or paste the .info file: Drag your lcov.info file onto the upload area, or paste its raw text content into the input field. The viewer accepts any standard LCOV format regardless of which tool generated it.
- Inspect coverage by file: The summary cards show overall line, function, and branch coverage percentages. The file table lists every source file with its individual coverage and colored indicators — green (≥80%), yellow (60–80%), and red (<60%). Sort any column or search by filename to find the biggest coverage gaps.
Frequently asked questions
- Is my code or coverage data sent to a server?
- No. The LCOV parser runs entirely in your browser in JavaScript. Your .info file is never uploaded — it is read and parsed locally. This makes the tool safe for proprietary codebases.
- Which test runners and coverage tools produce LCOV output?
- Jest (coverageReporters: ['lcov']), Vitest (coverage.reporter: ['lcov']), Istanbul/nyc (--reporter=lcov), gcov (with lcov CLI), coverage.py (coverage lcov), Cargo/tarpaulin (--out Lcov), and most CI coverage platforms including Codecov and Coveralls.
- What is the difference between line, function, and branch coverage?
- Line coverage counts whether each executable line was reached by at least one test. Function coverage counts whether each function was called. Branch coverage counts both sides of every conditional (if/else, ternary, switch) — a line with a conditional shows as covered even if only one branch was taken.
- What is a good coverage target for a production codebase?
- 80% line coverage is a widely accepted baseline for production code. Below 60% indicates critical gaps. Above 90% has diminishing returns — testing every trivial getter often produces less value than writing more scenario-based integration tests. Branch coverage below 70% is worth investigating: uncovered else branches often represent unhandled error states that manifest as production bugs.
- How do I fail a CI build when coverage drops below a threshold?
- Most test runners support coverage thresholds natively. In Jest: add coverageThreshold to jest.config with global.lines, global.functions, global.branches. In Vitest: coverage.thresholds.lines. You can also POST the lcov.info to the /api/lcov-viewer endpoint in a CI script and assert on the summary.linesCoverage field in the JSON response.
- Can I view LCOV reports generated by gcov (C/C++)?
- Yes. gcov generates coverage data for C and C++ programs. Use the lcov command-line tool to aggregate gcov output into a .info file: lcov --capture --directory . --output-file coverage.info. Then upload that file to this viewer. The format is identical to JavaScript LCOV output.
- Why do some files show 100% coverage but still have bugs?
- Coverage measures whether code was executed, not whether it was tested correctly. A test that calls a function without asserting on the output achieves 100% line coverage while verifying nothing. Branch and mutation coverage are stricter — mutation testing (e.g., Stryker for JavaScript) deliberately introduces code changes and checks whether tests detect them, giving a more meaningful quality signal.