Gcovr User Guide¶
Gcovr provides a utility for managing the use of the GNU gcov utility and generating summarized code coverage results. This command is inspired by the Python coverage.py package, which provides a similar utility for Python.
The gcovr
command can produce different kinds of coverage reports:
- default: compact human-readable summaries
--html
: HTML summaries--html-details
: HTML report with annotated source files--xml
: machine readable XML reports in Cobertura format--sonarqube
: machine readable XML reports in Sonarqube format--json
: JSON report with source files structure and coverage
Thus, gcovr can be viewed as a command-line alternative to the lcov utility, which runs gcov and generates an HTML-formatted report. The development of gcovr was motivated by the need for text summaries and XML reports.
The Gcovr Home Page is http://gcovr.com. Automated test results are available through Travis CI and Appveyor. Gcovr is available under the BSD license.
This documentation describes Gcovr 4.2.
This User Guide provides the following sections:
Related documents:
- Installation
- Contributing (includes instructions for bug reports)
- Gcovr Cookbook
- Frequently Asked Questions
- Change Log
- License
Getting Started¶
The gcovr
command provides a summary of the lines that have been
executed in a program. Code coverage statistics help you discover
untested parts of a program, which is particularly important when
assessing code quality. Well-tested code is a characteristic of
high quality code, and software developers often assess code coverage
statistics when deciding if software is ready for a release.
The gcovr
command can be used to analyze programs compiled with
GCC. The following sections illustrate the application of gcovr
to test coverage of the following program:
1 // example.cpp 2 3 int foo(int param) 4 { 5 if (param) 6 { 7 return 1; 8 } 9 else 10 { 11 return 0; 12 } 13 } 14 15 int main(int argc, char* argv[]) 16 { 17 foo(0); 18 19 return 0; 20 }
This code executes several subroutines in this program, but some lines in the program are not executed.
Tabular Output of Code Coverage¶
We compile example1.cpp
with the GCC compiler as follows:
g++ -fprofile-arcs -ftest-coverage -fPIC -O0 example.cpp -o program
Note that we compile this program without optimization, because
optimization may combine lines of code and otherwise change the
flow of execution in the program. Additionally, we compile with
the -fprofile-arcs -ftest-coverage -fPIC
compiler options, which
add logic to generate output files that can be processed by the
gcov
command.
The compiler generates the program
executable. When we execute this command:
./program
the files example1.gcno
and example1.gcda
are generated. These
files are processed with by gcov
to generate code coverage
statistics. The gcovr
command calls gcov
and summarizes these
code coverage statistics in various formats. For example:
gcovr -r .
generates a text summary of the lines executed:
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
example.cpp 7 6 85% 7
------------------------------------------------------------------------------
TOTAL 7 6 85%
------------------------------------------------------------------------------
Each line of this output includes a summary for a given source file, including the number of lines instrumented, the number of lines executed, the percentage of lines executed, and a summary of the line numbers that were not executed. To improve clarity, gcovr uses an aggressive approach to grouping uncovered lines and will combine uncovered lines separated by “non-code” lines (blank, freestanding braces, and single-line comments) into a single region. As a result, the number of lines listed in the “Missing” list may be greater than the difference of the “Lines” and “Exec” columns.
The -r
option specifies the root directory for the files that are
being analyzed. This allows gcovr
to generate a simpler report
(without absolute path names), and it allows system header files
to be excluded from the analysis.
Note that gcov
accumulates statistics by line. Consequently, it
works best with a programming style that places only one statement
on each line.
Tabular Output of Branch Coverage¶
The gcovr
command can also summarize branch coverage using the --branches
option:
gcovr -r . --branches
This generates a tabular output that summarizes the number of branches, the number of branches taken and the branches that were not completely covered:
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Branches Taken Cover Missing
------------------------------------------------------------------------------
example.cpp 2 1 50% 5
------------------------------------------------------------------------------
TOTAL 2 1 50%
------------------------------------------------------------------------------
Cobertura XML Output¶
The default output format for gcovr
is to generate a tabular
summary in plain text. The gcovr
command can also generate an
XML output using the --xml
and --xml-pretty
options:
gcovr -r . --xml-pretty
This generates an XML summary of the lines executed:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE coverage SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'>
<coverage line-rate="0.8571428571428571" branch-rate="0.5" lines-covered="6" lines-valid="7" branches-covered="1" branches-valid="2" complexity="0.0" timestamp="1573053861" version="gcovr 4.2">
<sources>
<source>.</source>
</sources>
<packages>
<package name="" line-rate="0.8571428571428571" branch-rate="0.5" complexity="0.0">
<classes>
<class name="example_cpp" filename="example.cpp" line-rate="0.8571428571428571" branch-rate="0.5" complexity="0.0">
<methods/>
<lines>
<line number="3" hits="1" branch="false"/>
<line number="5" hits="1" branch="true" condition-coverage="50% (1/2)">
<conditions>
<condition number="0" type="jump" coverage="50%"/>
</conditions>
</line>
<line number="7" hits="0" branch="false"/>
<line number="11" hits="1" branch="false"/>
<line number="15" hits="1" branch="false"/>
<line number="17" hits="1" branch="false"/>
<line number="19" hits="1" branch="false"/>
</lines>
</class>
</classes>
</package>
</packages>
</coverage>
This XML format is in the Cobertura XML format suitable for import and display within the Jenkins and Hudson continuous integration servers using the Cobertura Plugin. Gcovr also supports a Sonarqube XML Output
The --xml
option generates a denser XML output, and the --xml-pretty
option generates an indented XML output that is easier to read.
Note that the XML output contains more information than the tabular
summary. The tabular summary shows the percentage of covered lines,
while the XML output includes branch statistics and the number of
times that each line was covered. Consequently, XML output can be
used to support performance optimization in the same manner that
gcov
does.
HTML Output¶
The gcovr
command can also generate a simple
HTML output using the --html
option:
gcovr -r . --html -o example-html.html
This generates a HTML summary of the lines executed. In this
example, the file example1.html
is generated, which has the
following output:
The default behavior of the --html
option is to generate HTML for
a single webpage that summarizes the coverage for all files. The
HTML is printed to standard output, but the -o
(--output
) option
is used to specify a file that stores the HTML output.
The --html-details
option is used to create a separate web page
for each file. Each of these web pages includes the contents of
file with annotations that summarize code coverage. Consider the following
command:
gcovr -r . --html --html-details -o example-html-details.html
This generates the following HTML page for the file example1.cpp
:
Note that the --html-details
option can only be used with the
-o
(--output
) option. For example, if the --output
option
specifies the output file coverage.html
, then the web pages
generated for each file will have names of the form
coverage.<filename>.html
.
Sonarqube XML Output¶
If you are using Sonarqube, you can get a coverage report
in a suitable XML format via the gcovr --sonarqube
option:
gcovr --sonarqube coverage.xml
The Sonarqube XML format is documented at https://docs.sonarqube.org/latest/analysis/generic-test/.
JSON Output¶
The gcovr
command can also generate a JSON output using
the --json
and --json-pretty
options:
gcovr --json coverage.json
The --json-pretty
option generates an indented JSON output
that is easier to read.
Structure of file is based on gcov JSON intermediate format with additional key names specific to gcovr.
Structure of the JSON is following:
{
"gcovr/format_version": gcovr_json_version
"files": [file]
}
gcovr_json_version: version of gcovr JSON format
Each file has the following form:
{
"file": file
"lines": [line]
}
file: path to source code file, relative to gcovr root directory.
Each line has the following form:
{
"branches": [branch]
"count": count
"line_number": line_number
"gcovr/noncode": gcovr_noncode
}
gcovr_noncode: if True coverage info on this line should be ignored
Each branch has the following form:
{
"count": count
"fallthrough": fallthrough
"throw": throw
}
file, line and branch have the structure defined in gcov intermediate format. This format is documented at https://gcc.gnu.org/onlinedocs/gcc/Invoking-Gcov.html#Invoking-Gcov.
Multiple JSON files can be merged into the coverage data with sum of lines and branches execution
Multiple Output Formats¶
You can write multiple report formats with one gcovr invocation
by passing the output filename directly to the report format flag.
If no filename is specified for the format,
the value from -o/--output
is used by default,
which itself defaults to stdout.
The following report format flags can take an optional output file name:
Note that --html-details overrides any value of --html if it is present.
Combining Tracefiles¶
You can merge coverage data from multiple runs with gcovr --add-tracefile
.
For each run, generate JSON output:
... # compile and run first test case
gcovr ... --json run-1.json
... # compile and run second test case
gcovr ... --json run-2.json
Next, merge the json files and generate the desired report:
gcovr --add-tracefile run-1.json --add-tracefile run-2.json --html-details coverage.html
The gcovr Command¶
The gcovr
command recursively searches a directory tree to find
gcov
coverage files, and generates a text summary of the code
coverage. The --help
option generates the following summary of
the gcovr
command line options:
gcovr¶
A utility to run gcov and summarize the coverage in simple reports.
usage: gcovr [options] [search_paths...]
See <http://gcovr.com/> for the full manual.
Options¶
-
search_paths
¶
Search these directories for coverage files. Defaults to --root and --object-directory. Config key: search-path.
-
-h
,
--help
¶
Show this help message, then exit.
-
--version
¶
Print the version number, then exit.
-
-v
,
--verbose
¶
Print progress messages. Please include this output in bug reports.
-
-r
<root>
,
--root
<root>
¶ The root directory of your source files. Defaults to ‘.’, the current directory. File names are reported relative to this root. The --root is the default --filter.
-
-a
<add_tracefile>
,
--add-tracefile
<add_tracefile>
¶ Combine the coverage data from JSON files. Coverage files contains source files structure relative to root directory. Those structures are combined in the output relative to the current root directory. Option can be specified multiple times. When option is used gcov is not run to collect the new coverage data.
-
--config
<config>
¶ Load that configuration file. Defaults to gcovr.cfg in the --root directory.
-
--fail-under-line
<min>
¶ Exit with a status of 2 if the total line coverage is less than MIN. Can be ORed with exit status of ‘--fail-under-branch’ option.
-
--fail-under-branch
<min>
¶ Exit with a status of 4 if the total branch coverage is less than MIN. Can be ORed with exit status of ‘--fail-under-line’ option.
-
--source-encoding
<source_encoding>
¶ Select the source file encoding. Defaults to the system default encoding (UTF-8).
Output Options¶
Gcovr prints a text report by default, but can switch to XML or HTML.
-
-o
<output>
,
--output
<output>
¶ Print output to this filename. Defaults to stdout. Individual output formats can override this.
-
-b
,
--branches
¶
Report the branch coverage instead of the line coverage. For text report only. Config key: txt-branch.
-
-u
,
--sort-uncovered
¶
Sort entries by increasing number of uncovered lines. For text and HTML report.
-
-p
,
--sort-percentage
¶
Sort entries by increasing percentage of uncovered lines. For text and HTML report.
-
-x
<output>
,
--xml
<output>
¶ Generate a Cobertura XML report. OUTPUT is optional and defaults to --output.
-
--xml-pretty
¶
Pretty-print the XML report. Implies --xml. Default: False.
-
--html
<output>
¶ Generate a HTML report. OUTPUT is optional and defaults to --output.
-
--html-details
<output>
¶ Add annotated source code reports to the HTML report. Implies --html. OUTPUT is optional and defaults to --output.
-
--html-title
<title>
¶ Use TITLE as title for the HTML report. Default is Head.
-
--html-medium-threshold
<medium>
¶ If the coverage is below MEDIUM, the value is marked as low coverage in the HTML report. MEDIUM has to be lower than or equal to value of --html-high-threshold. If MEDIUM is equal to value of --html-high-threshold the report has only high and low coverage. Default is 75.0.
-
--html-high-threshold
<high>
¶ If the coverage is below HIGH, the value is marked as medium coverage in the HTML report. HIGH has to be greater than or equal to value of --html-medium-threshold. If HIGH is equal to value of --html-medium-threshold the report has only high and low coverage. Default is 90.0.
-
--html-absolute-paths
¶
Use absolute paths to link the --html-details reports. Defaults to relative links.
-
--html-encoding
<html_encoding>
¶ Override the declared HTML report encoding. Defaults to UTF-8. See also --source-encoding.
-
-s
,
--print-summary
¶
Print a small report to stdout with line & branch percentage coverage. This is in addition to other reports. Default: False.
-
--sonarqube
<output>
¶ Generate sonarqube generic coverage report in this file name. OUTPUT is optional and defaults to --output.
-
--json
<output>
¶ Generate a JSON report. OUTPUT is optional and defaults to --output.
-
--json-pretty
¶
Pretty-print the JSON report. Implies --json. Default: False.
Filter Options¶
Filters decide which files are included in the report. Any filter must match, and no exclude filter must match. A filter is a regular expression that matches a path. Filter paths use forward slashes, even on Windows.
-
-f
<filter>
,
--filter
<filter>
¶ Keep only source files that match this filter. Can be specified multiple times. If no filters are provided, defaults to --root.
-
-e
<exclude>
,
--exclude
<exclude>
¶ Exclude source files that match this filter. Can be specified multiple times.
-
--gcov-filter
<gcov_filter>
¶ Keep only gcov data files that match this filter. Can be specified multiple times.
-
--gcov-exclude
<gcov_exclude>
¶ Exclude gcov data files that match this filter. Can be specified multiple times.
-
--exclude-directories
<exclude_dirs>
¶ Exclude directories that match this regex while searching raw coverage files. Can be specified multiple times.
GCOV Options¶
The ‘gcov’ tool turns raw coverage files (.gcda and .gcno) into .gcov files that are then processed by gcovr. The gcno files are generated by the compiler. The gcda files are generated when the instrumented program is executed.
-
--gcov-executable
<gcov_cmd>
¶ Use a particular gcov executable. Must match the compiler you are using, e.g. ‘llvm-cov gcov’ for Clang. Can include additional arguments. Defaults to the GCOV environment variable, or ‘gcov’: ‘gcov’.
-
--exclude-unreachable-branches
¶
Exclude branch coverage from lines without useful source code (often, compiler-generated “dead” code). Default: False.
-
--exclude-throw-branches
¶
For branch coverage, exclude branches that the compiler generates for exception handling. This often leads to more “sensible” coverage reports. Default: False.
-
-g
,
--use-gcov-files
¶
Use existing gcov files for analysis. Default: False.
-
--gcov-ignore-parse-errors
¶
Skip lines with parse errors in GCOV files instead of exiting with an error. A report will be shown on stderr. Default: False.
-
--object-directory
<objdir>
¶ Override normal working directory detection. Gcovr needs to identify the path between gcda files and the directory where the compiler was originally run. Normally, gcovr can guess correctly. This option specifies either the path from gcc to the gcda file (i.e. gcc’s ‘-o’ option), or the path from the gcda file to gcc’s working directory.
-
-k
,
--keep
¶
Keep gcov files after processing. This applies both to files that were generated by gcovr, or were supplied via the --use-gcov-files option. Default: False. Config key: keep-gcov-files.
-
-d
,
--delete
¶
Delete gcda files after processing. Default: False. Config key: delete-gcov-files.
-
-j
<gcov_parallel>
¶ Set the number of threads to use in parallel. Config key: gcov-parallel.
The above Getting Started guide illustrates the use of some command line options. Using Filters is discussed below.
Using Filters¶
Gcovr tries to only report coverage for files within your project, not for your libraries. This is influenced by the following options:
-r
,--root
-f
,--filter
-e
,--exclude
--gcov-filter
--gcov-exclude
--exclude-directories
- (the current working directory where gcovr is invoked)
These options take filters.
A filter is a regular expression that matches a file path.
Because filters are regexes,
you will have to escape “special” characters with a backslash \
.
Always use forward slashes /
as path separators, even on Windows:
- wrong:
--filter C:\project\src\
- correct:
--filter C:/project/src/
If the filter looks like an absolute path, it is matched against an absolute path. Otherwise, the filter is matched against a relative path, where that path is relative to the current directory. Examples of relative filters:
--filter subdir/
matches only that subdirectory--filter '\.\./src/'
matches a sibling directory../src
. But because a dot.
matches any character in a regex, we have to escape it. You have to use additional shell escaping. This example uses single quotes for Bash or POSIX shell.--filter '(.+/)?foo\.c$'
matches only files calledfoo.c
. The regex must match from the start of the relative path, so we ignore any leading directory parts with(.+/)?
. The$
at the end ensures that the path ends here.
If no --filter
is provided,
the --root
is turned into a default filter.
Therefore, files outside of the --root
directory are excluded.
To be included in a report, the source file must match any --filter
,
and must not match any --exclude
filter.
The --gcov-filter
and --gcov-exclude
filters apply to the .gcov
files created by gcov
.
This is useful mostly when running gcov yourself,
and then invoking gcovr with -g
/--use-gcov-files
.
But these filters also apply when gcov is launched by gcovr.
Speeding up coverage data search¶
The --exclude-directories
filter is used
while searching for raw coverage data
(or for existing .gcov
files when --use-gcov-files
is active).
This filter is matched against directory paths, not file paths.
If a directory matches,
all its contents (files and subdirectories) will be excluded from the search.
For example, consider this build directory:
build/
├─ main.o
├─ main.gcda
├─ main.gcno
├─ a/
│ ├─ awesome_code.o
│ ├─ awesome_code.gcda
│ └─ awesome_code.gcno
└─ b/
├─ better_code.o
├─ better_code.gcda
└─ better_code.gcno
If we run gcovr --exclude-directories 'build/a$'
,
this will exclude anything in the build/a
directory
but will use the coverage data for better_code.o
and main.o
.
This can speed up gcovr when you have a complicated build directory structure.
Consider also using the search_paths
or --object-directory
arguments
to specify where gcovr starts searching.
If you are unsure which directories are being searched,
run gcovr in --verbose
mode.
For each found coverage data file gcovr will invoke the gcov
tool.
This is typically the slowest part,
and other filters can only be applied after this step.
In some cases, parallel execution with the -j
option
might be helpful to speed up processing.
Filters for symlinks¶
Gcovr matches filters against real paths that have all their symlinks resolved. E.g. consider this project layout:
/home/you/
├─ project/ (pwd)
│ ├─ src/
│ ├─ relevant-library/ -> ../external-library/
│ └─ ignore-this/
└─ external-library/
└─ src/
Here, the relevant-library
has the real path /home/you/external-library
.
To write a filter that includes both src/
and relevant-library/src/
,
we cannot use --filter relevant-library/src/
because that contains a symlink.
Instead, we have to use an absolute path to the real name:
gcovr --filter src/ --filter /home/you/external-library/src/
or a relative path to the real path:
gcovr --filter src/ --filter '\.\./external-library/src/'
Note
This section discusses symlinks on Unix systems. The behavior under Windows is unclear. If you have more insight, please update this section by submitting a pull request (see our contributing guide).
Configuration Files¶
Warning
Config files are an experimental feature and may be subject to change without prior notice.
Defaults for the command line options can be set in a configuration file. Example:
filter = src/
html-details = yes # info about each source file
output = build/coverage.html
How the configuration file is found:
If a --config
option is provided, that file is used.
Otherwise, a gcovr.cfg
file in the --root
directory is used,
if that file exists.
Each line contains a key = value
pair.
Space around the =
is optional.
The value may be empty.
Comments start with a hash #
and ignore the rest of the line,
but cannot start within a word.
Empty lines are also ignored.
The available config keys correspond closely to the command line options,
and are parsed similarly.
In most cases, the name of a long command line option
can be used as a config key.
If not, this is documented in the option’s help message.
For example, --gcov-executable
can be set via the gcov-executable
config key.
But --branches
is set via txt-branch
.
Just like command line options,
the config keys can be specified multiple times.
Depending on the option the last one wins or a list will be built.
For example, --filter
can be provided multiple times:
# Only show coverage for files in src/, lib/foo, or for main.cpp files.
filter = src/
filter = lib/foo/
filter = *./main\.cpp
Note that relative filters specified in config files will be interpreted relative to the location of the config file itself.
Option arguments are parsed with the following precedence:
- First the config file is parsed, if any.
- Then, all command line arguments are added.
- Finally, if an option was specified neither in a config file nor on the command line, its documented default value is used.
Therefore, it doesn’t matter whether a value is provided in the config file or the command line.
Boolean flags are treated specially.
When their config value is “yes” they are enabled,
as if the flag had been provided on the command line.
When their value is “no”, they are explicitly disabled
by assigning their default value.
The -j
flag is special as it takes an optional argument.
In the config file,
gcov-parallel = yes
would refer to the no-argument form,
whereas gcov-parallel = 4
would provide an explicit argument.
Some config file syntax is explicitly reserved for future extensions: Semicolon comments, INI-style sections, multi-line values, quoted values, variable substitutions, alternative key–value separators, …
Exclusion Markers¶
You can exclude parts of your code from coverage metrics.
- If
GCOVR_EXCL_LINE
appears within a line, that line is ignored. - If
GCOVR_EXCL_START
appears within a line, all following lines (including the current line) are ignored until aGCOVR_EXCL_STOP
marker is encountered.
Instead of GCOVR_*
,
the markers may also start with GCOV_*
or LCOV_*
.
However, start and stop markers must use the same style.
The markers are not configurable.
In the excluded regions, any coverage is excluded. It is not currently possible to exclude only branch coverage in that region. In particular, lcov’s EXCL_BR markers are not supported (see issue #121).
Acknowledgements¶
Gcovr is maintained by:
William Hart, John Siirola, and Lukas Atkinson.
The following developers contributed to gcovr (ordered alphabetically):
alex43dm, Andrew Stone, Arvin Schnell, Attie Grande, Bernhard Breinbauer, Carlos Jenkins, Cezary Gapiński Christian Taedcke, Dave George, Dom Postorivo, goriy, ja11sop, James Reynolds, Jeremy Fixemer, Jessica Levine, Joel Klinghed, John Siirola, Jörg Kreuzberger, Kai Blaschke, Kevin Cai, libPhipp, Lukas Atkinson, Luke Woydziak, Leon Ma, Marek Kurdej, Martin Mraz, Matsumoto Taichi, Matthew Stadelman, Matthias Schmieder, Matthieu Darbois, Michael Förderer, Michał Pszona, Mikael Salson, Mikk Leini, Nikolaj Schumacher, Piotr Dziwinski, Phil Clapham, Richard Kjerstadius, Reto Schneider, Robert Rosengren, Songmin Li, Steven Myint, Sylvestre Ledru, Tilo Wiedera, trapzero, Will Thompson, William Hart, and possibly others.
The development of Gcovr has been partially supported by Sandia National Laboratories. Sandia National Laboratories is a multi-program laboratory managed and operated by Sandia Corporation, a wholly owned subsidiary of Lockheed Martin Corporation, for the U.S. Department of Energy’s National Nuclear Security Administration under contract DE-AC04-94AL85000.