Condition coverage

Code Coverage for C

When analyzing C source code, HCL OneTest Embedded can provide coverage for:

  • Basic condition coverage

  • Modified condition/decisioncoverage(MC/DC)

  • Multiple condition coverage

  • Forced condition 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 can be true or false.

Basic conditions enable different cases or a default (which could be implicit) in a switch. These are distinguished even when they invoke the same simple block. One basic condition is associated with every case and default, whether implicit or not.

In the following example, there are 4*2 basic conditions:

/* 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 ;

}

In the following example, there are 5 basic conditions:

/* 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.

Modified Conditions

A modified condition (MC) is defined for each basic condition enclosed in a composition of || or && operators, proving that the condition affects the result of the enclosing composition. For example, in a subset of values affected by the other conditions, 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.

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

/* state_control function */

int state_control ( void )

{

if ( ( ( flag & 0x01 ) &&

( instances_number > 10 ) ) ||

( flag & 0x04 ) )

return VALID_STATE;

else

return INVALID_STATE;

}

The conditions can be described as True (T), False (F), or Not evaluated (X), as in the following example:

  • 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 the 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 number of modified conditions matches the number of Boolean basic conditions 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 function. It is defined by the simultaneous values of the enclosed Boolean basic conditions.

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.

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

/* state_control function */

/* -cond=compound */

int state_control ( void )

{

if ( ( ( flag & 0x01 ) &&

( instances_number > 10 ) ) ||

( flag & 0x04 ) )

return VALID_STATE;

else

return INVALID_STATE;

}

The conditions can be described as True (T), False (F), or Not evaluated (X), as in the following example:

  • 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.

Forced Conditions

Forced conditions are multiple conditions in which the Instrumentor replaces any occurrence of the || and && operators in the code, with | and & binary operators. You can use this coverage type, after evaluating all modified conditions, to be sure that every basic condition has been evaluated. With this forced condition coverage, you can ensure that only the basic condition has changed between 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. Before running the test, you need to verify that 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;

}

}

Related Topics

Selecting coverage types | Code Coverage settings