Controlling the instrumentation from the source code

Sometimes it is necessary to apply CoverageScanner settings only to certain regions of the source code, e.g. to exclude parts of a file from instrumentation.

Several methods to do this are described in the following sections.

Annotations

Source code annotations are specific comments which let you select source code parts to validate. Two kinds of annotations exist:

  • Comments: Comments are simple code comments which can be used for giving advice to the tester. They do not have any impact on the code coverage
  • Manual validations: Manual validations indicate that some lines of code should be considered as validated. Manual validations have the same effect on code coverage as executing the source lines.

Source code annotations can directly be edited with CoverageBrowser or generated by writing specific comments into the source code.

Comments

To generate comments for a single source line, start a C or C++ comment with the keyword coco. This will insert a comment for all instrumentations in the current line.

In the following example, the comment To test the failure, change the current working directory to a read-only directory will be added to the instrumentations of line 4.

void write_log( const char *text )
{
   FILE * f = fopen( "log.txt", "a+" );
   if ( f ) /* coco: To test the failure,
                     change the current working
                     directory to a read-only directory */
   {
       fputs( text, f ):
       fclose( f );
   }
}

Comments can also be generated for multiple source lines using the keywords coco begin and coco end.

In the following example, the comment To test the failure, change the current working directory to a read-only directory will be added to the instrumentations of the lines of the function write_log().

void write_log( const char *text )
{
   /* coco begin:  To test the failure,
                   change the current working
                   directory to a read-only directory */
   FILE * f = fopen( "log.txt", "a+" );
   if ( f )
   {
       fputs( text, f ):
       fclose( f );
   }
   /* coco end */
}

Manual validation

Manually validated instrumentation can be generated with a mandatory comment in the code that starts with the keyword coco validated: <comment>. The comment will later occur in the coverage report. To validate a multi-line region of code, use comments of the form

// coco begin validated: <comment>
...
// coco end

C-style comments ("/* ... */") are also possible.

In order to be compatible with PureCoverage adjustments, CoverageScanner also recognizes purecov line comments with the keywords inspected or tested, or alternatively "begin inspected" / "begin tested" and "end inspected" / "end tested" for multi-line annotations.

In the following example, the comment "This function does not need to be tested, only used for debugging." will be added to the instrumentations of the function write_log().

void write_log( const char *text )
{
   // coco begin validated: This function does not need to be tested, only used for debugging.
   FILE * f = fopen( "log.txt", "a+" );
   if ( f )
   {
       fputs( text, f ):
       fclose( f );
   }
}
// coco end

Note that the coco end comment is placed after the end of the function. This is because Coco measures code coverage of a function at its very end, where the final closing brace is located. When we want to mark a complete function as covered, we need to include the last closing brace in the region between the manual validation comments.

Including the function header by placing the coco begin comment in front of the function is not necessary.

Known limitations

It is currently not possible to mark a single outcome of a decision as manually validated.

If an "if (<decision>)" or "while (<decision>)" statement is surrounded by "coco validated:" and "coco end" comments, then both the case that <decision> is true and that it is false are counted as manually validated. Otherwise, none of them is validated. The same is true when an "if" or "while" statement is marked as validated in CoverageBrowser.

The same is true for the conditions of a complex decisions: For a statement of the form "if ((a && b) || c)", it is not possible to declare that the case with a and b false and c true is manually validated.

C and C++ pragmas

CoverageScanner defines C and C++ pragmas to control the instrumentation during the compilation. All control pragmas are handled in a stack. They are valid until the end of the source file or until a #pragma CoverageScanner(pop) is encountered.

The pragmas have the following syntax:

  • #pragma CoverageScanner(<string>)
  • __pragma (CoverageScanner(<string>))
  • _Pragma (CoverageScanner(<string>))

List of supported pragmas:

  • #pragma CoverageScanner(cov-on): Enable code coverage instrumentation.
  • #pragma CoverageScanner(cov-off): Disable code coverage instrumentation.
  • #pragma CoverageScanner(cov-hit): Instrument using code coverage hit.
  • #pragma CoverageScanner(cov-count): Instrument using code coverage count.
  • #pragma CoverageScanner(cov-statement-block): Select statement block coverage as instrumentation method.
  • #pragma CoverageScanner(cov-decision): Select decision coverage as instrumentation method.
  • #pragma CoverageScanner(cov-condition): Select condition coverage as instrumentation method.
  • #pragma CoverageScanner(cov-partial-instrumentation): Partial instrumentation of conditions and decisions.
  • #pragma CoverageScanner(cov-full-instrumentation): Full instrumentation of conditions and decisions.
  • #pragma CoverageScanner(cov-assignment-on): Instrument Boolean expressions in assignments.
  • #pragma CoverageScanner(cov-assignment-off): Do not instrument Boolean expressions in assignments.
  • #pragma CoverageScanner(cov-return-on): Instrument Boolean expressions in return statements.
  • #pragma CoverageScanner(cov-return-off): Do not instrument Boolean expressions in return statements.
  • #pragma CoverageScanner(cov-switch-case-off): Do not instrument all cases of a switch statement.
  • #pragma CoverageScanner(cov-switch-case-on): Instrument all cases in a switch statement.
  • #pragma CoverageScanner(pop): Restore the instrumentation options from before the call of the latest CoverageScanner pragma.

C# regions

CoverageScanner defines C# extensions of the #region keyword which, at compile-time, controls the generation of the instrumentation.

The #region extension has the following syntax:

#region CoverageScanner (<string>)

The keyword #endregion restores the generation options.

List of supported regions:

  • #region CoverageScanner(cov-on): Enable code coverage instrumentation.
  • #region CoverageScanner(cov-off): Disable code coverage instrumentation.
  • #region CoverageScanner(cov-hit): Instrument using code coverage hit.
  • #region CoverageScanner(cov-count): Instrument using code coverage count.
  • #region CoverageScanner(cov-statement-block): Select statement block coverage as instrumentation method.
  • #region CoverageScanner(cov-decision): Select decision coverage as instrumentation method.
  • #region CoverageScanner(cov-condition): Select condition coverage as instrumentation method.
  • #region CoverageScanner(cov-partial-instrumentation): Partial instrumentation of conditions and decisions.
  • #region CoverageScanner(cov-full-instrumentation): Full instrumentation of conditions and decisions.
  • #region CoverageScanner(cov-assignment-on): Instrument Boolean expressions in assignments.
  • #region CoverageScanner(cov-assignment-off): Do not instrument Boolean expressions in assignments.
  • #region CoverageScanner(cov-switch-case-off): Do not instrument all cases in a switch statement.
  • #region CoverageScanner(cov-switch-case-on): Instrument all cases in a switch statement.

Coco v7.3.0 ©2024 The Qt Company Ltd.
Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.