gcovr 4.2

(6 min read)

Gcovr 4.2 is out, and provides a broad array of new features! With the ability to use config files, new output formats like JSON and SonarQube XML, and the ability to combine coverage data from multiple runs, this release should make it easier to create coverage report in more complex scenarios.

Gcovr is a command line tool that uses gcov to produce code coverage reports in various formats, such as text summaries, detailed HTML reports, and various machine-readable formats. It works with the GCC and Clang compilers.

You can pip install gcovr from PyPI, read the overview on GitHub, or read the full documentation.

Changes in detail

For the full changelog, see https://gcovr.com/en/stable/changelog.html.

Configuration files

With many filters and other settings, a typical gcovr command line invocation can get pretty long. Now, you can store those settings in a config file. For example, a couple of filters and output formats:

# only show coverage for src/ and lib/foo:
filter = src/
filter = lib/foo/

# produce full HTML report:
html-details = build/coverage.html

# be verbose by default:
verbose = yes

The config file keys are the same as the command line options, with some exceptions that are listed in the gcovr --help message. The values in the config file are treated as a default, and can be overridden on the command line.

If the config file is in the --root directory, it will be picked up automatically. Paths for filters are resolved relative to the config file, not to the current working directory where gcovr is launched.

Configuration files are an experimental feature: they are there to stay, but some details might change in the future. After all, no existing Python module was able to provide the necessary feature set, so this is a custom design.

Documentation: Configuration Files

JSON Output

There is a new JSON output format that can be used by downstream tools. It is closely related to the GCC 9 gcov intermediate format, but differs in some details.

Documentation: JSON Output

Merge coverage data

Thanks to the new JSON output, gcovr can now load coverage data from previous runs. When the -a/--add-tracefile option is used, no new coverage is collected, but JSON files can be combined into new reports.

Importantly, this allows coverage from multiple configurations or test programs to be merged. For example:

mkdir -p coverage

# get coverage for one configuration:
make clean test CONFIG=A COVERAGE=1
gcovr --json coverage/a.json

# get coverage for a different configuration:
make clean test CONFIG=B COVERAGE=1
gcovr --json coverage/b.json

# produce a combined coverage report:
gcovr -a coverage/a.json -a coverage/b.json \
      --html-details coverage/combined.html

Documentation: Combining Tracefiles

Multiple output formats

With the addition of the new JSON and SonarQube XML output formats, it might happen that you want to get multiple reports in one go. Previously, you had to run gcovr once for each format, which can get very slow.

Now, you can produce multiple formats in one go. The format options like --html take an optional argument for the output file, but still default to the -o/--output option or to STDOUT if no file name is given.

For example:

gcovr --json coverage.json \
      --sonarqube coverage.xml \
      --html-details coverage.html

Alternatively, it's also possible to first write JSON output and then load it to produce the other formats:

# collect coverage:
gcovr --json coverage.json

# produce output formats:
gcovr -a coverage.json --sonarqube coverage.xml
gcovr -a coverage.json --html-details coverage.html

Documentation: Multiple Output Formats

Breaking changes

Unfortunately, there are also some breaking changes in this release:

  • Support for Python 3.4 has been dropped. In the future, gcovr will only support Python versions that enjoy upstream support. As a consequence, this is the last release that will support Python 2.7!

  • Because most output format options now take an optional argument, this could change the interpretation of command lines that also used the search paths feature.

    For example, gcovr --xml build used to search for coverage data in the build directory, but would now try to create a file called build. Since this will fail, no data loss is expected. To keep the old meaning, separate positional arguments like gcovr --xml -- build.

Other changes

There are various smaller changes that should still be mentioned:

  • You can now use gcovr --root ../src style invocations, which helps with out-of-source builds. Gcovr should always be invoked from your build directory (the same directory where the compiler runs), but used to have problems when the root path started with a .. path segment.

  • Gcovr improved its handling of exception-only code. Exception-only lines such as catch handlers are no longer ignored. However, C++ compilers generate lots of branches to deal with exceptions. To ignore those branches, use the --exclude-throw-branches option.

    For a full discussion, see the FAQ Why does C++ code have so many uncovered branches?

  • Coverage exclusion markers have long been supported by gcovr, but have now been documented. You can exclude individual lines by adding a GCOVR_EXCL_LINE marker, or exclude a region with GCOVR_EXCL_STARTGCOVR_EXCL_STOP. Gcovr does not currently support branch-only exclusion markers like lcov does.

    Documentation: Exclusion Markers

Future plans

The ideas may be implemented in future gcovr versions:

  • This is the last release that will support Python 2.7, and support for outdated Python versions will be dropped in 2020. By doing so, gcovr can enjoy the benefits of an up to date Python ecosystem, and get rid of a good amount of code that was needed for compatibility.

  • The HTML reports are an eyesore and could benefit from various improvements, starting with responsive CSS and more per-line information. Unfortunately, the test suite currently relies on textual HTML comparison, so that even small changes multiply into having to update around 50 test files.

  • Since the new JSON output format represents gcovr's entire data model, it would be possible to switch tests to this machine-readable format. That would also allow the brittle HTML tests to be removed.

  • GCC 9's new intermediate JSON format was the inspiration for gcovr's new JSON output, but gcovr can't yet read the GCC 9 JSON. Supporting this format would lead to a big performance improvement, but would also require significant changes to gcovr's architecture.

  • On a related point, the gcovr test suite is currently bound to GCC 5. With JSON-based tests, it might be more feasible to test on a larger suite of compilers including Clang.

  • While the JSON format provides an extension point that can be used by downstream processing, it would be cool to implement some common uses directly, like rendering a coverage badge.

How to contribute

Would you like to tackle any of the above issues or an item from the issue tracker? The gcovr contributing guide explains how to get started: how to set up a development environment, how to submit the pull request, and where to get help along the way. When I have the time I enjoy mentoring, so ping me (@latk on GitHub) if you need any assistance.