# 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. Web page: https://supercov.com/compare/lcov-vs-cobertura · Published 2026-10-12 All Supercov pages for agents: https://supercov.com/llms.txt · Full text: https://supercov.com/llms-full.txt ## 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: ```text 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: ```xml ``` 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 | | lcov | Cobertura | | --- | --- | --- | | Syntax | Text, one record per line | XML | | Lines | `DA:line,hits` | `` | | Branches | `BRDA`, one record per branch | `condition-coverage`, a count per line | | Functions | `FN` and `FNDA` | `` | | Totals | `LF`, `LH`, `BRF`, `BRH` per file | `line-rate` and `branch-rate` at every level | | File paths | `SF:` per file | `filename`, relative to a `` | | MC/DC | `MCDC`, with `MCF` and `MCH` per file, from lcov 2.0 | None | | Merging | `lcov --add-tracefile` | Needs 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](https://docs.codecov.com/docs/supported-report-formats), and JaCoCo XML. So does Coveralls; see [Codecov vs Coveralls](https://supercov.com/compare/codecov-vs-coveralls.md). - GitLab's [coverage view](https://docs.gitlab.com/ci/testing/code_coverage/) 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, `` 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](https://supercov.com/compare/jacoco-vs-cobertura.md). ## Export both from Supercov ```sh 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)](https://supercov.com/downloads/tool-comparisons-2026-10-12.json). Measured October 12, 2026 with Supercov 4.3.0. These small examples are not a performance benchmark or a general conformance test.