The importance of code coverage

May 2021
🔗

Definition 🤓

Code coverage can be defined as :

a measure used to describe the degree to which the source code of a program is executed when a particular test suite runs.

For a while, I mistakenly relied on code coverage for making sure my code is well tested, it was wrong.

To avoid such misunderstandings, there is a very simple solution :

God damn it, RTFM !

🔗

Example 🧪

Let us consider the following add function :

add.tsTS
export const add = (a: number) => (b: number) => a + b;

add(4)(10); // 14

When called with a number a, it returns a new function that will sum its argument b with a when executed. This means we declare two functions here : add itself, and the function it returns.

As a first test, we could check that when called once, it returns a function :

add.test.tsTS
import { add } from './add';

describe('add', () => {
  it('returns a function', () => {
    expect(add(4)).toBeInstanceOf(Function);
  });
});

At this point, the function (b: number) => a + b that was returned by the first call has not been executed.

We only have executed 1 out of 2 functions : the amount of function execution indicated by the code coverage report naturally equals 50%.

50% function code coverage

As a second test, we could now check that when called twice, it returns a number :

add.test.tsTS
import { add } from './add';

describe('add', () => {
  it('returns a function', () => {
    expect(add(4)).toBeInstanceOf(Function);
  });

  it('returns a function that returns a number', () => {
    expect(add(4)(10)).toEqual(expect.any(Number));
  });
});

Now that we have executed both functions, we can finally watch the code coverage reaching 100% !

100% code coverage

Great, it's all  !

The problem is, we still have not tested the core logic of the add function yet : it should return the sum of a and b .

It would be more relevant to test the value that is returned :

add.test.tsTS
import { add } from './add';

describe('add', () => {
  it('returns a function', () => {
    expect(add(4)).toBeInstanceOf(Function);
  });

  it('returns a function that returns the sum of the two arguments provided', () => {
    expect(add(4)(10)).toEqual(14);
  });
});
🔗

Conclusion

Code coverage is a useful indicator to know if any part of the code is missing tests, but it is not supposed to estimate the relevance of our tests.

Made with  ❤️  from Saumur