From our bootcamp: Code Coverage

Cover everything!

By Shubham Saxena

What is code coverage?

Code coverage is a proxy to measure the effectiveness of your automated specification suite. It tells us what percentage of our code is executed when our spec suite is run.

It’s possible to have a high coverage percentage while having a poor spec suite; coverage numbers are only useful when the spec suite is well written.

Coverage metrics are often integrated into a codebase’s continuous integration pipeline, and can be set up to fail the build if the coverage drops.

Why do you care?

It’s easy to miss specifying some decisions about what our code does in the automated spec suite, even with TDD. Code coverage helps us spot these areas easily.

What are the different types of coverage?

Let’s use an example.

int calculatesSomething(int x, boolean b1, boolean b2, boolean b3)

Statement coverage or C0 (zero) coverage is the most basic form of code coverage. A statement is covered if it is executed. A statement does not necessarily correspond to a line of code. In order to execute every statement we need only one spec case which would set all conditions to true, every line of a code (statement) is touched.

calculatesSomething(1, true, true, true) — 100% of statements covered

Branch coverage or C1 coverage verifies that whenever a program can jump, it jumps to all possible destinations. Every “if-statement” has two branches (true-branch and false-branch). In order to cover 100% of branches we would need to add the following spec case:

calculatesSomething(1, false, false, false) — 100% of branches covered

Path coverage or C 4 coverage verifies that all paths through the program are taken. The figure below will illustrate the concept of code coverage.

Path coverage covers every aspect of the branching conditions

Wondering what are C2 and C3 coverage?

These are less assertive. C2 and C3 coverage ensure that every sub boolean expression is set to true and false. This, however, does not necessarily imply path coverage.

So, as it stands Path coverage is substantially more exhaustive then branch coverage, which in turn is slightly better than statement coverage.

Some examples

A standard coverage report using Clover
A visual guide to which lines are covered by my specs.

Here, hashCode() is highlighted in red because isn’t being invoked by my spec suite.