SupercovCompare
← All comparisons

Code coverage · Comparison

lcov vs Cobertura: coverage report formats

lcov is text and names each branch; Cobertura is XML with a branch count per line. The same run in both formats, and which tools read which.

Which format should you produce?

Produce the one the tool reading it accepts; most coverage tools can write both. lcov is plain text with one record per line, and it names each branch. Cobertura is XML, and gives a branch count per line. When both are accepted, lcov keeps more detail and is easier to merge.

The same run in both formats

One Jest run on one file, written with both reporters. From the lcov file:

SF:src/access.js
FN:8,label
FNDA:1,label
DA:9,1
LF:5
LH:5
BRDA:9,3,0,1
BRDA:9,3,1,0
BRF:7
BRH:6
end_of_record

From the Cobertura file:

<class name="access.js" filename="src/access.js" line-rate="1" branch-rate="0.8571">
  <lines>
    <line number="9" hits="1" branch="true" condition-coverage="50% (1/2)"/>
  </lines>
</class>

Both say line 9 ran once and half its branches were taken. Only lcov says which half: BRDA:9,3,1,0 is the second branch, taken 0 times.

How they differ

lcovCobertura
SyntaxText, one record per lineXML
LinesDA:line,hits<line number hits>
BranchesBRDA, one record per branchcondition-coverage, a count per line
FunctionsFN and FNDA<method>
TotalsLF, LH, BRF, BRH per fileline-rate and branch-rate at every level
File pathsSF: per filefilename, relative to a <source>
MC/DCMCDC, with MCF and MCH per file, from lcov 2.0None
Merginglcov --add-tracefileNeeds a tool that understands the XML

Neither format records which test ran a line. Only lcov 2 has a record for MC/DC, and only readers that ask for it (--mcdc-coverage) read it.

Who reads which

Check the tool that consumes the report:

  • Codecov accepts both, and JaCoCo XML. So does Coveralls; see Codecov vs Coveralls.
  • GitLab’s coverage view in merge requests reads Cobertura and JaCoCo XML, not lcov.
  • SonarQube reads lcov for JavaScript and TypeScript, and Cobertura-style XML from coverage.py for Python.

Paths are the usual failure

A report that uploads but shows no coverage usually has paths the reader cannot match to the repository. In the Jest run above, <source> held the absolute path of the project on the machine that ran the tests. Generate reports from the repository root, and prefer repository-relative paths.

Cobertura is also the name of a Java coverage tool, last released in 2015. The format outlived it. See JaCoCo vs Cobertura.

Export both from Supercov

npx supercov runs report --format lcov --output coverage/lcov.info
npx supercov runs report --format cobertura --output coverage/cobertura.xml

Supercov writes both from one run, with repository-relative paths and a stable order. A line’s hit count is 1 or 0, because Supercov records that a line ran, not how often. Per-test coverage and MC/DC stay in Supercov’s own report, since neither format can hold them.

Example evidence: fixture source, commands and recorded results (JSON). Measured October 12, 2026 with Supercov 4.3.0. These small examples are not a performance benchmark or a general conformance test.