The lost opportunity in test coverage
Disclaimer: This is a bit of a rant, but it's a friendly rant :-)
When people look at code coverage, they are reading it wrong.
Suppose you have a class, something stupid, like your own implementation of a stack, called Stack
.
Because you are not a total monster, you have tests in your code right? In fact, you are claiming that you are doing TDD (Test Driven Development), or at least you
like TDD, or you would like the idea of TDD, or, let's be honest here, you just say you are
doing TDD, but what you do is you sprinkle the tests you feel are needed, which is largely OK, I am not
going to judge you, you freak.
And then you add test coverage checks, and it says: 80%
What most people feel when they see that is dread. They see that 80% and feel "OMFG, my tests suck! I don't have enough! If even 100% coverage is not enough then this 80% means my code is an unstable piece of garbage!"
Well, no.
Whether your code is good or not is independent of tests. Tests give you the ability to know if your code is crap or not... sometimes. What tests really give you (if they are not total garbage in themselves) is the confidence that you can change your code without significantly affecting the behaviours the tests are testing.
So, if your tests of Stack
ensure that:
-
Stack.push
puts the element at the top -
Stack.pop
gets the top element - Your stack can hold as many elements as your requirement defines (may be infinite)
Then what you implemented is a stack. Period. It works. It's fine. It may be inefficient, it may be
ugly, who knows, but tests are not going to give you good taste. All they are going to do is ensure
that Stack
is, indeed, a stack, and behaves like a stack, and that when you stick your mittens in it
and change things inside it it stays a stack.
Yet, your coverage is 80%.
Should you add more tests?
No.
You should delete 20% of your code.
Since code is a liability and the asset is the code's behaviour, then that's what the first D in TDD is for.
Test Driven Development.
Use the tests to define the behaviour you want. Then add code to implement that behaviour.
Don't chase useless stats like coverage.
If coverage is not 100%, consider your tests.
Is there behaviour you want that is not represented as a scenario in a test?
If yes: then add tests.
If not: remove code.
And using "coverage is low" as an opportunity to delete code instead of adding tests is something a lot of developers miss.