Originally reported by Matthew Crenshaw (Bitbucket: sgtsquiggs, GitHub: sgtsquiggs)
So that we can use coverage.py with IDE plugins that read the standard lcov.info format and highlight covered/uncovered lines. Would be super great!
I am not working on this at the moment, and probably will not be implementing this any time soon. There's no reason this has to be built-in to coverage.py. You can get data from coverage in XML format, or using the data API, and create a file like this with separate code.
Original comment by Bojan Kogoj (Bitbucket: bojankogoj, GitHub: bojankogoj)
Any progress? I'd like to use vs code coverage plugin but it doesn't support current format
I'm a bit nervous about the language semantics assumed by this file format (list of functions found?), but that seems to be par for the course for any of these formats.
Original comment by Matthew Crenshaw (Bitbucket: sgtsquiggs, GitHub: sgtsquiggs)
Following is a quick description of the tracefile format as used by
genhtml, geninfo and lcov.
A tracefile is made up of several human-readable lines of text, divided
into sections. If available, a tracefile begins with the testname which
is stored in the following format:
TN:<test name>
For each source file referenced in the .da file, there is a section
containing filename and coverage data:
SF:<absolute path to the source file>
Following is a list of line numbers for each function name found in the
source file:
FN:<line number of function start>,<function name>
Next, there is a list of execution counts for each instrumented funcā
tion:
FNDA:<execution count>,<function name>
This list is followed by two lines containing the number of functions
found and hit:
FNF:<number of functions found>
FNH:<number of function hit>
Branch coverage information is stored which one line per branch:
BRDA:<line number>,<block number>,<branch number>,<taken>
Block number and branch number are gcc internal IDs for the branch.
Taken is either '-' if the basic block containing the branch was never
executed or a number indicating how often that branch was taken.
Branch coverage summaries are stored in two lines:
BRF:<number of branches found>
BRH:<number of branches hit>
Then there is a list of execution counts for each instrumented line
(i.e. a line which resulted in executable code):
DA:<line number>,<execution count>[,<checksum>]
Note that there may be an optional checksum present for each instruā
mented line. The current geninfo implementation uses an MD5 hash as
checksumming algorithm.
At the end of a section, there is a summary about how many lines were
found and how many were actually instrumented:
LH:<number of lines with a non-zero execution count>
LF:<number of instrumented lines>
Each sections ends with:
end_of_record
In addition to the main source code file there are sections for all
#included files which also contain executable code.
Note that the absolute path of a source file is generated by interpretā
ing the contents of the respective .bb file (see gcov (1) for more
information on this file type). Relative filenames are prefixed with
the directory in which the .bb file is found.
Note also that symbolic links to the .bb file will be resolved so that
the actual file path is used instead of the path to a link. This
approach is necessary for the mechanism to work with the /proc/gcov
files.
Interesting idea. Do you have a link to information about the file format?
FWIW we've been using a patch for eons at work that has coverage generate LCOV files. Let me see about extricating that and making a PR.
Example non-great code posted as a PR to help kick things off. :)
We've gotten repeated requests to support python coverage in Bazel (https://bazel.build/) and integrating it in a multi-language situation (e.g., coverage for Python + C++) requires being able to generate lcov format.
I really haven't spend much time untangling this, are there any links to the specifics of the LCOV format or the specifics of what subset of that Bazel expects from LCOV files? (see also the comment thread on (https://github.com/nedbat/coveragepy/pull/863).
Bazel supports multi-language coverage, e.g., getting coverage results from Java, Python, and C++ from a single test run. However, in order to generate a combined report, all of these need to be converted into a single unified format. We've looked at different formats, and it seems like every coverage tool / implementation comes with its own format, and none is particularly prevalent. Our main restriction is that it shouldn't be too verbose (so XML might be a problem). Whatever format we standardize on in Bazel, we need to convert from all other formats to that one.
Right now, we're using lcov as our "standard" format, which is fairly simple, reasonably compact, and it's the same format Google uses internally (full disclosure: I work for Google). For large code bases, we're seeing multi-GB lcov outputs, so less compact could be problematic.
Ideally, whatever format we use also supports advanced features like branch coverage or edge coverage, but it's more important to settle on something than to have the latest and greatest features.
Each tool has to decide what lines to mark as covered. I would strongly recommend that it at least correctly annotate on a per-file level; there are potential uses for automatically selecting affected tests based on coverage information from a previous test run to reduce CI resource usage.
One more thing: Python is an exception, but we otherwise don't allow access to source code from the test run. Bazel sandboxes execution, and - by design - does not support general source access. We collect lcov from the test runs, and then generate an HTML report as a post-process during which we allow source access. As a corollary, the coverage tool should not put absolute paths into the output, because the sandbox is in a different file system location. We can post-process the data if necessary, but it's not ideal. Ideal is to use relative paths to the current working directory.
Hope to see this being implemented soon!
If anyone needs a converting tool in the meantime, I created a simple converter here: https://github.com/chaychoong/coveragepy-lcov
Most helpful comment
Hope to see this being implemented soon!
If anyone needs a converting tool in the meantime, I created a simple converter here: https://github.com/chaychoong/coveragepy-lcov