Skip to main content

Practical Decisions on Testing: Code Coverage Metrics

Another short reference post on the topic of unit testing, in the spirit of saving your keystrokes, based on a conversation I've had a couple of times concerning unit test code coverage. We're using Sonarqube on a current project, which, amongst other things, will review C# code and determine the percentage covered by unit tests.

We're currently running at around 80%, which to me seems a fairly healthy metric. It's not the be all and end all of course in that a high percentage of test coverage doesn't completely diagnose a healthy code base, but, all things being equal, it's a good sign.

The question then comes - why not 100%?

Not in the naive sense though - there's clearly areas of the code, property getters and setters being the classic example, that you could unit test, but wouldn't get much if any value in doing so, and hence the effort is unlikely to be worthwhile.

Rather in the sense that if there are areas that's aren't going to be covered in unit tests, we can decorate them with the [ExcludeFromCodeCoverage] attribute, and they'll be excluded from the code analysed for the test coverage metric, thus boosting it.

My view here, is that, when deciding what code should be covered by unit tests, the decision isn't black and white. Some, probably most, code would be better coupled with tests - confirming correct functionality, guiding design if adopting TDD and reducing the likelihood of regression issues - and so the tests should be written along with the feature. On the other hand, as mentioned, some code clearly offers little value in testing, and hence this can immediately be attributed, removing it from analysis, and via a comment, indicate why the decision has been taken to not apply unit tests to the code.

The grey area in between though, is code that is hard to test, and there's some, but not so much, value in doing so - the upper left quadrant as discussed in this previous post. Given that, you might well decide there are more important things to be spending time on right now - such as new feature development or paying off other technical debt. As time goes by though, that cost benefit may shift, as will the set of competing priorities. Given that, it seems best to keep the decision on "should we add tests for this" open, not closing it off by excluding the code from coverage, but rather keep it under review and re-consider doing so, when time and resources may allow.