Definition
Condition Coverage
Condition coverage is a structural testing metric that requires every individual atomic condition (boolean sub-expression) in a decision to be tested as both true and false.
Unlike branch coverage, it focuses on the inputs of a compound decision rather than the final outcome.
Concept
For a decision like if (A && B):
- Atomic Conditions: A, B.
- Requirement:
- Test case where A = True.
- Test case where A = False.
- Test case where B = True.
- Test case where B = False.
Independence: Condition coverage does not guarantee branch coverage. It is possible to toggle every sub-condition without ever toggling the final result of the if statement.
Comparison with Branch Coverage
While branch coverage and condition coverage seem similar, they test different aspects of the control flow.
- Branch Coverage tests the outcome of the decision node (True edge vs. False edge).
- Condition Coverage tests the atomic inputs to that decision (A vs. not A).
Independence Scenarios:
- Branch but not Condition:
if (A || B)tested with T/T and F/F.
- Outcome toggles (True/False) \to 100% Branch Coverage.
- Fail: A was never False alone, B was never True alone.
- Condition but not Branch:
if (A || B)tested with T/F and F/T.
- Atoms toggle (A: T/F, B: F/T) \to 100% Condition Coverage.
- Fail: Outcome is always True. False branch never taken.
Example
Consider the following code snippet:
if (A || B) { // BB_1 (Decision)
// True // BB_2
} else {
// False // BB_3
}
graph TD Entry((Entry)) --> Dec{"BB<sub>1</sub>: b<sub>1</sub> = A || B"} Dec -- "True" --> TrueBlock["BB<sub>2</sub>: True Branch"] Dec -- "False" --> FalseBlock["BB<sub>3</sub>: False Branch"]
- Test Case 1: : True.
- Test Case 2: : True.
Coverage Analysis:
- A: Tested as True (T1) and False (T2). Covered.
- B: Tested as False (T1) and True (T2). Covered.
- Result: 100% Condition Coverage.
- Problem: The decision outcome was True in both cases. The
elsebranch was never executed. - Branch Coverage: 1/2 = 50% (Only True branch covered).
Aren't two cases missing?
Why aren’t the following two cases missing?
Answer: Condition coverage only cares about that every value is tested once per input parameter individually. Condition coverage does not test for all combinations of inputs.
This is addressed by the C+B coverage.
Example: Short-Circuit Evaluation
A common mistake in calculating coverage is ignoring short-circuit evaluation. If the left side of a logical operator determines the result, the right side is not executed and thus receives no coverage.
Consider if (A > 0 && B < 5):
Test Case: A = -1 (False), B = 2 (True)
A > 0evaluates to False.&&sees False on the left. The result is False.B < 5is skipped.
Coverage Result:
A > 0: Covered as False.B < 5: Not covered (neither True nor False).
Tip
Do not mark
Bas covered just because the input value (B=2) makes the condition true. If the code didn’t execute it, it doesn’t count.
Example: Condition Coverage from CFG
Consider the following program that checks two boolean flags, a and b.
if (a || b) {
// Action 1
} else {
// Action 2
}Atomic Conditions:
Targets (): We need to observe .
Test Suite:
- Test 1:
- evaluates to True.
- Short-circuit
||: is NOT evaluated. - Trace:
- Test 2:
- evaluates to False.
- evaluates to False.
- Trace:
Calculation:
- Observed Set:
- Total Targets: 4
- Missing: (We never saw
bevaluate to True). - Coverage: .
Hierarchy & Improvement
To resolve the independence issue, stronger criteria exist in the hierarchy:
- Condition + Branch Coverage: Requires satisfying both criteria (100% condition toggles AND 100% branch outcomes).
- DC (Decision Coverage): A highly rigorous standard (used in avionics) requiring that each condition is shown to independently affect the decision outcome.