The typical cpptestcc
command line presented in the previous section:
cpptestcc -compiler <compiler_configuration> -line-coverage -workspace <workspace location> -- cc -I app/includes -D defines -c source.cpp
may be extended with additional options.
Enabling additional coverage metrics
Depending on the project quality/compliance policies, collecting one or more coverage metrics may be required. cpptestcc
supports code instrumentation for multiple metrics in one build.
To enable multiple metrics, add command line options for all required metrics in your cpptestcc
command line configuration.
See Command Line Reference for cpptestcc for a complete list of coverage metrics options and their syntax.
Enabling optimized coverage metrics
cpptestcc
supports optimized instrumentation for a subset of code coverage metrics. Optimized coverage metrics instrumentation is recommended when working with systems vulnerable to runtime overhead. When optimized instrumentation is enabled, code coverage results are stored in memory buffers and logged at the end of the testing session, rather than being logged in real-time. The optimization minimizes performance overhead during the execution of the tested code. However, unlike regular instrumentation, with optimized instrumentation, results will not be reported if the tested application crashes before the testing session is finalized.
The following options enable optimized metrics:
- -optimized-line-coverage
- -optimized-function-coverage
- -optimized-statement-coverage
- -optimized-block-coverage
- -optimized-decision-coverage
- -optimized-call-coverage
See Command Line Reference for cpptestcc for a complete list of coverage metrics options and their syntax.
It is not recommended to mix regular and optimized metrics in one build.
Configuring code coverage scope
Code coverage scope configuration options allow you to limit the instrumentation scope to files relevant to the project's quality or compliance policies. Limiting the scope of instrumentation simplifies coverage reports by excluding irrelevant files, such as external libraries, compiler headers, and automatically generated or test code, from coverage reporting.
The -ignore <IGNORE_FILE_PATH>
option specifies file path or file path pattern to be ignored from processing.
Example: -ignore /home/project/src/ATM.cxx
-ignore regex:/home/project/autogen/*.cxx
See Command Line Reference for cpptestcc for details on option syntax.
The -ignore
option applies to source files specified in the compiler command line. Any source file matching the path or path pattern passed as an argument to the -ignore
option will be entirely skipped from the coverage instrumentation, which implies that any files included by the ignored file will also be ignored.
The typical applications of the -ignore
option are:
- Excluding files with unit test cases, for example GoogleTest or other framework test suites
Example:-ignore regex:*/tests/*Suite.cxx
- Excluding automatically generated source files, for example files generated from models.
Example: -ignore regex:*/build/autogen*.cpp
- Excluding source files with low-level code, for example files containing interrupt handler implementations.
Example: -ignore /home/project/src/isr_handlers.c
The -include <INCLUDE_FILE_PATH>
option includes matching files into the instrumentation scope
The -exclude <EXCLUDE_FILE_PATH>
option excludes matching files from the instrumentation scope
Example: -exclude regex:*
-include /home/project/src/application.cxx
See Command Line Reference for cpptestcc for options syntax details.
The -include/-exclude
options allow you to define instrumentation filters. Only files that are included and not excluded will be instrumented. The -include/-exclude
options are processed in the order they are specified, with an implicit -include regex:*
at the beginning.
The -include/-exclude
filters are applied after source code preprocessing, at the translation unit level, which enables filtering of include files.
The typical applications of the -include/-exclude
options are:
- Excluding compiler header files
Example: -include "regex:*" -exclude "regex:*/gcc/include/*"
The first option enables instrumentation for all source and header files, and the -exclude
option excludes all files from the compiler installation directory. With this instrumentation scope configuration, coverage will be reported for all project files, but it will not be reported for example, for the iostream.h
file or any other header or source file from the compiler installation.
- Enabling code instrumentation for a specific project directory
Example:-exclude "regex:*" -include "regex:*/project/library/*"
The first option disables instrumentation for all source and header files, and the second option enables instrumentation for all source and header files matching the "/home/project/src/module/*" path pattern. With this instrumentation scope configuration, coverage will be reported only for source and header files matching the "/home/project/src/module/*" path pattern.
Note: When the /home/project/src/module/
directory contains header files included by source files residing outside of /home/project/src/module/
, coverage metrics will be reported for those header files.
Understanding the difference between -exclude/-include
filter options and the -ignore
option
The -exclude/-include
instrumentation filter options, and the -ignore
option may generate similar results in some situations. However, they work differently and are designed to handle different cases.
The -ignore
option applies to source files and is used very early in the source file instrumentation process. When a source file matches ignored paths, the instrumentation engine skips the file without preprocessing, parsing, or instrumentation. As a consequence, coverage will not be collected for the ignored file and any header file included by the source file.
The -exclude/-include
filters are applied later in the instrumentation process at the translation unit level, after source code preprocessing and parsing. They enable filtering sections of the translation unit. It is possible to exclude coverage reporting from a source file while enabling coverage for all header files.
Disabling coverage instrumentation selectively
Coverage instrumentation may be disabled or enabled for specific functions by using special parasoft-instrumentation coverage
comments:
// parasoft-instrumentation coverage off
- disables coverage instrumentation.// parasoft-instrumentation coverage on
- re-enables coverage instrumentation.
Elements (such as lines, decisions, etc.) of a function with disabled coverage instrumentation will not be counted as coverable.
Both comments affect function definitions located in the same file (before preprocessing), beginning after the line containing each respective comment. They operate at the granularity of an entire function (as a whole) - e.g. if placed inside a function, their effect will apply only to function definitions following them.
In the following example, code coverage instrumentation will be disabled for functions f2()
, f3()
, f5()
, main()
and enabled for functions g()
, f1()
, f4()
. The comment inside function f4()
affects functions f5()
and main()
as their definitions are placed after this comment. C/C++test CT will treat this exemplary code as having seven coverable lines (one in g()
, two in f1()
and four in f4()
).
int g(int i) { return i+1; } int f1(int a) { if (a >= 0) return +1; else return -1; } // parasoft-instrumentation coverage off int f2(int a) { return g(a - 1) + g(a); } int f3(int a) { return a + 2; } // parasoft-instrumentation coverage on int f4(int a, int b) { if (a == 3) { return b; } else { /* parasoft-instrumentation coverage off */ int i = g(a+b); return i; } } int f5(int a) { return f3(a * 2); } int main() { f1(12); return 0; }
The parasoft-instrumentation coverage
construct may be used inside both //...
and /*...*/
comments. In case of /*...*/
comments, the entire construct must be placed in the same line as the /*
comment opening characters. To be recognized, the parasoft-instrumentation coverage
comment must be the only construct in the code line.
Advanced configurations
Enabling coverage for C++ template code
In the default configuration, cpptestcc
does not instrument C++ templates for code coverage. Code coverage instrumentation for C++ templates can be enabled using the following option:
-template-coverage
See Command Line Reference for cpptestcc for details on option syntax.
With the option, coverage is collected cumulatively for all instances of a specific template.
Enabling coverage for functions and methods declared with the 'constexpr' specifier
In the default configuration, cpptestcc
does not instrument functions and methods declared with the 'constexpr' specifier. Code coverage instrumentation can be enabled for 'constexpr' functions and methods using the following option:
-constexpr-coverage
See Command Line Reference for cpptestcc for details on option syntax and a list of supported compilers.
With the option, all 'constexpr' functions and methods that are suitable for runtime execution will be instrumented for code coverage. 'constexpr' functions and methods that are not suitable for runtime execution will not be instrumented.
Enabling multiple variants of the coverage data for different compilations of the same source file
In some situations, the build process performs several compilations of a single file, for example, with and without the —fPIC
flag for position-independent code. cpptestcc
is configured by default for single compilation pass builds, and it overwrites the coverage data files created in a previous compilation pass with each subsequent compilation of a specific file. Depending on the test setup, a lack of coverage data files from previous compilation passes may prevent successful report generation.
Support for storing multiple copies of coverage data files can be enabled using the following option:
-coverage-data-variants
See Command Line Reference for cpptestcc for details on option syntax.
Note: Be sure different compilations of the same source file do not introduce conflicting code - this is an unsupported scenario.