Free tool
Coverage files, as a report people can read.
Drop the lcov.info, coverage.xml or clover.xml your test run wrote. Get line, branch and function coverage, the least-covered files and their uncovered lines — then copy a Markdown summary for the pull request or send the report as a link.
63.1% lines · 64.2% branches · 66.6% functions · 14 uncovered lines
Publishes this report on Comma: one URL that opens on any phone, comments pinned to the file that needs tests, and the next run kept as a revision you can diff to see whether coverage moved. Free, no card.
How the file is read
- LCOV: each
SF:starts a file,DA:line,hitsare lines,BRDA:line,block,branch,takenare branches (-means never reached) andFN/FNDAare functions. TheLF/LHsummary lines are ignored and recounted. - Cobertura: every
<class filename="…">is grouped by file;condition-coverage="50% (1/2)"gives the branches, and a<method>counts as covered when any of its lines was hit. - Clover:
<line type="stmt">andtype="cond"are lines,truecount/falsecountare the two sides of each branch, andtype="method"are functions. - Paths lose the directory every file shares, so
/home/runner/work/shop/shop/src/cart/cart.tsreadscart/cart.tsunder acartdirectory row.
Getting the file
| Tool | Writes a coverage file with |
|---|---|
| Jest | jest --coverage → coverage/lcov.info, coverage/clover.xml |
| Vitest | vitest run --coverage --coverage.reporter=lcov |
| c8 / nyc | c8 --reporter=lcov npm test → coverage/lcov.info |
| pytest-cov | pytest --cov --cov-report=xml → coverage.xml (Cobertura) |
| coverage.py | coverage lcov (or coverage xml) |
| gcov / C++ | lcov --capture -d . -o coverage.info (or gcovr --xml) |
| Rust | cargo llvm-cov --lcov --output-path lcov.info |
| Go | gcov2lcov -infile=coverage.out -outfile=lcov.info |
| Flutter | flutter test --coverage → coverage/lcov.info |
| .NET | dotnet test --collect:"XPlat Code Coverage" → coverage.cobertura.xml |
| PHPUnit | phpunit --coverage-clover clover.xml |
When the coverage number should be a link
A coverage percentage in a CI log starts arguments; the list of files behind it ends them. Published to Comma, the report opens for anyone without a seat in your CI or a coverage SaaS, reviewers comment on the file that needs tests, and an agent can publish it from the pipeline on every run. For the full line-by-line source view, publish the genhtml or lcov-report folder instead — see how to share an lcov report. More on the format in what LCOV is and what code coverage measures.
Questions
- How do I view an lcov.info file?
- Drop it onto this page or paste its contents. It becomes a coverage report in your browser: line, branch and function percentages, a roll-up per directory, and every file sorted least-covered first with its uncovered line numbers. Nothing is uploaded, and there is no genhtml or Perl to install.
- Which coverage formats does it read?
- LCOV tracefiles (lcov.info, coverage.info), Cobertura XML (coverage.xml, cobertura.xml, Cobertura.xml) and Clover XML (clover.xml). Between them that covers Jest, Vitest, c8 and nyc/Istanbul, coverage.py and pytest-cov, gcov via lcov or gcovr, cargo-llvm-cov and grcov, Flutter, .NET coverlet, PHPUnit and JaCoCo through its Cobertura converter.
- How are the percentages calculated?
- From the line-level records, not from the summary numbers in the file. Lines: DA records (LCOV) or <line> elements (Cobertura, Clover) with a hit count above zero. Branches: BRDA records, Cobertura's condition-coverage, or Clover's truecount/falsecount. Functions: FN/FNDA records, Cobertura <method> elements with any hit line, or Clover method lines. Percentages are rounded down, so 99.96% shows as 99.9%, not 100%.
- Why does my number differ from Codecov or Istanbul's summary?
- Tools disagree on what counts. Istanbul reports statements, which this viewer doesn't see in LCOV. Codecov counts a line with a partly taken branch as a partial, not a hit. Some tools merge overlapping runs differently. Here a line is covered when any record in the file hit it, and a file that appears twice — several TN: blocks or split classes — is merged, so a line hit in either run counts.
- Can I merge coverage from several test runs?
- For LCOV, paste the tracefiles one after another; repeated SF: records for the same file are summed, the way lcov --add-tracefile does. Cobertura and Clover files are read one at a time.
- Can I post the summary on a pull request?
- Yes. “Copy Markdown” gives a GitHub-flavored table — line, branch and function coverage plus the fifteen least-covered files with their uncovered lines — that pastes into a PR comment or appends to $GITHUB_STEP_SUMMARY.
- Is my coverage data uploaded?
- No. The file is parsed and the report is built in your browser. It only leaves your machine if you click “Get a shareable link” and publish the report to Comma.
Related: JUnit XML viewer · SARIF viewer · share a coverage report · coverage report links broken · all free tools