Code coverage metrics in Software Engineering - Time & Space Complexity
When measuring code coverage, we want to understand how the effort to check code parts grows as the code size increases.
How does the time to analyze coverage change when the code base gets bigger?
Analyze the time complexity of the following code snippet.
function calculateCoverage(tests, codeLines) {
let coveredLines = new Set();
for (let test of tests) {
for (let line of test.executedLines) {
coveredLines.add(line);
}
}
return coveredLines.size / codeLines.length;
}
This code calculates coverage by collecting all lines executed by tests and then compares to total code lines.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops over tests and their executed lines.
- How many times: Outer loop runs once per test; inner loop runs once per executed line in each test.
As the number of tests and executed lines grow, the total operations increase roughly by multiplying these two.
| Input Size (tests x avg lines) | Approx. Operations |
|---|---|
| 10 x 5 | 50 |
| 100 x 5 | 500 |
| 100 x 50 | 5,000 |
Pattern observation: Doubling tests or lines roughly doubles the work; total work grows with the product of tests and lines.
Time Complexity: O(t × l)
This means the time to calculate coverage grows proportionally to the number of tests times the average lines each test executes.
[X] Wrong: "The time to calculate coverage depends only on the total code lines."
[OK] Correct: The calculation depends more on how many tests and lines they cover, not just total code size.
Understanding how coverage calculation scales helps you reason about testing tools and performance in real projects.
"What if each test executed all code lines? How would the time complexity change?"