Condition coverage

Code Coverage for C++

When analyzing C++ source code, HCL OneTest Embedded can provide the following condition coverage:

  • Basic Coverage

  • Forced Coverage

Basic Conditions

Conditions are operands of either || or && operators wherever they appear in the body of a C++ function. They are also if and ternary expressions, tests for for, while, and do/while statements even if these expressions do not contain || or && operators. Two branches are involved in each condition: the sub-condition being true and the sub-condition being false.

Basic conditions also enable different case or default (which could be implicit) in a switch to be distinguished even when they invoke the same simple block. A basic condition is associated with every case and default (written or not).

There are 4*2 basic conditions in the following example:

/* Power_of_10 function */

/* -cond */

int power_of_10 ( int value, int max )

{

int result = value, i;

if ( value == 0 ) return 0;

for ( i = 0; i < 10; i++ )

{

result = max > 0 && ( max / value ) < result ?

result * value :

max;

}

return result ;

}

There are at least 5 basic conditions in this example:

/* Near_color function */

ColorType near_color ( ColorType color )

{

switch ( color )

{

case WHITE :

case LIGHT_GRAY :

return WHITE;

case RED :

case PINK :

case BURGUNDY :

return RED;

/* etc ... */

}

}

Two branches are enumerated for each condition, and one per case or default.

Forced Conditions

Forced conditions are multiple conditions in which any occurrence of the | | and && operators has been replaced in the code with | and & binary operators. Such a replacement done by the Instrumentor enforces the evaluation of the right operands. You can use this coverage type after modified conditions have been reached to be sure that every basic condition has been evaluated. With this coverage type, you can be sure that only the considered basic condition changed between the two tests.

/* User source code */ /* -cond=forceevaluation */

if ( ( a && b ) || c ) ...

/* Replaced with the Code Coverage feature with : */

if ( ( a & b ) | c ) ...

/* Note : Operands evaluation results are enforced to one if different from 0 */

Note This replacement modifies the code semantics. You need to verify that using this coverage type does not modify the behavior of the software.

int f ( MyStruct *A )

{

if (A && A->value > 0 ) /* the evaluation of A->value will cause a program error using

forced conditions if A pointer

is null */

{

A->value -= 1;

}

}

Modified Conditions

A modified condition is defined for each basic condition enclosed in a composition of | | or && operators. It aims to prove that this condition affects the result of the enclosing composition. To do that, find a subset of values affected by the other conditions, for example, if the value of this condition changes, the result of the entire expression changes.

Because compound conditions list all possible cases, you must find the two cases that can result in changes to the entire expression. The modified condition is covered only if the two compound conditions are covered.

/* state_control function */

int state_control ( void )

{

if ( ( ( flag & 0x01 ) &&

( instances_number > 10 ) ) ||

( flag & 0x04 ) )

return VALID_STATE;

else

return INVALID_STATE;

}

In this example, there are 6 basic conditions (FALSE and TRUE of each), 5 compound conditions, and 3 modified conditions :

  • flag & 0x01 : TTX=T and FXF=F

  • nb_instances > 10 : TTX=T and TFF=F

  • flag & 0x04 : TFT=T and TFF=F, or FXT=T and FXF=F

Therefore the 4 following test cases are enough to cover all those modified conditions :

  • TTX=T

  • FXF=F

  • TFF=F

  • TFT=T or FXT=T

Note You can associate a modified condition with more than one case, as shown in this example for flag & 0x04. In this example, the modified condition is covered if the two compound conditions of at least one of these cases are covered.

Code Coverage calculates matching cases for each modified condition.

The same number of modified conditions as Boolean basic conditions appears in a composition of | | and && operators.

Multiple Conditions

A multiple (or compound) condition is one of all the available cases for the || and && logical operator's composition, whenever it appears in a C++ class. It is defined by the simultaneous values of the enclosed Boolean basic conditions.

A multiple condition is noted with a set of T, F, or X letters. These mean that the corresponding basic condition evaluated to true, false, or was not evaluated, respectively. Remember that the right operand of a || or && logical operator is not evaluated if the evaluation of the left operand determines the result of the entire expression.

/* state_control function */

/* -cond=compound */

int state_control ( void )

{

if ( ( ( flag & 0x01 ) &&

( instances_number > 10 ) ) ||

( flag & 0x04 ) )

return VALID_STATE;

else

return INVALID_STATE;

}

In this example, there are 3 basic conditions and 5 compound conditions :

  • TTX=T <=> (( T && T ) || X ) = T

  • TFT=T

  • TFF=F

  • FXT=T

  • FXF=F

Code Coverage calculates every available case for each composition.

The number of enumerated branches is the number of distinct available cases for each composition of || or && operators.

Related Topics

Selecting coverage types | Code Coverage settings