Coverage Analysis
ESBMC supports coverage analysis for branch, condition, and assertion coverage. This helps identify which code paths have been tested in your program.
Usage
ESBMC provides three coverage analysis modes:
# Branch coverage
esbmc example.c --branch-coverage
# Condition coverage
esbmc example.c --condition-coverage
# Assertion coverage
esbmc example.c --assertion-coverageCoverage Modes
Branch Coverage
Branch coverage verifies that all branches of conditional statements are executed. For each if, else, while, or for statement, both the true and false branches must be covered.
Example:
int check_sign(int n) {
if (n > 0)
return 1;
else
return -1;
}
int main() {
check_sign(5); // Only covers true branch
return 0;
}$ esbmc example.c --branch-coverage
...
[Coverage]
Branches : 2
Reached : 1
Branch Coverage: 50%The Branch Coverage: 50% shows incomplete coverage. The output indicates that n <= 0 is needed to cover the else branch.
Full coverage example:
int main() {
check_sign(5); // Covers true branch
check_sign(-3); // Covers false branch
return 0;
}$ esbmc example.c --branch-coverage
...
[Coverage]
Branches : 2
Reached : 2
Branch Coverage: 100%The Branch Coverage: 100% indicates all branches have been tested.
Condition Coverage
Condition coverage verifies that each boolean sub-expression in conditional statements evaluates to both true and false at least once. Unlike branch coverage, which tests branches, condition coverage tests individual conditions within complex expressions.
Example:
int validate(int x, int y) {
if (x > 0 && y > 0) // Complex condition
return 1;
else
return 0;
}
int main() {
validate(5, 3);
return 0;
}$ esbmc example.c --condition-coverage
...
[Coverage]
Reached Conditions: 4
Short Circuited Conditions: 0
Total Conditions: 4
Condition Properties - SATISFIED: 2
Condition Properties - UNSATISFIED: 2
Condition Coverage: 50%The Condition Coverage: 50% shows that only the true cases of both conditions were tested. For full condition coverage, each condition must evaluate to both true and false at least once:
x > 0must be true (✓ tested) and false (✗ not tested)y > 0must be true (✓ tested) and false (✗ not tested)
Full coverage example:
int main() {
validate(5, 3); // x>0: T, y>0: T
validate(5, -1); // x>0: T, y>0: F
validate(-1, -1); // x>0: F (y>0 short-circuited)
return 0;
}Note: Due to short-circuit evaluation in &&, when x>0 is false, y>0 is never evaluated. To test y>0 as both true and false, x>0 must be true in those tests.
Assertion Coverage
Assertion coverage verifies that all assertions in the code are reached and tested. This ensures that all validation checks are exercised.
Example:
int process(int n) {
if (n > 10) {
assert(n < 100);
return n * 2;
}
else {
assert(n < 10);
return n + 2;
}
return n;
}
int main() {
process(5); // Covers second assertion
return 0;
}$ esbmc example.c --assertion-coverage
...
[Coverage]
Total Asserts: 2
Total Assertion Instances: 2
Reached Assertion Instances: 1
Assertion Instances Coverage: 50%Full coverage example:
int main() {
process(50); // Covers first assertion
process(5); // Covers second assertion
return 0;
}$ esbmc example.c --assertion-coverage
...
[Coverage]
Total Asserts: 2
Total Assertion Instances: 2
Reached Assertion Instances: 2
Assertion Instances Coverage: 100%Supported Languages
Coverage analysis is supported for:
- C - All C features supported by ESBMC
- C++ - All C++ features supported by ESBMC
- Python - Full Python frontend support
- Solidity - Full Solidity frontend support
Interpreting Coverage Results
The key output of coverage analysis is the coverage percentage shown in the [Coverage] section. This indicates what portion of your code paths have been exercised.
Coverage Statistics
ESBMC reports:
- Total elements: Number of branches/conditions/assertions in the code
- Reached elements: How many were covered by the test inputs
- Coverage percentage: (Reached / Total) × 100%
Understanding the Output
Coverage analysis uses verification internally to determine reachability. You may see VERIFICATION SUCCESSFUL or VERIFICATION FAILED in the output, but these are intermediate messages during coverage computation, not indicators of program correctness.
What matters: The coverage percentage (e.g., “Branch Coverage: 75%”) Less relevant: VERIFICATION status (just shows coverage tool operation)
Python Examples
Branch Coverage
def is_positive(n: int) -> int:
if n > 0:
return 1
else:
return 0
# Only covers positive branch
is_positive(10)$ esbmc example.py --branch-coverage
...
[Coverage]
Branches : 2
Reached : 1
Branch Coverage: 50%The Branch Coverage: 50% indicates incomplete coverage.
Condition Coverage
def check_range(x: int, y: int) -> int:
if x > 0 and y > 0:
return 1
else:
return 0
# Full condition coverage - accounting for short-circuit evaluation
check_range(5, 3) # x>0: T, y>0: T
check_range(5, -1) # x>0: T, y>0: F
check_range(-1, -1) # x>0: F (y>0 short-circuited)$ esbmc example.py --condition-coverage
...
[Coverage]
Reached Conditions: 4
Short Circuited Conditions: 0
Total Conditions: 4
Condition Properties - SATISFIED: 4
Condition Properties - UNSATISFIED: 0
Condition Coverage: 100%The Condition Coverage: 100% indicates that each condition was tested with both true and false inputs.
Assertion Coverage
def validate_positive(n: int) -> int:
assert n > 0, "n must be positive"
return n * 2
validate_positive(5)$ esbmc example.py --assertion-coverage
...
[Coverage]
Total Asserts: 1
Total Assertion Instances: 1
Reached Assertion Instances: 1
Assertion Instances Coverage: 100%Technical Notes
- Coverage analysis in ESBMC uses symbolic execution and SMT solving
- Unlike traditional testing tools, ESBMC determines path reachability and calculates exact coverage percentages
- All paths are explored automatically without manual test case writing
- Coverage analysis adds false assertions to test each branch/condition
- Verification time increases with code complexity
Combining with Other Flags
Coverage analysis can be combined with other ESBMC options:
# With bounded model checking
esbmc example.c --branch-coverage --unwind 10
# With k-induction
esbmc example.c --branch-coverage --k-induction